簡體   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