如何正确销毁JDialog?

lor*_*oku 5 java swing jdialog

我目前正在开发一个具有JFrame始终存在的主要工作的应用程序.我现在有一个孩子JDialog出现在按钮上.该框架具有JMenu"退出显示器"的项目.当我JDialog按下显示选项的注销时,我的任务是确保这个孩子消失.注销发生时,主显示器通过以下方式设置为不可见:

mainFrame.setVisible(false);
Run Code Online (Sandbox Code Playgroud)

子JDialog具有默认的关闭操作:

DISPONSE_ON_CLOSE
Run Code Online (Sandbox Code Playgroud)

当用户重新登录时,首先要做的是:

mainFrame.setVisible(true); 
Run Code Online (Sandbox Code Playgroud)

发生这种情况时,子对话框会显示备份.看看JDialogJavadoc,这似乎是预期的行为.然而,我还没有找到一种方法来打破父母/孩子的关系或完全摧毁孩子JDialog.它似乎JDialog仍然存在,直到它是GC,这可能不会及时发生.

这是一个模拟我所看到的行为的示例程序:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;

public class WindowTest { 

    public static void createAndShowGUI() {
        JFrame aFrame = new JFrame("LAUNCHER");
        final JFrame aParent = new JFrame("PARENT"); 
        final JDialog aChild = new JDialog(aParent);

        aParent.setSize(200,200);

        final JToggleButton showParentButton = new JToggleButton("HIDE");

        showParentButton.addActionListener(new ActionListener() { 
            public void actionPerformed(ActionEvent e) {
                showParentButton.setText(!showParentButton.isSelected() ? "SHOW": "HIDE");
                aParent.setVisible(!showParentButton.isSelected());
            }
        });

        aChild.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
        aChild.setSize(200,200);
        aParent.addComponentListener(new ComponentAdapter() {

            public void componentHidden(ComponentEvent e) {
                aChild.dispose(); 
                aChild.setVisible(false);
            }
        });
        aFrame.setContentPane(showParentButton);
        aFrame.pack();
        aFrame.setVisible(true);
        aParent.setVisible(true);
        aChild.setVisible(true);
    }
    public static void main(String [] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                createAndShowGUI();
            }
        });
     }
 }
Run Code Online (Sandbox Code Playgroud)

当父母被隐藏时,孩子就会被处理掉.显示父级时,孩子会显示备份.真正奇怪的是,当我按下孩子的X时:当父母被隐藏然后再次显示时,孩子不显示备份.

我看到的唯一区别是单击X也会触发WindowClosing事件.我尝试在上面的componentHidden方法中调度even:

//Added into the constructor
//add to the imports: import java.awt.event.WindowEvent;
aParent.addComponentListener(new ComponentAdapter() {

        public void componentHidden(ComponentEvent e) {
            aChild.dispose(); 
            aChild.setVisible(false); 
            WindowEvent closingEvent = 
                new WindowEvent(aChild, WindowEvent.WINDOW_CLOSING); 
            aChild.dispatchEvent(closingEvent);
        }
    });
Run Code Online (Sandbox Code Playgroud)

这并没有解决问题.

目前看起来我唯一的选择是将孩子的类型改为a JFrame.我只是想知道是否有适当的处理孩子的方法JDialog.

我目前在Redhat Enterprise Linux Server 6.4版上运行Java版本:1.7.0_76 64位.

cam*_*ckr 4

我不知道命名约定会影响编译。

事实并非如此。约定是为了一致性、可读性和可维护性而制定的。编写代码的人并不总是维护代码的人。因此,如果您希望其他人阅读您的代码,尤其是在寻求帮助时,请遵循标准。

您可以从Java 编程风格指南开始

我正在按照我公司的标准从另一个屏幕手动复制代码。

这完全是浪费时间。您的代码没有任何专有内容。同样,当您提出问题时,代码应该采用SSCCE的形式,以便它演示问题。这允许您删除所有不必要的代码。

计算出进口量是很简单的。

正是如此,所以你应该这样做。您希望我们帮助您,那么我们为什么要花时间解决这个问题???让人们尽可能容易地想要帮助你。

添加导入没有帮助。您发布的代码仍然无法编译,所以我不知道它是否准确地反映了您试图描述的问题。

同样,发布代码的目的是为了让我们可以复制/粘贴/编译/测试。在您发布正确的 SSCCE 之前,我不会提供答案。

编辑:

根据我的测试,如果当父窗口变得不可见时,子窗口的可见性被父窗口的可见性改变,那么当子窗口变得可见时,子窗口的可见性也会被父窗口改变。因此,看起来当可见性发生变化时,父窗口保留了子窗口的状态。

所以解决方案是让子窗口在父窗口之前不可见:

showParentButton.setText(!showParentButton.isSelected() ? "SHOW": "HIDE");
aChild.setVisible(false); // add this
aParent.setVisible(!showParentButton.isSelected());
Run Code Online (Sandbox Code Playgroud)

如果您没有对子窗口的引用,那么我想您可以使用该Windows.getOwnedWindows()方法来访问所有子窗口。

另一个编辑:

作为黑客,我创建了一个自定义对话框,一旦被处理就无法再次显示:

    final JDialog aChild = new JDialog(aParent)
    {
        private boolean disposed = false;

        @Override
        public void dispose()
        {
            super.dispose();
            disposed = true;
        }

        @Override
        public void show()
        {
            if (disposed)
                return;

            super.show();
        }
    };
Run Code Online (Sandbox Code Playgroud)