【问题标题】:Listening/Handling JPanel events侦听/处理 JPanel 事件
【发布时间】:2012-04-07 02:13:38
【问题描述】:

女士们,先生们,晚上好,

我有一个无法解决的 Java Swing 问题,也许你可以帮助我。这里是:

  • 我有一个使用 BorderLayout 的 JFrame 和许多 JPanel。
  • 每次我需要建立一个新屏幕(即从主菜单,当单击搜索按钮时,转到搜索菜单),我只需删除位于中心的组件(JPanel),然后将而是在中心的新屏幕(新 JPanel)。
  • 这样,每次我想建立一个新屏幕时,我就不会调用我所有的页眉和页脚对象。

除了这个小问题之外,这个系统一切正常:我想在每次创建新的 JPanel 或更改回现有的 JPanel 时触发一些方法(一般来说,每次出现 JPanel 时)。

为了做到这一点,我尝试实现 ComponentListener 的 componentShown(ComponentEvent e) 方法,并将 ComponentListener 添加到我放在 JFrame 中心的 JPanel 中,但它不起作用。在此之后,我做了一些研究,发现这个 componentShown (@ComponentListener) 方法仅在 JPanel 的可见性发生变化(从不可见到可见或相反)时才有效。不幸的是,我没有改变 JPanel 的可见性,只是用另一个替换它:删除当前的,然后添加新的。下面的代码说明了我如何替换 JPanel。

// Get the JPanel located in the center of our JFrame
JPanel currentView = (JPanel) myFrame.getContentPane().getComponent( 2 );

if ( currentView != null )
{
   // Remove it from the JPanel         
   myFrame.getContentPane().remove( currentView );
}

// Add the new JPanel    
myFrame.getContentPane().add( otherView, BorderLayout.CENTER );

// Pack the JFrame and show it
myFrame.pack();

这就是我所拥有的。如果您能帮助我,我将不胜感激。

【问题讨论】:

  • 除了自己添加/删除JPanels 之外,您还可以在contentPaneCENTER 中使用JPanelCardLayoutHow to use CardLayout.
  • @Jeffrey,感谢您的快速响应。你说的很好,很合理,但我正在处理的是一个小组工作。我们有一个我们现在正在遵循的模式,在建议改变我们的模式(BorderLayout --> CardLayout)之前,我想 - 至少 - 尝试用当前模式提出一个解决方案。
  • 您使用 BorderLayout 并不意味着您也不能使用 CardLayout,因为它们不是互斥的。 BorderLayout.CENTER 面板可以是持卡人,使用 CardLayout 的 JPanel。
  • 我不认为我理解你的问题。您有从一个面板切换到另一个面板的代码,并且您正在询问切换面板后如何做一些额外的事情......为什么不简单地在调用 add 方法后添加代码而不是尝试使用侦听器?跨度>
  • 直观的“可见性”通知通过 AncestorListener 发生:docs.oracle.com/javase/7/docs/api/javax/swing/event/…

标签: java swing event-handling jpanel event-listener


【解决方案1】:

我认为这个问题对应HierarchyListener,用于比较

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ContainerListener extends JFrame {

    private static final long serialVersionUID = 1L;

    public ContainerListener() {
        super("Test");
        setContentPane(new TestPanel());
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] parameters) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ContainerListener containerListener = new ContainerListener();
            }
        });
    }

    private class TestPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        TestPanel() {
            setLayout(new FlowLayout(FlowLayout.LEFT));
            add(new JButton(new AbstractAction("Add label") {

                private static final long serialVersionUID = 1L;
                private int n = 0;

                @Override
                public void actionPerformed(ActionEvent event) {
                    TestPanel.this.add(new JLabel("Label " + ++n));
                    validate();
                }
            }));
            addHierarchyListener(new HierarchyListener() {

                @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: " + e.getChanged());
                        } else {
                            System.out.println("Components: " + e.getChanged());
                        }
                    }
                }
            });
            addContainerListener(new ContainerAdapter() {

                @Override
                public void componentAdded(ContainerEvent event) {
                    System.out.println("componentAdded : " + event.getChild() + "containerName" + " was added");
                }
            });

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }
}

【讨论】:

  • 非常感谢您的回答。当我使用 HierarchyListener 而不是 ContainerListener 时,它起作用了!!
【解决方案2】:

我强烈建议您听取@Jeffrey 的建议,但如果您继续进行此设计,那么实现ContainerListener 接口可能会很有用。

如有疑问,请查阅 API。

【讨论】:

  • 我刚刚尝试了您的解决方案并实现了 ContainerListener。它与新创建的 JPanel 完美配合。不幸的是,当返回到现有的 JPanel 时它不起作用。无论是返回一个现有的 JPanel 还是创建一个新的 JPanel 并放置它的视图,我总是使用上面相同的方式来删除和添加一个视图到我的框架中。我不明白为什么将现有面板放在框架上时它不起作用......:S
  • 您需要WindowListenerWindowFocusListenerWindowStateListener
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
相关资源
最近更新 更多