2012-03-05 36 views
14

Tôi có ứng dụng Java netbeans sẽ hiển thị JFrame (lớp StartUpWindow mở rộng JFrame) với một số tùy chọn khi ứng dụng được khởi chạy, sau đó người dùng nhấp vào nút và JFrame nên được đóng lại và một khung mới (lớp MainWindow) sẽ được mở.Ứng dụng Java swing, đóng một cửa sổ và mở khác khi nhấn nút

Vậy làm cách nào để thực hiện điều này một cách chính xác. Tôi rõ ràng thiết lập một trình xử lý nhấn vào nút trong StartupWindow nhưng tôi phải đặt cái gì trong trình xử lý này để tôi có thể đóng StartUpWindow và mở MainWindow? Dường như luồng cũng đi vào quá trình này vì mọi cửa sổ dường như có chuỗi riêng của họ ... hoặc là các vấn đề về luồng tự động được xử lý bởi chính JFrames ...

+3

[Sử dụng nhiều khung hình chữ nhật, thực hành tốt/xấu?] (Http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice/9554657#9554657) và [Xóa vùng chứa cấp cao nhất trên thời gian chạy] (http://stackoverflow.com/questions/6309407/remove-top-level-container-on-runtime) – mKorbel

Trả lời

22

Dưới đây là một ví dụ:

enter image description here

enter image description here

StartupWindow.java

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 


public class StartupWindow extends JFrame implements ActionListener 
{ 
    private JButton btn; 

    public StartupWindow() 
    { 
     super("Simple GUI"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     btn = new JButton("Open the other JFrame!"); 
     btn.addActionListener(this); 
     btn.setActionCommand("Open"); 
     add(btn); 
     pack(); 

    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     String cmd = e.getActionCommand(); 

     if(cmd.equals("Open")) 
     { 
      dispose(); 
      new AnotherJFrame(); 
     } 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable(){ 

      @Override 
      public void run() 
      { 
       new StartupWindow().setVisible(true); 
      } 

     }); 
    } 
} 

AnotherJFrame.java

import javax.swing.JFrame; 
import javax.swing.JLabel; 

public class AnotherJFrame extends JFrame 
{ 
    public AnotherJFrame() 
    { 
     super("Another GUI"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     add(new JLabel("Empty JFrame")); 
     pack(); 
     setVisible(true); 
    } 
} 
+0

Ví dụ tuyệt vời, Được thăng hạng !!! – ron

+0

@ Eng.Fouad cách mở 'StartupWindow' từ' AnotherJFrame', việc tạo đối tượng 'StartupWindow' trong' AnotherJFrame' sẽ không hoạt động –

9

Bạn có thể gọi dispose() trên cửa sổ hiện tại và setVisible(true) trên cửa sổ bạn muốn hiển thị.

+0

Bạn có giữ biến JFrame trong phạm vi lớp không? hoặc bạn sẽ làm cho nó có thể lựa chọn để thu thập rác khi JFrame thứ hai được hiển thị? –

+0

vứt bỏ() sẽ làm cho nó bị thu thập rác miễn là bạn không giữ bất kỳ tham chiếu nào khác. –

9

Đây rõ ràng là trường hợp bạn nên sử dụng CardLayout. Ở đây thay vì mở hai JFrame, những gì bạn có thể làm chỉ đơn giản là thay đổi JPanels bằng cách sử dụng CardLayout.

Và mã chịu trách nhiệm tạo và hiển thị GUI của bạn phải nằm trong SwingUtilities.invokeLater (...); phương thức cho nó là Thread Safe. Để biết thêm thông tin, bạn phải đọc về Concurrency in Swing.

Nhưng nếu bạn muốn gắn bó với cách tiếp cận của mình, dưới đây là Mã mẫu cho Trợ giúp của bạn.

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 

public class TwoFrames 
{ 
    private JFrame frame1, frame2; 
    private ActionListener action; 
    private JButton showButton, hideButton; 

    public void createAndDisplayGUI() 
    { 
     frame1 = new JFrame("FRAME 1"); 
     frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
     frame1.setLocationByPlatform(true); 

     JPanel contentPane1 = new JPanel(); 
     contentPane1.setBackground(Color.BLUE); 

     showButton = new JButton("OPEN FRAME 2"); 
     hideButton = new JButton("HIDE FRAME 2"); 

     action = new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       JButton button = (JButton) ae.getSource(); 

       /* 
       * If this button is clicked, we will create a new JFrame, 
       * and hide the previous one. 
       */ 
       if (button == showButton) 
       { 
        frame2 = new JFrame("FRAME 2"); 
        frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        frame2.setLocationByPlatform(true); 

        JPanel contentPane2 = new JPanel(); 
        contentPane2.setBackground(Color.DARK_GRAY); 

        contentPane2.add(hideButton); 
        frame2.getContentPane().add(contentPane2); 
        frame2.setSize(300, 300); 
        frame2.setVisible(true); 
        frame1.setVisible(false); 
       } 
       /* 
       * Here we will dispose the previous frame, 
       * show the previous JFrame. 
       */ 
       else if (button == hideButton) 
       { 
        frame1.setVisible(true); 
        frame2.setVisible(false); 
        frame2.dispose(); 
       } 
      } 
     }; 

     showButton.addActionListener(action); 
     hideButton.addActionListener(action); 

     contentPane1.add(showButton); 

     frame1.getContentPane().add(contentPane1); 
     frame1.setSize(300, 300); 
     frame1.setVisible(true); 
    } 
    public static void main(String... args) 
    { 
     /* 
     * Here we are Scheduling a JOB for Event Dispatcher 
     * Thread. The code which is responsible for creating 
     * and displaying our GUI or call to the method which 
     * is responsible for creating and displaying your GUI 
     * goes into this SwingUtilities.invokeLater(...) thingy. 
     */ 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new TwoFrames().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

Và kết quả sẽ là:

Frame1Frame2

+1

Vì vậy, chúng ta gặp lại ... một ví dụ tuyệt vời khác. – ron

+1

@ron: [ví dụ] (http://stackoverflow.com/a/9443609/1057230), không cho phép người dùng mở nhiều hơn một 'JFrame', điều này cũng kiểm tra điều kiện, nếu' JFrame' mở, sau đó không mở một cái mới. –

+0

Đáng yêu, cảm ơn rất nhiều! – ron

1
 final File open = new File("PicDic.exe"); 
     if (open.exists() == true) { 
      if (Desktop.isDesktopSupported()) { 
       javax.swing.SwingUtilities.invokeLater(new Runnable() { 

        public void run() { 
         try { 
          Desktop.getDesktop().open(open); 
         } catch (IOException ex) { 
          return; 
         } 
        } 
       }); 

       javax.swing.SwingUtilities.invokeLater(new Runnable() { 

        public void run() { 
         //DocumentEditorView.this.getFrame().dispose(); 
         System.exit(0); 
        } 

       }); 
      } else { 
       JOptionPane.showMessageDialog(this.getFrame(), "Desktop is not support to open editor\n You should try manualy"); 
      } 
     } else { 
      JOptionPane.showMessageDialog(this.getFrame(), "PicDic.exe is not found"); 
     } 

// bạn có thể bắt đầu ứng dụng khác bằng cách sử dụng nó và có thể cắt toàn bộ dự án của bạn trong nhiều ứng dụng. nó sẽ hoạt động rất nhiều

0

Sử dụng this.dispose để cửa sổ hiện tại đóng và next_window.setVisible(true) để hiển thị cửa sổ tiếp theo sau thuộc tính nút ActionPerformed, Ví dụ được hiển thị bên dưới trong ảnh trợ giúp của bạn.

enter image description here

+0

Đảm bảo rằng bạn đã viết 'this.dispose()' trước tiên bạn đang mở 'JFrame' tiếp theo của bạn –

0

Gọi dưới phương pháp ngay sau khi gọi phương thức để mở cửa sổ mới, điều này sẽ đóng cửa sổ hiện hành.

private void close(){ 
    WindowEvent windowEventClosing = new WindowEvent(this, WindowEvent.WINDOW_CLOSING); 
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowEventClosing); 
} 

Cũng trong thuộc tính của JFrame, hãy chắc chắn defaultCloseOperation được thiết lập như đoạt.

Các vấn đề liên quan