检测 JPanel 卸载/关闭事件

Posted

技术标签:

【中文标题】检测 JPanel 卸载/关闭事件【英文标题】:Detecting a JPanel Unloading/Close Events 【发布时间】:2013-12-03 06:46:25 【问题描述】:

全部

我有一个 JPanel,说是 JTabbedPane 的容器,其中包含一个设计和一个预览面板。

JPanel 在 JFrame 中,

预览面板包含一个 JME3 画布。

我想要完成的是,每当用户移动到应用程序中的另一个面板时,我可以捕获容器 Jpanel 的卸载并关闭 JME3 应用程序,

我找到了以下主题,

Similar Threads 1

Similar Thread 2

我通过这些线程了解到 HierarchyListener 可能对我有用, 但我被卡住了如何在那里获得特定的面板卸载检测?

谢谢 米希尔

【问题讨论】:

【参考方案1】:

有三个 Listener 对这些事件做出反应 AncestorListener、ComponentListener、HierarchyListener

默认情况下 ComponentListener 是可行的

.

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

public class CardlayoutTest extends JFrame 

    private static final long serialVersionUID = 1L;
    public CardLayout card = new CardLayout();

    public CardlayoutTest() 
        JPanel pnlA = new JPanel(new BorderLayout());
        pnlA.add(new JButton("A"), BorderLayout.CENTER);
        JPanel pnlB = new JPanel(new BorderLayout());
        pnlB.add(new JButton("B"), BorderLayout.CENTER);
        JPanel pnlC = new JPanel(new BorderLayout());
        pnlC.add(new JButton("C"), BorderLayout.CENTER);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(card);
        add(pnlA, "A");
        add(pnlB, "B");
        add(pnlC, "C");

        pnlA.addAncestorListener(new EventHandler());
        pnlB.addAncestorListener(new EventHandler());
        pnlC.addAncestorListener(new EventHandler());

        pnlA.addHierarchyListener(new EventHandler());
        pnlB.addHierarchyListener(new EventHandler());
        pnlB.addHierarchyListener(new EventHandler());

        pnlA.addComponentListener(new EventHandler());
        pnlB.addComponentListener(new EventHandler());
        pnlB.addComponentListener(new EventHandler());
    

    class EventHandler implements AncestorListener, ComponentListener, HierarchyListener 

        @Override
        public void ancestorAdded(AncestorEvent event) 
            System.out.println("CardlayoutTest.EventHandler.ancestorAdded()");
        

        @Override
        public void ancestorMoved(AncestorEvent event) 
            System.out.println("CardlayoutTest.EventHandler.ancestorMoved()");
        

        @Override
        public void ancestorRemoved(AncestorEvent event) 
            System.out.println("CardlayoutTest.EventHandler.ancestorRemoved()");
        

        @Override
        public void hierarchyChanged(HierarchyEvent e) 
            System.out.println("Components Change: " + e.getChanged());
            if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) 
                if (e.getComponent().isDisplayable()) 
                    System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());
                 else 
                    System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());
                
            
            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) 
                if (e.getComponent().isDisplayable()) 
                    System.out.println("Components SHOWING_CHANGED : " + e.getChanged());
                 else 
                    System.out.println("Components SHOWING_CHANGED : " + e.getChanged());
                
            
        

        public void componentHidden(ComponentEvent e) 
            System.out.println(e.getComponent().getClass().getName() + " --- Hidden");
        

        public void componentMoved(ComponentEvent e) 
            System.out.println(e.getComponent().getClass().getName() + " --- Moved");
        

        public void componentResized(ComponentEvent e) 
            System.out.println(e.getComponent().getClass().getName() + " --- Resized ");
        

        public void componentShown(ComponentEvent e) 
            System.out.println(e.getComponent().getClass().getName() + " --- Shown");
        
    

    public static void main(String[] args) 
        CardlayoutTest t = new CardlayoutTest();
        t.setSize(500, 500);
        System.out.println("CardlayoutTest.main()------------------------ FIRST");
        t.card.show(t.getContentPane(), "A");
        t.setVisible(true);
        System.out.print("\n");
        try 
            Thread.sleep(2000);
         catch (InterruptedException e) 
        
        System.out.println("CardlayoutTest.main()------------------------ SECOND");
        t.card.show(t.getContentPane(), "B");
        System.out.print("\n");
        try 
            Thread.sleep(2000);
         catch (InterruptedException e) 
        
        System.out.println("CardlayoutTest.main()------------------------ THIRD");
        t.card.show(t.getContentPane(), "C");
        System.out.print("\n");
    

有事件

