成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

探秘JDK 7之三:JLayer裝飾Swing組件

開發 后端
探秘JDK 7:JLayer裝飾Swing組件。本文為探秘JDK 7系列的第三篇,前兩篇分別是“探秘JDK 7:將會出現新的語言特性”和“探秘JDK 7之二:半透明和任意形狀的窗口”。

51CTO在給各位介紹過“探秘JDK 7”和“再探JDK 7”之后,今天我們再次走上探秘JDK 7之旅。本文將為大家介紹JDK 7引入了一個新的Swing組件來裝飾其它Swing組件,這個新的組件是通過javax.swing.JLayer類,基于Swing實驗室項目Swing Helper的JXLayer實現的。JLayer結合javax.swing.plaf.LayerUI使用可以實現高級的繪制效果,并可以在它的邊界范圍內接收由java.awt.AWTEvents產生的所有通知。

JLayer和LayerUI概述

根據JDK的文檔描述,JLayer委托處理LayerUI對象的繪制和輸入事件,LayerUI負責裝飾,你可以使用這些類修改現有組件的外觀和行為使它們的裝飾效果更好。

實際上,你可以自己動手擴展LayerUI,廢除它們自帶的方法,自己定制繪制和事件處理方法,然后將這個類的實例和裝飾后的組件一道,傳遞給下面的JLayer構造器:
public JLayer(V view,LayerUI<V> ui)

第一個參數可以是任何類的延伸java.awt.Component,表示你要裝飾的Swing組件,這個組件可以是一個JPanel或其它容器,這個容器和它里面所有的組件都將被裝飾,第二個參數代表裝飾器。使用這些構造器創建JLayer時,可以延遲指定LayerUI實例和/或視圖。

如果初始化時不指定視圖,之后你可以調用JLayer's public void setView(V view)方法來提供一個視圖,這個類也提供了一個public V getView()方法返回組件是否被裝飾,沒有裝飾就返回null。

如果初始化時不指定LayerUI實例,之后你可以調用JLayer's public void setUI(LayerUI ui方法提供一個實例,這個類也提供了一個public LayerUI getUI()方法返回當前的裝飾器,沒有裝飾器就返回null。

JLayer自定義繪制

為了演示JLayer的自定義繪制特性,我創建了一個ReverseText程序,其代碼顯示在清單1中,當按下按鈕時,輸入到textfield中的文本將全部顛倒,這個程序使用JLayer在用戶界面后繪制了一個墻紙圖案。

清單1. ReverseText.java

  1. // ReverseText.java  
  2. import java.awt.Color;  
  3. import java.awt.EventQueue;  
  4. import java.awt.GradientPaint;  
  5. import java.awt.Graphics;  
  6. import java.awt.Graphics2D;  
  7. import java.awt.event.ActionEvent;  
  8. import java.awt.event.ActionListener;  
  9. import javax.swing.JButton;  
  10. import javax.swing.JComponent;  
  11. import javax.swing.JFrame;  
  12. import javax.swing.JLabel;  
  13. import javax.swing.JLayer;  
  14. import javax.swing.JPanel;  
  15. import javax.swing.JTextField;  
  16. import javax.swing.plaf.LayerUI;  
  17. public class ReverseText  
  18. {  
  19.    private static Color PALE_YELLOW = new Color (1.0f,1.0f,0.0f,0.2f);  
  20.    private static Color PALE_GREEN = new Color (0.0f,1.0f,0.0f,0.2f);  
  21.    private static JLayer<JPanel> createLayer ()  
  22.    {  
  23.       LayerUI<JPanel> layerUI;  
  24.       layerUI = new LayerUI<JPanel> ()  
  25.       {  
  26.          public void paint (Graphics g,JComponent c)  
  27.          {  
  28.             // Paint the wallpaper.  
  29.             Graphics2D g2 = (Graphics2D) g;  
  30.             g2.setPaint (new GradientPaint (0,0,PALE_YELLOW,  
  31.                                             5,0,PALE_GREEN,true));  
  32.             g2.fillRect (0,0,c.getWidth (),c.getHeight ());  
  33.             // Make sure that layer's panel view is not opaque.  
  34.             JLayer l = (JLayer) c;  
  35.             if (l.getView ().isOpaque ())  
  36.                 ((JPanel) l.getView ()).setOpaque (false);  
  37.             // Paint the view minus its background.  
  38.             super.paint (g,c);  
  39.          }  
  40.       };  
  41.       // Create a user interface to be decorated.  
  42.       JPanel pnl = new JPanel ();  
  43.       JLabel lblName = new JLabel ("Name:");  
  44.       pnl.add (lblName);  
  45.       final JTextField txtName = new JTextField (20);  
  46.       pnl.add (txtName);  
  47.       JButton btnReverse = new JButton ("Reverse");  
  48.       pnl.add (btnReverse);  
  49.       ActionListener al;  
  50.       al = new ActionListener ()  
  51.            {  
  52.                public void actionPerformed (ActionEvent ae)  
  53.                {  
  54.                   String txt = txtName.getText ();  
  55.                   txt = new StringBuffer (txt).reverse ().toString ();  
  56.                   txtName.setText (txt);  
  57.                }  
  58.            };  
  59.       btnReverse.addActionListener (al);  
  60.       // Create the layer for the panel using our custom layerUI.  
  61.       return new JLayer<JPanel> (pnl,layerUI);  
  62.    }  
  63.    private static void createAndShowUI ()  
  64.    {  
  65.       JFrame frame = new JFrame ("Reverse Text");  
  66.       frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);  
  67.       frame.add (createLayer ());  
  68.       frame.pack ();  
  69.       frame.setLocationRelativeTo (null);  
  70.       frame.setVisible (true);  
  71.    }  
  72.    public static void main (String [] args)  
  73.    {  
  74.       Runnable r = new Runnable ()  
  75.                    {  
  76.                        public void run ()  
  77.                        {  
  78.                           createAndShowUI ();  
  79.                        }  
  80.                    };  
  81.       EventQueue.invokeLater (r);  
  82.    }  

