<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Swing


    天行健 君子以自強(qiáng)不息

    posts - 69, comments - 215, trackbacks - 0, articles - 16
       :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    監(jiān)聽JComponent顯示事件

    Posted on 2010-02-04 22:09 zht 閱讀(1529) 評(píng)論(1)  編輯  收藏 所屬分類: Swing

        很多時(shí)候,我們需要在界面初始化以后對(duì)程序進(jìn)行某些設(shè)置,舉個(gè)例子,當(dāng)界面呈現(xiàn)出來以后,設(shè)置下SplitPane的的百分比(關(guān)于這個(gè)為什么必須這么處理請(qǐng)參考java源代碼)。很容易我們就想到給程序添加ComponentListener監(jiān)聽,然后在監(jiān)聽中作處理,如下所示

    panel.addComponentListener(new ComponentAdapter() {

                         public void componentShown(ComponentEvent e) {

                                System.out.println("panel:shown");

                         }

                  });

    但是并沒有和我們想象的那樣,當(dāng)組件在界面上顯示出來的時(shí)候firecomponentShown類型的事件的,下面我們通過研究源代碼分析下原因

    首先的問題是在什么地方會(huì)fireComponentEvent

    通過查看源代碼,我們可以看到實(shí)在Componentshow()方法中

    ComponentEvent e = new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);

    Toolkit.getEventQueue().postEvent(e);

    具體代碼,請(qǐng)參考java源程序

    也就是說只有在組件調(diào)用到setVisible(true)的時(shí)候才會(huì)fireComponentEvent

    但是你會(huì)發(fā)現(xiàn),即便是我們調(diào)用JComponentsetVisible(true),也不會(huì)監(jiān)聽到shown事件

    原因主要是JComponent重載了setVisible方法

    如下

    public void setVisible(boolean aFlag) {

            if(aFlag != isVisible()) {

                super.setVisible(aFlag);

                Container parent = getParent();

                if(parent != null) {

                    Rectangle r = getBounds();

                    parent.repaint(r.x,r.y,r.width,r.height);

                }

               // Some (all should) LayoutManagers do not consider components

               // that are not visible. As such we need to revalidate when the

               // visible bit changes.

               revalidate();

            }

    }

    因?yàn)?/span>JComponentvisible屬性默認(rèn)就是true,所以不會(huì)調(diào)用到ComponentsetVisible方法,所以也不會(huì)fireComponentEvent,當(dāng)然,如果你調(diào)用下JComponentsetVisible(false)+setVisible(true)是會(huì)fireComponentEvent.COMPONENT_SHOWN事件的,(但是在里面很可能得不到當(dāng)前組件的大小信息或者不能SplitPane設(shè)置分割比例,因?yàn)檫@個(gè)時(shí)候界面還沒有初始化),而且如果是JFrameJDialogJApplet等也是沒問題的,因?yàn)樗麄冋{(diào)用的都是ComponentsetVisible方法(所以給這些頂層組件添加ComponentListener是沒有問題的,都會(huì)監(jiān)聽到)

    如果不想使用上述方法,還有另外一種方式就是添加HierarchyListener監(jiān)聽,因?yàn)楫?dāng)頂層組件(JFrame,JDialog)setVisible(true)界面顯示的時(shí)候,里面都會(huì)fireHierarchyEvent,具體代碼如下(詳細(xì)代碼請(qǐng)參考Componentshow()方法)

           createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,

                                         this, parent,

                                         HierarchyEvent.SHOWING_CHANGED,

                                              Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));

    createHierarchyEvents方法會(huì)在每個(gè)組件上fireHierarchyEvent,至于具體細(xì)節(jié),有時(shí)間的可以dubug下,具體的解決方法如下

           panel.addHierarchyListener(new HierarchyListener() {

                         public void hierarchyChanged(HierarchyEvent e) {

                                if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {

                                       if (e.getComponent().isShowing()) {

                                              System.out.println(panel.getBounds());

                                              System.out.println("panel:hshow");

                                       }

                                       else {

                                              System.out.println("panel:hhide");

                                       }

                                }

                         }

                  });

    測(cè)試代碼如下
    public class Test {
        
    public static void main(String[] args) {
            
    new Test();
        }


        
    public Test() {
            
    final JPanel panel = new JPanel();
            panel.addComponentListener(
    new ComponentAdapter() {
                
    public void componentShown(ComponentEvent e) {
                    System.out.println(panel.getBounds());
                    System.out.println(
    "panel:shown");
                }

            }
    );
            
    //        panel.setVisible(false);
            
    //        panel.setVisible(true);
            panel.addHierarchyListener(new HierarchyListener() {
                
    public void hierarchyChanged(HierarchyEvent e) {
                    
    if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0{
                        
    if (e.getComponent().isShowing()) {
                            System.out.println(panel.getBounds());
                            System.out.println(
    "panel:hshow");
                        }

                        
    else {
                            System.out.println(
    "panel:hhide");
                        }

                    }

                }

            }
    );

            JFrame frame 
    = new JFrame();

            frame.addComponentListener(
    new ComponentAdapter() {
                
    public void componentShown(ComponentEvent e) {
                    System.out.println(
    "frame:shown");
                }

            }
    );

            frame.setContentPane(panel);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(
    500400);
            frame.setVisible(
    true);
        }

    }

    主站蜘蛛池模板: 97在线免费视频| 亚洲短视频在线观看| 免费人成网站永久| 国产免费无遮挡精品视频| 亚洲精品无码专区| 在线观看永久免费视频网站| 亚洲人成无码网站在线观看 | 曰批免费视频播放在线看片二| 日韩在线免费电影| jizzjizz亚洲日本少妇| 又粗又大又猛又爽免费视频| 国产亚洲成在线播放va| 中文亚洲成a人片在线观看| 国产性生大片免费观看性| 亚洲国产精品无码久久一区二区| 日本在线免费观看| 亚洲日韩中文字幕天堂不卡| 啦啦啦高清视频在线观看免费 | 精品国产污污免费网站入口| 亚洲精品乱码久久久久久久久久久久 | 91在线老王精品免费播放| 91亚洲精品麻豆| 永久中文字幕免费视频网站| 免费又黄又爽又猛大片午夜| 亚洲精品夜夜夜妓女网| 久久午夜羞羞影院免费观看| 学生妹亚洲一区二区| 亚洲成aⅴ人片久青草影院| 免费在线观看一级片| 亚洲国产最大av| 亚洲国产成人精品无码久久久久久综合 | 亚洲av无码国产精品夜色午夜| 99国产精品免费视频观看| 亚洲中文字幕无码久久2020| 亚洲AV中文无码乱人伦在线视色 | 99久久99久久精品免费看蜜桃 | 亚洲美女高清一区二区三区| 日韩精品极品视频在线观看免费 | 又黄又爽的视频免费看| 日本免费中文视频| 亚洲爆乳无码精品AAA片蜜桃|