CardlayoutTest.main()------------------------ FIRST 组件更改: javax.swing.JPanel[,0,0,0x0,invalid,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 DISPLAYABILITY_CHANGED : javax.swing.JPanel[,0,0,0x0,invalid,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: javax.swing.JPanel[,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 DISPLAYABILITY_CHANGED : javax.swing.JPanel[,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: javax.swing.JPanel[,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 DISPLAYABILITY_CHANGED : javax.swing.JPanel[,0,0,0x0,invalid,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 组件 SHOWING_CHANGED : Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 组件变化: Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 组件 SHOWING_CHANGED : Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 组件变化: Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 组件 SHOWING_CHANGED : Listeners.CardlayoutTest[frame0,0,0,500x500,layout=java.awt.BorderLayout,title=,resizable,normal,defaultCloseOperation=EXIT_ON_CLOSE,rootPane=javax.swing.JRootPane[,8,31,484x461,layout=javax.swing. JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]

CardlayoutTest.EventHandler.ancestorMoved() javax.swing.JPanel --- 调整大小的 javax.swing.JPanel --- 调整大小的 javax.swing.JPanel --- 调整大小的 CardlayoutTest.EventHandler.ancestorMoved() CardlayoutTest.EventHandler.ancestorAdded() CardlayoutTest.main()------------------------ 第二个组件 改变: javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 SHOWING_CHANGED : javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: javax.swing.JPanel[,0,0,484x461,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 SHOWING_CHANGED : javax.swing.JPanel[,0,0,484x461,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: javax.swing.JPanel[,0,0,484x461,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 SHOWING_CHANGED : javax.swing.JPanel[,0,0,484x461,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]

CardlayoutTest.EventHandler.ancestorRemoved() javax.swing.JPanel --- 隐藏 CardlayoutTest.EventHandler.ancestorAdded() javax.swing.JPanel --- 显示 javax.swing.JPanel --- 显示 CardlayoutTest.main()------------------------ 第三个组件更改: javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 SHOWING_CHANGED : javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件变化: javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] 组件 SHOWING_CHANGED : javax.swing.JPanel[,0,0,484x461,hidden,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=] CardlayoutTest.EventHandler.ancestorRemoved() javax.swing.JPanel --- 隐藏的 javax.swing.JPanel --- 隐藏

CardlayoutTest.EventHandler.ancestorAdded()

【讨论】:

嗨,我现在就试试,但我已经使用了 grouplayout,但它仍然适用吗? 是的,在将 ComponentListener 添加到 JPanel(使用 Grouplayout)的情况下,但 LayoutManager 与此侦听器无关【参考方案2】:

在面板上实现 AncestorListener,你想知道加载/卸载事件。我添加了一个按钮来显示和隐藏创建的 JPanel。下面是相同的代码。 AncestorListener 告诉我它何时完美加载和卸载。

public class PanelTrial extends javax.swing.JPanel implements AncestorListener 

     private Container frame;
     private javax.swing.JPanel btnPanel;

     public PanelTrial(Container frame) 
           this.frame = frame;
           initComponents();
           createBtnPanel();
           btnPanel.addAncestorListener(this);
     

      // Called on btn click event - to show/hide btnPanel
      private void updateRightPanel(boolean showBtnPanel) 
           jPanel1.removeAll();

           GroupLayout layout = (GroupLayout) jPanel1.getLayout();

           if (showBtnPanel) 
               layout.setHorizontalGroup(layout.createSequentialGroup()
                .addComponent(btnPanel));
               layout.setVerticalGroup(layout.createParallelGroup(
                Alignment.TRAILING).addComponent(btnPanel));

                 else 
                layout.setHorizontalGroup(layout.createSequentialGroup()
                .addComponent(rightPanel));
                layout.setVerticalGroup(layout.createParallelGroup(
                Alignment.TRAILING).addComponent(rightPanel));

            

            jPanel1.validate();
            this.validate();
       


     @Override
     public void ancestorAdded(AncestorEvent e) 
           if (e.getSource() == btnPanel) 
                System.out.println("BTNSPANEL LOADED / ADDED");
     

     @Override
     public void ancestorMoved(AncestorEvent e) 
                 // This is of no use for your purpose 
           System.out.println("Anc Moved - " + e.getSource());
      

      @Override
      public void ancestorRemoved(AncestorEvent e) 
           if (e.getSource() == btnPanel) 
             System.out.println("BTNSPANEL UNLOADED / REMOVED");
      

【讨论】:

以上是关于检测 JPanel 卸载/关闭事件的主要内容,如果未能解决你的问题,请参考以下文章

接收包安装和卸载事件

如何使用 React js 检测浏览器标签关闭事件?

如何在 Java 中检测 Image 对象上的鼠标单击事件?

如何使用javascript或php检测窗口关闭事件[重复]

UIPopoverController 在“点击关闭”时关闭 - 我如何检测此事件?

如何检测浏览器窗口/选项卡关闭事件?