#p#

其中createLayer()方法是最重要的代碼,它創建了一個匿名LayerUI子類的實例,繪制了墻紙和JPanel視圖,創建了UI,在實例中包含了UI的面板容器。

繪制操作是由LayerUI's public void paint(Graphics g,JComponent c)方法實現的,第二個參數引用了視圖(被裝飾的組件)中的JLayer實例,不是引用的視圖。

在視圖后創建了漸變渲染墻紙后,調用paint()方法確保視圖(沒有嵌套面板的單一面板)是透明的,它將會隱藏墻紙,然后繪制視圖。

paint()對比paintLayer()

JDK文檔中除了提到paint()方法外,還提到了paintLayer()方法,我這里之所以選擇paint()方法,是因為LayerUI中不存在paintLayer(),此外,文檔還錯誤地引用paintLayer() doesn't exist in LayerUI. Furthermore,the documentation incorrectly refers to addPropertyChange(),configureGraphics(),processComponentEvent(),processFocusEvent(),processHierarchyBoundsEvent(),processHierarchyEvent(),processKeyEvent(),processMouseEvent(),processMouseMotionEvent(),processMouseWheelEvent(),and repaintLayer()這些在LayerUI中根本不存在的方法,當然這些方法也可能在JDK 7最終發布時會包含進來。

圖1顯示了有墻紙背景的UI。

顯示了有墻紙背景的UI
圖1 在用戶界面后加了一層墻紙背景

ReverseText程序演示了自定義繪制,避開了事件觸發,不需要檢測事件,因為程序只關心墻紙的繪制效果。相反,清單2顯示了一個需要響應鼠標移動事件的程序代碼。

