2017-06-04 71 views
0

所以我正在創建一個應用程序。我想讓main初始化一個登錄窗口,我已經完成了。現在我希望登錄窗口在我點擊按鈕時關閉,當它關閉時,一個新窗口(稱爲MainWindow)以不同的按鈕/信息/文本打開。Java Swing - 爲什麼我的第一個窗口不處理/關閉?

所有這些類都是分開的,但在同一個包中。

問題是:當我單擊登錄時主窗口會打開,但登錄窗口不會終止/關閉。

我的主要方法,從我稱之爲登錄窗口:

import javax.swing.*; 

public class Main { 

    // Display Login Window 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      new LoginWindow(); 
      LoginWindow.createAndShowLoginGUI(); 
     }); 
    } 
} 

我的登錄窗口類:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class LoginWindow extends JFrame implements ActionListener { 

    public void prepareLoginGUI() { 

     // Frame with GridBagLayout 
     JFrame loginFrame = new JFrame("Login Window"); 
     loginFrame.setSize(1200, 800); 
     loginFrame.setLayout(new GridBagLayout()); 


     // Button for logging in, with respective GridBagConstraint 
     // setFocusable is set to false to take out the border around the text 
     JButton loginButton = new JButton("Login"); 
     loginButton.addActionListener(this::actionPerformed); 
     loginButton.setActionCommand("Open"); 
     GridBagConstraints lButtonC = new GridBagConstraints(); 
     loginButton.setFocusable(false); 


     // Username text-field and JLabel with respective GridBagConstraints 
     JTextField tfUsername = new JTextField(15); 
     GridBagConstraints tfUserC = new GridBagConstraints(); 
     JLabel txtUser = new JLabel("Username: "); 
     GridBagConstraints txtUserC = new GridBagConstraints(); 


     // Password text-field and JLabel with respective GridBagConstraints 
     JPasswordField tfPassword = new JPasswordField(15); 
     GridBagConstraints tfPassC = new GridBagConstraints(); 
     JLabel txtPassword = new JLabel("Password: "); 
     GridBagConstraints txtPassC = new GridBagConstraints(); 


     // Add all components to the JFrame 
     // Making sure to add the text before the text-fields 
     loginFrame.add(txtUser, txtUserC); 
     loginFrame.add(tfUsername, tfUserC); 
     loginFrame.add(txtPassword, txtPassC); 
     loginFrame.add(tfPassword, tfPassC); 
     loginFrame.add(loginButton, lButtonC); 

     // Show and set close parameters 
     loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     loginFrame.setVisible(true); 
    } 

    // Instructions for when the login button is clicked 
    // Close this window, if button == open, which it does 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     String cmd = e.getActionCommand(); 
     if (cmd.equals("Open")) { 
      this.dispose(); 
      this.setVisible(false); 
      new MainWindow(); 
      MainWindow.createAndShowMainWGUI(); 
     } 
    } 

    // Callable from Main class 
    public static void createAndShowLoginGUI() { 
     LoginWindow loginW = new LoginWindow(); 
     loginW.prepareLoginGUI(); 

    } 

} 

我的主窗口類:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class MainWindow extends JFrame implements ActionListener { 

    public void prepareMainWGUI(){ 
     // Frame with GridBagLayout 
     JFrame loginFrame = new JFrame("Main Window"); 
     loginFrame.setSize(1200, 800); 
     loginFrame.setLayout(new GridBagLayout()); 


     // Username text-field and JLabel with respective GridBagConstraints 
     JLabel txtUser = new JLabel("It worked!"); 
     GridBagConstraints txtUserC = new GridBagConstraints(); 

     loginFrame.add(txtUser, txtUserC); 

     loginFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     loginFrame.setVisible(true); 
    } 

    // Callable from Main class 
    public static void createAndShowMainWGUI() { 
     MainWindow mainWind = new MainWindow(); 
     mainWind.prepareMainWGUI(); 
    } 

} 

如果您使用此代碼,當主窗口打開時,登錄窗口就會在其後面。

+0

請參閱[使用多個JFrames,好/壞實踐?](http://stackoverflow.com/q/9554636/418556) –

+0

@AndrewThompson感謝您的鏈接。我想知道如何改變框架的顯示呢?我應該爲每個顯示器使用面板嗎? – Theo

回答

1

按下按鈕

System.exit(0); 

這時候會終止你的應用程序可以使用。要關閉一個窗口使用(如果你同時打開多個窗口),而不會影響到其他人,

setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) 

然後,打開新的,

new frameName().setvisible(true); 

例子:

JButton closeButton = new JButton("Close"); 

closeButton .addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) 
    { 
     this.dispose();//current(close only this) frame 
     new frameName().setvisible(true); 
    } 
}); 

乘坐看看這question

UPDATE:

在下面行,你有extends JFrame但你因此未使用它。

public class LoginWindow extends JFrame implements ActionListener { 

,而不是你從JFrame

JFrame loginFrame = new JFrame("Login Window"); 

創建新的對象要添加到loginFrame的所有組件。但當actionPerformed試圖this.dispose(),因爲你沒有使用擴展JFrame什麼都不會發生。

解決方案:

聲明你JFrame作爲一個實例變量:

public class LoginWindow implements ActionListener { 
    JFrame loginFrame; 
    public void prepareLoginGUI() { 

然後改變,

this.dispose(); 

要:

loginFrame.dispose(); 

在此this.dispose();呼叫擴展JFrame,對您的JFrame對象(loginForm)沒有影響。

還有最後一件事,請務必刪除extends JFrame。因爲你沒有做任何擴展JFrame。閱讀post about extended JFrame

+0

嗯,很奇怪我已經完成了同樣的事情。但是,當我在prepareMainWGUI方法中執行它而不是覆蓋它時,它可以工作。爲什麼是這樣? – Theo

+0

很少有事情要指出。等一下我會更新答案 – Blasanka

+0

@他們看看** UPDATE **部分 – Blasanka

相關問題