繁体   English   中英

Java Swing dispose() 与 setVisible(false)

[英]Java Swing dispose() vs. setVisible(false)

我有一个独立的 Java 应用程序,它从数据库中获取数据并将其显示在JTable 当应用程序启动时,会在JDialog中提示用户输入用户名/密码。 输入正确的凭据后,将显示包含数据的主JFrame 在主JFrame上,我有一个注销按钮,单击该按钮应关闭主JFrame并重新显示登录JDialog 一切正常,除了我发现单击注销按钮时主JFrame并没有消失。 下面是我的代码的一个小型工作示例:

主.java:

import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();
            }
        });
    }
}

MainFrame.java:

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

import javax.swing.JButton;
import javax.swing.JFrame;

public class MainFrame extends JFrame implements ActionListener {
    private JButton button;
    private MyDialog dialog;
    
    public MainFrame() {
        super("this is the JFrame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        dialog = new MyDialog(this);
        button = new JButton("click me to hide this JFrame and display JDialog");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false); // works when changed to dispose();
        dialog.setVisible(true);
    }
}

MyDialog.java:

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

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;


public class MyDialog extends JDialog implements ActionListener {
    private JFrame parentFrame;
    private JButton button;
    
    public MyDialog(JFrame parentFrame) {
        super(parentFrame, "this is the JDialog", true);
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.parentFrame = parentFrame;
        button = new JButton("click me to hide JDialog and show JFrame");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        setVisible(false);
        parentFrame.setVisible(true);
    }
}

MainFrame.java中,如果我将表示setVisible(false)的行更改为dispose() ,那么当我单击按钮时 JFrame 就会消失。 我的问题是,为什么这适用于dispose()而不是setVisible(false) 有没有更好的方法来组织我的代码? 我是 Swing 新手,所以如果这是一个基本问题,我深表歉意。 谢谢你。


编辑于 2011-10-19 10:26 PDT

感谢大家的帮助。 我将JDialog更改为具有 null 父级,现在一切都按我的意愿工作。

查看启动 JDialog 的行:

dialog = new MyDialog(this);

您正在设置与对话框所在的父框架相同的框架。 你看,一个对话框不能单独出现,它必须位于父框架的顶部。

因此,在您的代码中,当您编写时:

setVisible(false); // works when changed to dispose();
dialog.setVisible(true);

在第一行你告诉框架消失,然后你告诉对话框出现,这实际上告诉对话框出现在它的父框架上。 由于父框架是相同的,它看起来对您保持可见。 如果您删除第二行,我相信框架会消失。 但是当你告诉框架丢弃时,它完全消失了,因为你告诉它不仅要失去可见性,还要从记忆中删除它自己。

然后,当您告诉对话框出现时,它会查找其 JFrame(已被释放),重新初始化并打开它。

解决问题的方法是为 JDialog 创建一个单独的新 JFrame。 然后不要使用 dispose ,只需使用 setVisible 命令。

-阿萨夫

我只会以我自己的风格给出正确的代码。 它当然不是唯一的,甚至不是经过验证的最佳解决方案。

主机上的 setVisible(false) 应该调用关闭操作,逻辑上用于主机 EXIT_ON_CLOSE。 如果对话框是主框架的子框架,则应用程序退出。

所以我将模态对话框设为第二个顶部窗口,它有一个 (JFrame)null 作为父窗口。 因此,您有一个带有两个顶部窗口的应用程序。 并且每次都处理模态对话框。 我制作了模式对话框 DO_NOTHING_ON_CLOSE,因为您不希望关闭图标起作用。 因此 actionPerformed 中的 dispose()。 (如果您在任何时候都有父母,您可以使用 getOwner() 而不是将父母复制到字段中。)

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainFrame mainFrame = new MainFrame();
                mainFrame.actionPerformed(null);
            }
        });
    }
}


public class MainFrame extends JFrame implements ActionListener {
    private JButton button;

    public MainFrame() {
        super("this is the JFrame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        button = new JButton("click me to hide this JFrame and display JDialog");
        button.addActionListener(this);
        add(button);
        pack();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        MyDialog dialog = new MyDialog(MainFrame.this);
        dialog.setVisible(true);
        setVisible(false);
    }
}


public class MyDialog extends JDialog implements ActionListener {
    private JButton button;
    private JFrame parentFrame;

    public MyDialog(JFrame parentFrame) {
        super((JFrame)null, "this is the JDialog", false);
        this.parentFrame = parentFrame;
        setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        button = new JButton("click me to hide JDialog and show JFrame");
        button.addActionListener(this);
        add(button);
        pack();
        setVisible(false);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        parentFrame.setVisible(true);
        dispose();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM