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

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

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

    Swing


    天行健 君子以自強不息

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

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

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

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

    panel.addComponentListener(new ComponentAdapter() {

                         public void componentShown(ComponentEvent e) {

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

                         }

                  });

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

    首先的問題是在什么地方會fireComponentEvent

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

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

    Toolkit.getEventQueue().postEvent(e);

    具體代碼,請參考java源程序

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

    但是你會發(fā)現(xiàn),即便是我們調(diào)用JComponentsetVisible(true),也不會監(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();

            }

    }

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

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

           createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,

                                         this, parent,

                                         HierarchyEvent.SHOWING_CHANGED,

                                              Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));

    createHierarchyEvents方法會在每個組件上fireHierarchyEvent,至于具體細節(jié),有時間的可以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");

                                       }

                                }

                         }

                  });

    測試代碼如下
    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);
        }

    }

    主站蜘蛛池模板: 国产高清对白在线观看免费91 | 一级黄色免费网站| 夜夜嘿视频免费看| 国产亚洲中文日本不卡二区 | 国产精品二区三区免费播放心 | 亚洲日产乱码一二三区别 | 亚洲AV午夜成人片| 在线成人精品国产区免费| 亚洲欭美日韩颜射在线二| 国产日韩AV免费无码一区二区| 日本亚洲欧洲免费天堂午夜看片女人员 | 免费一级毛片正在播放| 最好2018中文免费视频| 亚洲熟伦熟女新五十路熟妇| 99久久免费国产特黄| 亚洲好看的理论片电影| 91网站免费观看| 男人的天堂av亚洲一区2区| 五月婷婷亚洲综合| 美女被免费网站91色| 亚洲伊人久久大香线蕉苏妲己| 亚洲国产精品免费观看| 亚洲国产成人无码AV在线影院| 亚洲视频一区二区| 无码专区AAAAAA免费视频| 亚洲综合色7777情网站777| 国产男女猛烈无遮挡免费视频| 好吊色永久免费视频大全| 亚洲国产天堂久久综合网站| 成人毛片18女人毛片免费视频未| 农村寡妇一级毛片免费看视频| 亚洲精品制服丝袜四区| 台湾一级毛片永久免费 | 91情国产l精品国产亚洲区| 成全影视免费观看大全二| 成人午夜影视全部免费看| 久久久久亚洲AV成人片| 国产乱人免费视频| 无码国产精品一区二区免费模式| 亚洲色偷偷偷综合网| 亚洲色偷偷偷鲁综合|