2011-10-18 36 views
8

Tôi có một ứng dụng Java độc lập lấy dữ liệu từ một cơ sở dữ liệu và hiển thị nó trong một JTable. Khi ứng dụng bắt đầu, người dùng được nhắc nhập tên người dùng/mật khẩu trong JDialog. Khi các thông tin đăng nhập chính xác được nhập, JFrame chính chứa dữ liệu được hiển thị. Trên JFrame chính tôi có một nút đăng xuất, khi được nhấp, nên đóng JFrame chính và hiển thị lại JDialog đăng nhập. Tất cả mọi thứ chủ yếu là làm việc ngoại trừ tôi đã thấy rằng JFrame chính không biến mất khi nút đăng xuất được nhấp. Dưới đây là một ví dụ nhỏ làm việc của mã của tôi:Java Swing vứt bỏ() so với setVisible (false)

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); 
    } 
} 

Trong MainFrame.java nếu tôi thay đổi dòng ghi setVisible(false) thành dispose() thì JFrame sẽ biến mất khi tôi nhấp vào nút. Câu hỏi của tôi là, tại sao điều này làm việc với dispose() và không phải với setVisible(false)? Có cách nào tốt hơn để tôi tổ chức mã của tôi không? Tôi mới đến Swing nên tôi xin lỗi nếu đây là một câu hỏi cơ bản. Cảm ơn bạn.


EDITED 2011-10-19 10:26 PDT

Cảm ơn mọi người giúp đỡ của bạn. Tôi thay đổi JDialog để có một phụ huynh null và bây giờ tất cả mọi thứ hoạt động như tôi muốn.

+0

Để được trợ giúp tốt hơn sớm hơn, gửi một [SSCCE] (http: // pscode. org/sscce.html). –

Trả lời

6

Xem dòng mà bạn tiến hành JDialog:

dialog = new MyDialog(this); 

Bạn đang đặt cùng một khung như khung chính mà hộp thoại đặt trên đó. Bạn thấy đấy, một hộp thoại không thể tự xuất hiện, nó phải nằm ở trên cùng của một khung chính.

Vì vậy, trong mã của bạn, khi bạn viết:

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

Trong dòng đầu tiên bạn nói với khung để biến mất, sau đó bạn nói với hộp thoại xuất hiện, mà thực sự nói với hộp thoại xuất hiện trên khung mẹ . Vì khung cha mẹ giống nhau nên có vẻ như nó vẫn hiển thị cho bạn. Nếu bạn loại bỏ dòng thứ hai, tôi chắc chắn khung sẽ biến mất. Nhưng khi bạn nói với khung để xử lý, nó biến mất hoàn toàn bởi vì bạn đã nói với nó không chỉ để mất khả năng hiển thị, nhưng cũng loại bỏ chính nó khỏi bộ nhớ.

Sau đó, khi bạn yêu cầu hộp thoại xuất hiện, nó sẽ tìm JFrame của nó (đã được xử lý), khởi tạo lại nó và mở ra.

Cách để giải quyết vấn đề của bạn là tạo một JFrame mới riêng biệt cho JDialog. Sau đó, không sử dụng vứt bỏ và chỉ sử dụng lệnh setVisible.

-Asaf

+1

Nó chỉ có thể là đủ để không làm cho khung nó mở lại khung mẹ của nó. Vì vậy, thực hiện cuộc gọi siêu trong 'MyDialog()' go: 'super (null," đây là JDialog ", false);'. Nếu khung chính bị ẩn, nó sẽ không nhận được đầu vào có ý nghĩa, vì vậy không có lý do gì để thực hiện phương thức hộp thoại. – millimoose

+0

@Inerdia Bạn đúng, đó cũng là một lựa chọn. Tôi quên rằng boolean có cho phương thức. Ngoài ra, tôi khá chắc chắn rằng phương thức boolean đã không được chấp nhận và phương thức ModalityType hiện được ưu tiên. – Asaf

+0

Không thực sự bị phản đối, ít nhất là không chính thức. Nó được xác định giá trị boolean tương ứng với kiểu phương thức nào, vì vậy nó có lẽ chỉ là một câu hỏi về kiểu mà bạn thích. – millimoose

0

Tôi chỉ cần cung cấp mã chính xác theo phong cách riêng của mình. Nó chắc chắn không phải là giải pháp tốt nhất hoặc thậm chí đã được chứng minh.

setVisible (false) trên khung chính sẽ gọi hoạt động gần, hợp lý cho khung chính EXIT_ON_CLOSE. Nếu hộp thoại là con của khung chính, thì ứng dụng sẽ thoát.

Vì vậy, tôi đã thực hiện hộp thoại phương thức một cửa sổ trên cùng thứ hai, có một (JFrame) null làm cha mẹ. Do đó bạn có một ứng dụng với hai cửa sổ trên cùng. Và các hộp thoại phương thức là mỗi lần xử lý. Tôi đã thực hiện hộp thoại phương thức DO_NOTHING_ON_CLOSE, vì bạn không muốn biểu tượng Đóng hoạt động. Do đó việc vứt bỏ() trong actionPerformed. (Nếu bạn bất cứ lúc nào có cha mẹ, bạn có thể sử dụng getOwner() thay vì sao chép các phụ huynh đến một lĩnh vực.)

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(); 
    } 
} 
+1

Tôi không nghĩ setVisible gọi hoạt động đóng. Nó chỉ ẩn khung/hộp thoại ... – Bogdan