Java Swing dispose() 与 setVisible(false)
我有一个独立的 Java 应用程序,它从数据库获取数据并将其显示在 JTable
中。当应用程序启动时,系统会在 JDialog
中提示用户输入用户名/密码。输入正确的凭据后,将显示包含数据的主 JFrame
。在主 JFrame
上,我有一个注销按钮,单击该按钮后,应关闭主 JFrame
并重新显示登录 JDialog
。一切都基本正常,除了我发现单击注销按钮时主 JFrame 不会消失。下面是我的代码的一个小工作示例:
Main.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
更改为具有空父级,现在一切都按我想要的方式工作。
I have a standalone Java application that gets data from a database and displays it in a JTable
. When the application starts, the user is prompted for a username/password in a JDialog
. Once the correct credentials are entered, the main JFrame
containing the data is displayed. On the main JFrame
I have a logout button that, when clicked, should close the main JFrame
and redisplay the login JDialog
. Everything is mostly working except I have found that the main JFrame
does not go away when the logout button is clicked. Below is a small working example of my code:
Main.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);
}
}
In MainFrame.java if I change the line that says setVisible(false)
to dispose()
then the JFrame goes away when I click the button. My question is, why does this work with dispose()
and not with setVisible(false)
? Is there a better way for me to organize my code? I am new to Swing so I apologize if this is a basic question. Thank you.
EDITED 2011-10-19 10:26 PDT
Thank you everyone for your help. I changed the JDialog
to have a null parent and now everything works as I wanted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请参阅启动 JDialog 的行:
您正在设置与对话框所在的父框架相同的框架。您会看到,对话框不能单独出现,它必须位于父框架之上。
因此,在代码中,当您编写:
在第一行中告诉框架消失,然后告诉对话框出现,这实际上告诉对话框出现在其父框架上。由于父框架是相同的,因此看起来它对您仍然可见。如果删除第二行,我确信框架会消失。但是,当您告诉框架进行处置时,它会完全消失,因为您告诉它不仅要失去可见性,还要将其自身从内存中删除。
然后,当您告诉对话框出现时,它会查找其 JFrame(已被处理),重新初始化它并打开。
解决问题的方法是为 JDialog 制作一个单独的新 JFrame。然后不要使用 dispose,只使用 setVisible 命令。
-阿萨夫
See the line where you initiate the JDialog:
You're setting the same frame as the parent frame that the dialog sits on. You see, a dialog can't appear on its own, it must sit on top of a parent frame.
So in your code, when you write:
In the first line you tell the frame to disappear, then you tell the dialog to appear, which really tells the dialog to appear on its parent frame. Since the parent frame is the same it looks like it stays visible to you. If you remove the second line, I'm sure the frame would disappear. But when you tell the frame to dispose, it disappears entirely because you told it not just to lose visibility, but also remove itself from memory.
Then when you tell the dialog to appear it looks for its JFrame (which has been disposed), re-initializes it and opens up.
The way to solve your problem is to make a separate new JFrame for the JDialog. Then don't use dispose and just use the setVisible command.
-Asaf
我只会以我自己的风格给出正确的代码。它当然不是单一的,甚至不是经过验证的最佳解决方案。
主框架上的 setVisible(false) 应调用关闭操作,逻辑上主框架 EXIT_ON_CLOSE。如果该对话框是主框架的子级,则应用程序退出。
因此,我将模式对话框设置为第二个顶部窗口,该窗口具有 (JFrame)null 作为父窗口。因此,您的应用程序有两个顶部窗口。并且每次都会处理模式对话框。
我制作了模式对话框 DO_NOTHING_ON_CLOSE,因为您不希望“关闭”图标起作用。
因此,actionPerformed 中的 dispose() 。
(如果您随时有父级,则可以使用 getOwner() 而不是将父级复制到字段。)
I will simply give correct code, in my own style. It certainly is not the single or even proven best solution.
setVisible(false) on the main frame should invoke the close operation, logically for a main frame EXIT_ON_CLOSE. If the dialog is a child of the main frame, then the application exits.
So I made the modal dialog a second top window, which has a (JFrame)null as parent. Hence you have an application with two top windows. And the modal dialogs are every time disposed.
I made the modal dialog DO_NOTHING_ON_CLOSE, as you do not want the Close icon to function.
Hence the dispose() in the actionPerformed.
(If you at any time have a parent, you may use getOwner() instead of copying the parent to a field.)