2

我正在处理一些奇怪的遗留代码。他们有一个实现 JPanel 的自定义对象。该JPanel对象是主应用程序中的辅助弹出屏幕。我遇到的问题是检测辅助弹出屏幕何时关闭。

我尝试WindowListener为该类实现一个,但是当我尝试添加它时,没有JFrame与该对象关联。我假设这是因为他们正在使用自定义对象并且它是嵌入式弹出屏幕。

我试图检索一个JFrame使用:

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this);

在 a 上失败了NullPointerException。我不知道为什么在此页面上检测到右上角的“x”关闭按钮如此困难!我应该提到他们能够将鼠标和按键监听器添加到嵌入在JPanel. 但是整个窗口的外部监听器给我带来了麻烦。

(请多多包涵,这是我的第一篇 stackoverflow 帖子,我是 Swing 新手。)

非常感谢!!

4

3 回答 3

5

尝试为那个奇怪的面板调用getParent()。它应该返回父 GUI 组件。如果这仍然不是您的框架,而是一些中间面板,请在其上调用 getParent()。顶级组件返回 null。

   Component p = strangePanel;
   while ( p != null && ! (p instanceof Window))
     p = p.getParent();

   ((Window) p ).addWindowListener(..);
于 2013-01-18T06:20:33.273 回答
0

无法理解为什么您在以下位置收到“NullPointerException”:

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this);

在两种情况下会发生这种情况:

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(null);

在您的情况下,这是不可能的,因为您已将用作参数。

其次,您是否在上面的代码行中进行了一些其他操作,例如:

JFrame parentFrame = ((JFrame) SwingUtilities.getWindowAncestor(this)).someOperation();

在这种情况下,如果您的对象表示顶部窗口,那么您应该得到“NullPointerException”,因为顶部父级的祖先返回为“null”。在其他情况下,我怀疑您会遇到此异常。

您能否在遇到异常的地方发布一段代码。

于 2013-01-18T06:44:40.393 回答
0

对于这个答案,我做了一个小假设,即 Nullpointer 没有被抛出您提到的行,而是当您尝试将 WindowListener 添加到 parentFrame 时。这很可能是因为您正在打电话

JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this);

在将 JPanel 添加到 JFrame 层次结构之前。

这是有关如何解决此问题的粗略代码示例。认为它等待面板被通知它已附加到其层次结构中某处的 JFrame。

package test;

import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class HierarchyTest extends JPanel {

    protected static void loadApp() {
        HierarchyTest test = new HierarchyTest();
        JFrame frame = new JFrame();
        frame.add(test);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                loadApp();

            }
        });

    }

    public HierarchyTest() {
        this.addHierarchyListener(new HierarchyListener() {

            @Override
            public void hierarchyChanged(HierarchyEvent e) {
                // This can be optimized by checking the right flags, but I leave that up to you to look into
                boolean connected = setupListenersWhenConnected();

                if (connected) {
                    HierarchyTest.this.removeHierarchyListener(this);
                }
            }
        });
    }

    protected boolean setupListenersWhenConnected() {
        JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
        if (parentFrame == null) {
            return false;
        }
        parentFrame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Implementation here
                System.out.println("This window is closing!");
            }
        });
        return true;
    }
}
于 2013-01-18T08:42:41.123 回答