[英]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.