清單2. BrandedUI.java

  1. // BrandedUI.java  
  2. import java.awt.AWTEvent;  
  3. import java.awt.Color;  
  4. import java.awt.Component;  
  5. import java.awt.EventQueue;  
  6. import java.awt.Font;  
  7. import java.awt.GradientPaint;  
  8. import java.awt.Graphics;  
  9. import java.awt.Graphics2D;  
  10. import java.awt.GridLayout;  
  11. import java.awt.Point;  
  12. import java.awt.event.MouseEvent;  
  13. import javax.swing.JComponent;  
  14. import javax.swing.JFrame;  
  15. import javax.swing.JLabel;  
  16. import javax.swing.JLayer;  
  17. import javax.swing.JPanel;  
  18. import javax.swing.JTextField;  
  19. import javax.swing.SwingUtilities;  
  20. import javax.swing.plaf.LayerUI;  
  21. public class BrandedUI  
  22. {  
  23.    private static Color PALE_BLUE = new Color (0.0f, 0.0f, 1.0f, 0.3f);  
  24.    private static Color PALE_RED = new Color (1.0f, 0.0f, 0.0f, 0.3f);  
  25.    private static Font BRAND_FONT = new Font ("Arial", Font.BOLD, 18);  
  26.    private static String MSG = "My brand";  
  27.    private static JLayer<JPanel> createLayer ()  
  28.    {  
  29.       LayerUI<JPanel> layerUI;  
  30.       layerUI = new LayerUI<JPanel> ()  
  31.       {  
  32.          private Color color = PALE_BLUE;  
  33.          public void installUI (JComponent c)  
  34.          {  
  35.             super.installUI (c);  
  36.             ((JLayer) c).setLayerEventMask (AWTEvent.MOUSE_MOTION_EVENT_MASK);  
  37.          }  
  38.          public void eventDispatched (AWTEvent e,  
  39.                                       JLayer <? extends JPanel> l)  
  40.          {  
  41.             MouseEvent me = (MouseEvent) e;  
  42.             Point pt = SwingUtilities.convertPoint ((Component) me.getSource (),  
  43.                                                     me.getX (), me.getY (), l);  
  44.             int cx = l.getWidth ()/2;  
  45.             int cy = l.getHeight ()/2;  
  46.             if (pt.x > cx-45 && pt.x < cx+45 && pt.y > cy-10 && pt.y < cy+10)  
  47.                 color = PALE_RED;  
  48.             else  
  49.                 color = PALE_BLUE;  
  50.             l.repaint ();  
  51.          }  
  52.          public void paint (Graphics g, JComponent c)  
  53.          {  
  54.             // Paint the view.  
  55.             super.paint (g, c);  
  56.             // Paint the brand.  
  57.             g.setColor (color);  
  58.             g.setFont (BRAND_FONT);  
  59.             int width = g.getFontMetrics ().stringWidth (MSG);  
  60.             int height = g.getFontMetrics ().getHeight ();  
  61.             g.drawString (MSG, (c.getWidth ()-width)/2,  
  62.                           c.getHeight ()/2+height/4);  
  63.          }  
  64.          public void uninstallUI (JComponent c)  
  65.          {  
  66.             super.uninstallUI (c);  
  67.             ((JLayer) c).setLayerEventMask (0);  
  68.          }  
  69.       };  
  70.       // Create a user interface to be decorated.  
  71.       JPanel pnlMain = new JPanel ();  
  72.       pnlMain.setLayout (new GridLayout (2, 1));  
  73.       JPanel pnlTemp = new JPanel ();  
  74.       JLabel lblName = new JLabel ("Name:");  
  75.       pnlTemp.add (lblName);  
  76.       JTextField txtName = new JTextField (20);  
  77.       pnlTemp.add (txtName);  
  78.       pnlMain.add (pnlTemp);  
  79.       pnlTemp = new JPanel ();  
  80.       JLabel lblAddr = new JLabel ("Address:");  
  81.       pnlTemp.add (lblAddr);  
  82.       JTextField txtAddr = new JTextField (20);  
  83.       pnlTemp.add (txtAddr);  
  84.       pnlMain.add (pnlTemp);  
  85.       // Create the layer for the main panel using our custom layerUI.  
  86.       return new JLayer<JPanel> (pnlMain, layerUI);  
  87.    }  
  88.    private static void createAndShowUI ()  
  89.    {  
  90.       JFrame frame = new JFrame ("Branded UI");  
  91.       frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);  
  92.       frame.add (createLayer ());  
  93.       frame.pack ();  
  94.       frame.setLocationRelativeTo (null);  
  95.       frame.setVisible (true);  
  96.    }  
  97.    public static void main (String [] args)  
  98.    {  
  99.       Runnable r = new Runnable ()  
  100.                    {  
  101.                        public void run ()  
  102.                        {  
  103.                           createAndShowUI ();  
  104.                        }  
  105.                    };  
  106.       EventQueue.invokeLater (r);  
  107.    }  
  108. }  
  109.  

上面的代碼渲染UI上的文本印記,我們通常使用印記提醒用戶使用的是試用軟件,印記文本是半透明的,以便背景可以全部顯示,我們不希望這個印記給用戶造成太大的干擾。

另一方面,我們希望用戶能注意到這個印記,讓他們下定決心購買這款軟件,清單2中的代碼通過改變印記的顏色(改成淡紅色)來達到這個目的,當鼠標移到初始值是綠色的印記面板上時,顏色就變成淡紅色。

#p#

事件檢測

JLayer和LayerUI結合起來可以檢測視圖任意區域上發生的事件(包括嵌套的子組件),這些類共同提供了4個方法來檢測事件。

· public void setLayerEventMask(long layerEventMask)

調用這個JLayer方法時必須使用位掩碼AWTEvent常量選擇它檢測到的事件類型,如:setLayerEventMask (AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);可以檢測到按鍵和焦點改變事件。

◆public void installUI(JComponent c)

這個LayerUI方法通常放在setLayerEventMask()方法之前,這個方法類的代碼首先調用超類方法(super.installUI (c);),然后是引用JLayer的JComponent參數,最后使用setLayerEventMask(): ((JLayer) c).setLayerEventMask(AWTEvent.KEY_EVENT_MASK);返回的結果。

◆public void uninstallUI(JComponent c)

這個LayerUI方法放在沒有參數的setLayerEventMask()方法后,這個方法內的代碼首先調用超類方法(super.uninstallUI (c);),然后是引用JLayer的JComponent參數,最后使用setLayerEventMask(): ((JLayer) c).setLayerEventMask(0);返回的結果。

◆public void eventDispatched(AWTEvent e, Jlayer l)

只要前面注冊的事件發生了,就會調用這個LayerUI方法,在這個方法中插入的代碼負責響應事件,并恰當地更新層,更新了不同的繪制屬性(如顏色)后,通過傳遞給這個方法的JLayer參數調用repaint()方法重新繪制視圖。

在清單2中,LayerUI的installUI()方法調用setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK)檢測鼠標移動事件,它又調用eventDispatched()方法返回結果。

這個方法首先調用javax.swing.SwingUtilities類的convertPoint()方法確定鼠標移動事件相對于層的坐標位置。

接下來這個方法通過檢查它的坐標是否落在圍繞UI中心的一個矩形區域內,檢測鼠標指針是否移到印記文本上方,如果坐標剛好落在這個矩形區域內,印記文本的顏色就變為淡紅色,除此以外,印記文本的顏色就恢復為藍色。

圖2顯示了鼠標移到印記文本上方前后的顏色變化。

顯示了鼠標移到印記文本上方前后的顏色變化
圖2 鼠標指針移到文本上方時,重新繪制文本顏色給用戶一個不刺眼的提示

小結

JLayer對自定義繪制和事件檢測的支持讓你可以改進UI的各個組件,你可以將這個Swing組件和半透明及任意形狀窗口特性結合起來使用,讓你可以設計出更有趣的用戶界面。

【編輯推薦】

  1. 探秘JDK 7之二:半透明和任意形狀的窗口
  2. 探秘JDK 7:將會出現新的語言特性
  3. 我們真的能沒有Java嗎?
  4. 探秘Java 7:JVM動態語言支持詳解
  5. 探秘Java 7新增垃圾回收器G1特性
責任編輯:佚名 來源: IT168
相關推薦

2012-03-14 11:08:32

JavaJLayer

2011-07-29 09:31:32

JDK 7

2011-05-20 09:35:22

JDK7

2011-05-20 09:43:23

JDK7

2011-05-20 09:53:00

JDK7

2011-05-20 10:15:06

JDK7

2011-05-20 10:28:29

JDK7

2010-06-22 11:07:42

JDK 7Java開發Java

2010-06-23 09:25:50

JDK 7Java開發Java

2011-05-20 10:20:11

JDK7

2009-07-15 13:06:38

Swing組件

2009-07-10 18:06:59

JTree Swing

2009-07-17 12:54:13

2022-03-14 15:36:34

Row容器組件Column容器組件鴻蒙

2011-05-20 09:59:42

JDK7

2010-06-29 09:23:09

JDK 7I|ONIO.2

2009-08-24 08:37:52

Windows 7防火墻

2009-07-15 11:02:32

Swing組件

2009-07-10 12:30:12

Swing組件

2009-07-14 17:21:42

Swing組件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九导航| 久久出精品 | 国产在线一级片 | 久久综合久久综合久久 | 精品精品 | 日韩成人av在线播放 | 欧美一级片免费看 | av资源中文在线天堂 | 少妇一级淫片免费放播放 | 亚洲精品久久久久久宅男 | 9999国产精品欧美久久久久久 | 天天操一操 | 丝袜天堂 | 97视频人人澡人人爽 | 久久97精品 | 欧美一级二级在线观看 | 亚洲成av人片在线观看无码 | 久久久91 | 国产精品日本一区二区不卡视频 | 精品视频在线播放 | 国精产品一区二区三区 | 亚洲精品三级 | 黑人久久 | 久久精品国产精品青草 | 一区二区三区免费观看 | 久久蜜桃av一区二区天堂 | 91精品国产麻豆 | 欧美一级做a爰片免费视频 国产美女特级嫩嫩嫩bbb片 | 91一区二区 | 国产高潮好爽受不了了夜夜做 | 在线午夜 | 99在线免费视频 | 欧美一区两区 | 日韩精品成人在线 | 亚欧洲精品在线视频免费观看 | 99久久精品免费看国产免费软件 | 999久久久| 免费国产视频在线观看 | 国产精品一区二区久久 | 日韩不卡在线观看 | 欧美一区在线看 |