当前位置: 首页 > 知识库问答 >
问题:

为什么在调用setVisible(false)和dispose()时,窗口/组件监听器的调用方式不同?

竺绍辉
2023-03-14

我看到的不同之处在于(运行在JDK 1.7上):

public class JDialogTest extends JDialog {
    private static final long serialVersionUID = 1L;

    public JDialogTest(JFrame owner){
        super(owner,ModalityType.APPLICATION_MODAL);
        init();
    }
    private void init() {
        this.getContentPane().setLayout(new GridLayout(1,2));
        JButton btnVisible = new JButton("Set visible false");
        btnVisible.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JDialogTest.this.setVisible(false);
            }
        });
        JButton btnDispose = new JButton("Dispose");
        btnDispose.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JDialogTest.this.dispose();
            }
        });
        this.getContentPane().add(btnVisible);
        this.getContentPane().add(btnDispose);
        this.pack();
    }

    public static void main(String[] args) {

        //A fake frame to test JDialog
        JFrame fakeFrame = new JFrame("Fake Frame");
        fakeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fakeFrame.getContentPane().setLayout(new BorderLayout());
        JButton btnOpen = new JButton("Open Dialog");
        fakeFrame.getContentPane().add(btnOpen,BorderLayout.CENTER);
        fakeFrame.pack();
        fakeFrame.setLocationRelativeTo(null);

        //Generate the test dialog
        final JDialogTest dialog = new JDialogTest(fakeFrame);
        dialog.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentShown(ComponentEvent e) {
                System.out.println("Component Shown");
            }
            @Override
            public void componentHidden(ComponentEvent e) {
                System.out.println("Component Hidden");
            }
        });

        dialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("Window open");
            }
            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("Window closed");
            }
        });
        dialog.setLocationRelativeTo(null);

        btnOpen.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dialog.setVisible(true);
            }
        });
        fakeFrame.setVisible(true);
    }
}

我考虑过这个帖子:

JDialog setVisible(false)vs

  • 在回答中似乎是应该没有区别的,使用dispose()...

我为什么要关心:当然是出于好奇,但也因为我使用按钮来关闭窗口(调用dispose()),并且界面也可以通过顶部/右侧窗口关闭图标和alt+F4关闭(调用setvisible(false)!?)。因此,上述监听器中的任何一个都不能使用。只有HierarchyListener才能同时捕获它们,这似乎违背了直觉。

编辑:问题的范围是“为什么会这样”?目的是什么?“。我希望dispose()调用两者!我在API文档中找不到任何线索来解释为什么不这样做。

共有1个答案

班言
2023-03-14

该界面也可以通过顶部/右侧窗口关闭图标Alt+F4关闭(调用setVisible(false)!?)

这是由默认的关闭操作决定的。您可以使用SetDefaultCloseOperation设置它。默认值是hide_on_close,这就是为什么要调用componenthidden。如果将其设置为dispose_on_close,则将获得windowclosed调用。设置为后者将允许您只注册这些事件类型。

不管怎样,隐藏和处置做不同的事情。处理会释放所使用的资源,而隐藏不会。此外,隐藏最后一个窗口不会退出JVM,而处理它会退出。

至于事件调度的技术方面,有很多错综复杂的地方。虽然处理窗口确实调用了它的隐藏方法,但事件的调度是在操作完成后进行的。这意味着EDT可以“事后”分派事件。因为窗口是关闭的,所以它不会分派隐藏事件。

 类似资料:
  • 问题内容: 在对话框上使用setVisible(false)并在以后重用它是否有意义,还是每次调用dispose()并创建新的JDialog更为安全。用setVisible(false)处理内存泄漏怎么办? 编辑:我的问题不是关于退出应用程序。有关以主框架为父框架并在应用程序生命周期中打开和关闭的对话框的更多信息。例如,假设我的应用程序大约有10个对话框,这些对话框每次打开时都会显示不同的数据。我

  • 本文向大家介绍在事件侦听上调用event.preventDefault()的最佳方式是什么?相关面试题,主要包含被问及在事件侦听上调用event.preventDefault()的最佳方式是什么?时的应答技巧和注意事项,需要的朋友参考一下 在事件侦听上调用event.preventDefault()的最佳方式是什么?

  • 本文向大家介绍vuejs中监听窗口关闭和窗口刷新事件的方法,包括了vuejs中监听窗口关闭和窗口刷新事件的方法的使用技巧和注意事项,需要的朋友参考一下 1、使用window.onunload之类的API 2、在生命周期钩子中注册监听事件 在 mounted 钩子中注册事件 在 destroyed 钩子卸载事件 以上这篇vuejs中监听窗口关闭和窗口刷新事件的方法就是小编分享给大家的全部内容了,希望

  • 在了解到/对象在使用后应该调用之后,我开始修改我的游戏以合并这一点。 当我在的重写的中添加时,我添加的组件(类的扩展)在没有呈现的地方仍然能够单击它们,但它们不会被绘制。 我使用普通的和具有相同效果的进行了测试(不过鼠标在上时会呈现)。 所以我的问题是为什么会发生这种情况? 下面是一个SSCCE演示: 取消对类的中的调用的注释后:

  • 问题内容: 当我发现抽象类和接口之间的区别时,这个问题就浮现在脑海中。在这篇文章中,我知道接口很慢,因为它们需要额外的间接访问。但是我没有得到接口而不是抽象类或具体类所需的间接类型,请对此进行澄清。提前致谢 问题答案: 关于性能的神话很多,有些可能在几年前是正确的,而在没有JIT的VM上可能仍然正确。 Android文档(请记住,Android没有JVM,而是Dalvik VM)曾经说过,在接口上

  • 问题内容: 例如,当我们向窗格添加新按钮时,我们需要编写以下代码: 为什么我们需要调用“ getChildren()”?它甚至做什么?我们为什么不能说: 我们将按钮添加到窗格中。我们不会将其添加到其子项中, 问题答案: 简短的答案就是“您必须那样做,因为这就是API的编写方式”。当然,您可能真正要问的是为什么要这样编写API。我认为这实际上是两个(相关的)问题。一种与方法名称有关,以及该方法的作用