隨筆 - 18  文章 - 96  trackbacks - 0
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345


          常用鏈接

          留言簿(4)

          隨筆檔案

          相冊

          我的兄弟們

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          “千里冰封” 兄弟的截屏程序酷斃了,但是好像9月4日之后就沒有繼續更新了,我們來繼續為他的程序改進,順便也把我們這幾天都在講的2D繪制用進來,我們的目標是讓冰封的截屏程序成為截屏程序里的王!
          今天先改進一下截圖時候的選框,還是先放上截圖的截圖(*o*):

          這是原來的圖片,下面是改進后的

          和改進的代碼部分:
          這部分代碼插入 Temp類的paintComponent方法中的    if (showTip) 這句的前面
              Graphics2D g2d = (Graphics2D) g.create();
                      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                              RenderingHints.VALUE_ANTIALIAS_ON);
                      g2d.setComposite(AlphaComposite.getInstance(
                              AlphaComposite.SRC_OVER, 
          0.3F));
                      g2d.setColor(Color.RED.brighter().brighter());
                      
          int sX = Math.min(startX, endX);
                      
          int sY = Math.min(endY, startY);
                      g2d.fillRect(sX, sY, Math.abs(endX 
          - startX), Math.abs(endY
                              
          - startY));
                      g2d.setComposite(AlphaComposite.getInstance(
                              AlphaComposite.SRC_OVER, 1F));
                      
          boolean drawCTip = endX - startX != 0 && endY - startY != 0;
                      
          if (drawCTip) {
                          String cTip 
          = String.format("%dX%d", Math.abs(endX - startX),
                                  Math.abs(endY 
          - startY));
                          
          int cTipH = 20;
                          Font cTipFont 
          = new Font("system", Font.BOLD, 16);
                          g2d.setFont(cTipFont);
                          
          int cTipW = SwingUtilities.computeStringWidth(
                                  getFontMetrics(cTipFont), cTip);
                          g2d.setPaint(Color.BLACK);
                          
          int cStartY = sY - cTipH > 0 ? sY - cTipH : sY;
                          g2d.fillRect(sX, cStartY, cTipW, cTipH);
                          g2d.setPaint(Color.WHITE);
                          g2d.drawString(cTip, sX, cStartY 
          == sY ? sY + cTipH - 3
                                  : sY 
          - 3);
                      }
                      g2d.dispose();

          怎么樣,比起QQ的截圖程序,我們又近一步了,嗯。

          posted @ 2007-09-13 13:28 ruislan 閱讀(1493) | 評論 (10)編輯 收藏
               摘要: 嗯,BeanSoft的話很有道理,令我敬佩,也許是昨天在下對那個“更好的”三個字感到一時憤慨,所以看到UI就自己擴大了問題,想到迎合LookAndFeel上面去了,在此說句對不起了。你的回帖里面偏重于從整個組件的設計和重用性上,我的文章主要講的是如何將2D繪制和組件的繪制結合起來,看客如果既了解了如何繪制自己想要的組件,又能設計得體,重用性高的話也算是對我拋磚引玉的欣慰了。...  閱讀全文
          posted @ 2007-09-12 13:36 ruislan 閱讀(2442) | 評論 (11)編輯 收藏
          看來我們的JTextField之旅也到了一個階段,已經很不錯了,現在我們來改造JButton,讓那個呆板的Swing看起來舒服一些。

          還是先放上完成后的效果圖:

          普通的狀態


          鼠標滑過


          鼠標按下

          和代碼:
            1 /**
            2  * @(#)RJButton.java  0.1.0  2007-9-11
            3  */
            4 package ruislan.rswing;
            5 
            6 import java.awt.AlphaComposite;
            7 import java.awt.Color;
            8 import java.awt.Font;
            9 import java.awt.GradientPaint;
           10 import java.awt.Graphics;
           11 import java.awt.Graphics2D;
           12 import java.awt.RenderingHints;
           13 import java.awt.Shape;
           14 import java.awt.event.MouseAdapter;
           15 import java.awt.event.MouseEvent;
           16 import java.awt.geom.RoundRectangle2D;
           17 
           18 import javax.swing.JButton;
           19 
           20 /**
           21  * Custom JButton
           22  * 
           23  * @version 0.1.0
           24  * @author ruislan <a href="mailto:z17520@126.com"/>
           25  */
           26 public class RButton extends JButton {
           27     private static final long serialVersionUID = 39082560987930759L;
           28     public static final Color BUTTON_COLOR1 = new Color(205255205);
           29     public static final Color BUTTON_COLOR2 = new Color(5115447);
           30     // public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
           31     // public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
           32     public static final Color BUTTON_FOREGROUND_COLOR = Color.WHITE;
           33     private boolean hover;
           34 
           35     public RButton() {
           36         setFont(new Font("system", Font.PLAIN, 12));
           37         setBorderPainted(false);
           38         setForeground(BUTTON_COLOR2);
           39         setFocusPainted(false);
           40         setContentAreaFilled(false);
           41         addMouseListener(new MouseAdapter() {
           42             @Override
           43             public void mouseEntered(MouseEvent e) {
           44                 setForeground(BUTTON_FOREGROUND_COLOR);
           45                 hover = true;
           46                 repaint();
           47             }
           48 
           49             @Override
           50             public void mouseExited(MouseEvent e) {
           51                 setForeground(BUTTON_COLOR2);
           52                 hover = false;
           53                 repaint();
           54             }
           55         });
           56     }
           57 
           58     @Override
           59     protected void paintComponent(Graphics g) {
           60         Graphics2D g2d = (Graphics2D) g.create();
           61         int h = getHeight();
           62         int w = getWidth();
           63         float tran = 1F;
           64         if (!hover) {
           65             tran = 0.3F;
           66         }
           67 
           68         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
           69                 RenderingHints.VALUE_ANTIALIAS_ON);
           70         GradientPaint p1;
           71         GradientPaint p2;
           72         if (getModel().isPressed()) {
           73             p1 = new GradientPaint(00new Color(000), 0, h - 1,
           74                     new Color(100100100));
           75             p2 = new GradientPaint(01new Color(00050), 0, h - 3,
           76                     new Color(255255255100));
           77         } else {
           78             p1 = new GradientPaint(00new Color(100100100), 0, h - 1,
           79                     new Color(000));
           80             p2 = new GradientPaint(01new Color(255255255100), 0,
           81                     h - 3new Color(00050));
           82         }
           83         g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
           84                 tran));
           85         RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(00, w - 1,
           86                 h - 12020);
           87         Shape clip = g2d.getClip();
           88         g2d.clip(r2d);
           89         GradientPaint gp = new GradientPaint(0.0F0.0F, BUTTON_COLOR1, 0.0F,
           90                 h, BUTTON_COLOR2, true);
           91         g2d.setPaint(gp);
           92         g2d.fillRect(00, w, h);
           93         g2d.setClip(clip);
           94         g2d.setPaint(p1);
           95         g2d.drawRoundRect(00, w - 1, h - 12020);
           96         g2d.setPaint(p2);
           97         g2d.drawRoundRect(11, w - 3, h - 31818);
           98         g2d.dispose();
           99         super.paintComponent(g);
          100     }
          101 }
          102 


          注意代碼中的幾個部分:

          首先是paintComponent方法中最后一行,我們調用了父類的paintComponent方法,這是因為我們要靠父類來繪制字符,但是父類的這個方法除了繪制字符之外還會繪制其他的,所以我們需要關閉掉其他的(當然我們也可以自己來繪制字符,但是JButton提供了方法為什么不用呢),所以我們在構造方法那里調用了:
          setBorderPainted(false);
          setFocusPainted(false);
          setContentAreaFilled(false);
          告訴父類不用繪制邊框,不用繪制焦點,不用繪制內容部分,這部分我們自己來搞*o*。

          然后就是這一句了g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)告訴繪制API我們需要平滑一點,否則繪制出來會有很多鋸齒喲。

          接下來的這一句g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,tran))告訴繪圖API我們需要繪制一個有透明度的,tran就是透明度(0-1)。

          然后就是將邊框的邊角變直角為圓角,我們繪制一個RoundRectangle2D,這個就是邊角都為圓角的方形,然后我們根據這個方形來clip我們的方形,這樣方形就被RoundRectangle2D的圓角方形包裹,從而變成了圓角方形。

          最后就是繪制外邊線和內邊線,通過改變內邊線和外邊線的色變從而造成陷入或者突出效果。

          整個JButton改造完畢,如果你能夠活用clip的話,你也可以做一個五角星的JButton喲。

          整個源代碼我連同Eclipse工程文件已經打包成zip放在我的文件里面,下載鏈接如下:
          http://www.aygfsteel.com/Files/ruislan/rswing-0.1.0.zip

          posted @ 2007-09-11 12:24 ruislan 閱讀(5559) | 評論 (20)編輯 收藏
          昨天我們給JTextField增加了一個泡泡提示窗口,今天我們繼續昨天的,首先處理在顯示泡泡的時候忽略輸入的Backspace、Enter、Delete、Esc按鍵,然后加上錯誤的時候的聲音提示,最后再給JTextField換裝備,讓它看起來像MSN 8.5beta的輸入框,還是先放上圖片:


          這幅圖是MSN的輸入框,輸入框的內部到光標有一部分是有點毛玻璃的感覺,不過這個style是死的,我們改進一下,我們的JTextField在輸入之前是看似普通的,在鼠標放上去之后,看起來就與MSN的輸入框類似了,而且我們還給這個輸入框加入一個淡黃色的背景。

          好了,現在很明確要做的事情了
          1. 加入鼠標事件監聽器,監聽MouseEnter和MouseExit事件,根據這個兩個事件設置不同的背景色和邊框
          2. 做一個能夠顯示毛玻璃效果的邊框

          以下是邊框的代碼和部分MyJTextField的代碼,完整的代碼待我會打包傳上來的
          MyJTextField.java
          在初始化組件的時候加上Border的初始化:
                  hoverBorder = new CoolBorder(HOVER_BORDER_COLOR, 3);
                  border 
          = BorderFactory.createCompoundBorder(new LineBorder(
                          BORDER_COLOR, 
          1), new EmptyBorder(new Insets(2222)));

                  setBackground(BACKGROUND_COLOR);
                  setBorder(border);
          和事件的初始化:
                  addMouseListener(new MouseAdapter() {
                      @Override
                      
          public void mouseEntered(MouseEvent e) {
                          setBorder(hoverBorder);
                          setBackground(HOVER_BACKGROUND_COLOR);
                          repaint();
                      }

                      @Override
                      
          public void mouseExited(MouseEvent e) {
                          setBorder(border);
                          setBackground(BACKGROUND_COLOR);
                          repaint();
                      }
                  });
          以及屏蔽功能性按鈕和發出聲音提示的代碼:
          addKeyListener(new KeyAdapter() {
                      @Override
                      
          public void keyTyped(KeyEvent e) {
                          
          char input = e.getKeyChar();
                          
          // ESC27 ,Backspace 8 ,Enter 10, Del 127, must ignore
                          boolean ignoreInput = input == (char) KeyEvent.VK_ESCAPE
                                  
          || input == (char) KeyEvent.VK_BACK_SPACE
                                  
          || input == (char) KeyEvent.VK_ENTER
                                  
          || input == (char) KeyEvent.VK_DELETE;
                          
          if (ignoreInput) {
                              limitTip.setVisible(
          false);
                              numberTip.setVisible(
          false);
                              
          return;
                          }
                          
          if (getText().length() + 1 > limit) {
                              Toolkit.getDefaultToolkit().beep();
                              deleteInputChar(e);
                              limitTip.setVisible(
          true);
                              
          return;
                          } 
          else {
                              limitTip.setVisible(
          false);
                          }
                          
          if (numberOnly) {
                              
          if (!Character.isDigit(input)) {
                                  numberTip.setVisible(
          true);
                                  Toolkit.getDefaultToolkit().beep();
                                  deleteInputChar(e);
                              } 
          else {
                                  numberTip.setVisible(
          false);
                              }
                          }
                      }

                      
          private void deleteInputChar(KeyEvent source) {
                          source.setKeyChar((
          char) KeyEvent.VK_CLEAR);
                      }
                  });


          下面是Border的完整代碼:
           1 /**
           2  * @(#)CoolBorder.java  0.1.2  2007-9-10
           3  */
           4 package ruislan;
           5 
           6 import java.awt.Color;
           7 import java.awt.Component;
           8 import java.awt.Dimension;
           9 import java.awt.GradientPaint;
          10 import java.awt.Graphics;
          11 import java.awt.Graphics2D;
          12 import java.awt.Insets;
          13 
          14 import javax.swing.border.Border;
          15 
          16 /**
          17  * Custom Border.
          18  * 
          19  * @version 0.1.2, 2007-9-10
          20  * @author ruislan <a href="mailto:z17520@126.com"/>
          21  */
          22 public class CoolBorder implements Border {
          23     private int thickness;
          24     private Insets insets;
          25     private Dimension lastComponentSize;
          26     private Color color;
          27     private Color color2;
          28 
          29     public CoolBorder(Color color, int thickness) {
          30         this.color = color;
          31         if (color == null) {
          32             this.color = color = Color.gray;
          33         }
          34         color2 = new Color(2102102100);
          35         this.thickness = thickness;
          36     }
          37 
          38     @Override
          39     public Insets getBorderInsets(Component c) {
          40         Dimension currentComponent = c.getSize();
          41 
          42         if (currentComponent.equals(lastComponentSize)) {
          43             return insets;
          44         }
          45 
          46         insets = new Insets(thickness, thickness, thickness, thickness);
          47         lastComponentSize = currentComponent;
          48         return insets;
          49     }
          50 
          51     @Override
          52     public boolean isBorderOpaque() {
          53         return true;
          54     }
          55 
          56     @Override
          57     public void paintBorder(Component c, Graphics g, int x, int y, int width,
          58             int height) {
          59         Graphics2D g2d = (Graphics2D) g.create();
          60         // 畫上邊緣
          61         GradientPaint gp = new GradientPaint(x, y, color, x, y + thickness,
          62                 color2);
          63         g2d.setPaint(gp);
          64         g2d.fillRect(x, y, width, thickness);
          65         // 畫下邊緣
          66         gp = new GradientPaint(x, y + height - thickness - 1, color2, x, y
          67                 + height, color);
          68         g2d.setPaint(gp);
          69         g2d.fillRect(x, y + height - thickness - 1, width, thickness);
          70         // 畫左邊緣
          71         gp = new GradientPaint(x, y, color, x + thickness, y, color2);
          72         g2d.setPaint(gp);
          73         g2d.fillRect(x, y, thickness, height);
          74         // 畫右邊緣
          75         gp = new GradientPaint(x + width - thickness - 1, y, color2, x + width,
          76                 y, color);
          77         g2d.setPaint(gp);
          78         g2d.fillRect(x + width - thickness - 1, y, thickness, height);
          79         // 畫外框
          80         g2d.setPaint(color);
          81         g2d.drawRect(x, y, width - 1, height - 1);
          82         g2d.dispose();
          83     }
          84 
          85 }
          86 

          然后來欣賞我們的結果吧:

          鼠標放上去之前


          鼠標放上去之后

          我們輸入了不是數字的字符

          至此,我們的JTextField又向前走了一步,下次我們還能如何改進呢?把JTextField這個死板的長方形改造成云狀的或者其他形狀的?

          附源代碼下載地址:http://www.aygfsteel.com/Files/ruislan/myjtextfield.zip

          posted @ 2007-09-10 13:21 ruislan 閱讀(4350) | 評論 (3)編輯 收藏
               摘要: 接著昨天的MyJTextField,我們繼續為JTextField增強,今天我們為MyJTextField增加一個泡泡提示。先看圖片: 當輸入第三個字符'a'時,由于昨天我們的MyJTextField做了處理,所以'a'不能被輸入,而且彈出泡泡提示你下次不要了喲! 同樣的,下一張圖片: 為MyJTextField增加泡泡提示功能要做以下幾件事情: 1. 泡泡窗口 2. 顯示的...  閱讀全文
          posted @ 2007-09-09 13:32 ruislan 閱讀(5183) | 評論 (2)編輯 收藏
          在網上Google了一下,基本上的做法有兩種,第一種是JFormattedTextField;另外一種是自己繼承PlainDocument, Override insertString方法,然后用JTextFiled.setDocument的方法放入自己繼承的對象實例。但是最終我都沒有采用這兩種方法,首 先我對JFormattedTextField的方式不太舒服,然后感覺繼承PlainDocument有點太重,所以自己考慮了一種方案,也許有人跟我 的想法雷同,那就純屬巧合了。

          下面放上代碼:
          public class MyJTextField extends JTextField {
              
          private int limit = Integer.MAX_VALUE;
              
          private boolean numberOnly;

              
          public MyJTextField() {
                  addKeyListener(
          new KeyAdapter() {
                      @Override
                      
          public void keyTyped(KeyEvent e) {
                          
          if (getText().length() + 1 > limit) {
                              deleteInputChar(e);
                              
          return;
                          }
                          
          if (numberOnly) {
                              
          char input = e.getKeyChar();
                              
          if (!Character.isDigit(input)) {
                                  deleteInputChar(e);
                              }
                          }
                      }

                      
          private void deleteInputChar(KeyEvent source) {
                          source.setKeyChar((
          char) KeyEvent.VK_CLEAR);
                      }
                  });

              }

              
          public void setMaxTextLength(int limit) {
                  
          if (limit < 0) {
                      
          return;
                  }
                  
          this.limit = limit;
              }

              
          public int getMaxTextLength() {
                  
          return limit;
              }

              
          public void setNumberOnly(boolean numberOnly) {
                  
          this.numberOnly = numberOnly;
              }

              
          public boolean isNumberOnly() {
                  
          return this.numberOnly;
              }
          }

          整個思路很簡單,就是檢查Type事件,如果超出了限制就刪除新增加的字符,如果設置了只是數字,那么不是數字的就刪除新增加的字符。使用的時候只需要
          MyJTextField textField = new MyJTextField();
          textField.setLimit(8);
          textField.setNumberOnly(true);
          結果就是最多輸入8個字符而且只能是數字。

          posted @ 2007-09-09 00:41 ruislan 閱讀(1286) | 評論 (2)編輯 收藏
          其實認識這里也有一段時間了,平常也常常上來看看,也用someone的給一些博主有些留言。但是因為自己有了blogspot,所以始終沒有注冊??上У氖莃logspot被封太久了,我也懶得去改什么東西來破解,所以遺憾的放棄了blogspot,當然這里也并非我退而其次的選擇。今天在這里注冊了就算正式與blogspot告別了。blogspot上的文章也不打算轉過來了。從頭開始寫吧。
          posted @ 2007-09-08 13:59 ruislan 閱讀(209) | 評論 (1)編輯 收藏
          僅列出標題
          共2頁: 上一頁 1 2 
          主站蜘蛛池模板: 蒙阴县| 辽阳县| 霍山县| 吉首市| 汶上县| 阿城市| 南澳县| 屏东县| 稻城县| 尼勒克县| 江山市| 临邑县| 蕲春县| 江门市| 巨野县| 新干县| 什邡市| 丰都县| 开平市| 新邵县| 本溪市| 伽师县| 开阳县| 蒙城县| 普兰县| 永州市| 海安县| 祁连县| 建德市| 平果县| 牙克石市| 曲水县| 巴里| 玉林市| 彭水| 原平市| 安徽省| 武平县| 崇仁县| 崇义县| 石台县|