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