按下JFrame中的按钮后打开JPanel

我知道这个问题已被提出,但我找不到解决办法。

我创建了一个用于登录的JFrame ,我希望在按下“Cont Nou”按钮打开一个带有jpanel的新窗口的新窗口,但是不知道如何使初始帧消失并显示带有jpanel的帧。你有什么主意吗? 谢谢! 这就是我现在所做的:

这是带登录的JFrame

 public class LogIn extends JFrame implements ActionListener{ private JLabel labelEmail; private JLabel labelParola; private JTextField textFieldEmail; private JPasswordField textFieldParola; private JButton buttonLogin; private JButton buttonContNou; public LogIn (){ super(); this.setSize(400,200); this.setTitle("Login"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLayout(null); this.setResizable(false); this.setupComponents(); } private void setupComponents(){ labelEmail = new JLabel("Email: "); labelParola = new JLabel("Parola: "); textFieldEmail = new JTextField(); textFieldParola = new JPasswordField(); buttonContNou = new JButton("Cont Nou"); buttonLogin = new JButton("Login"); labelEmail.setBounds(30,30,50,20); labelParola.setBounds(30,70,50,20); textFieldEmail.setBounds(100,30,185,20); textFieldParola.setBounds(100,70,185,20); buttonContNou.setBounds(185,110,100,20); buttonLogin.setBounds(100,110,75,20); buttonLogin.addActionListener(this); buttonContNou.addActionListener(this); this.add(labelEmail); this.add(labelParola); this.add(textFieldEmail); this.add(textFieldParola); this.add(buttonLogin); this.add(buttonContNou); } public static void main(String[] args){ LogIn login= new LogIn(); login.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { if(e.getSource().equals(buttonLogin)){ boolean toateDateleOk =true; textFieldEmail.setBackground(Color.WHITE); textFieldParola.setBackground(Color.WHITE); if(textFieldEmail.getText().length()==0){ textFieldEmail.setBackground(Color.RED); toateDateleOk =false; } if(textFieldParola.getPassword().length==0){ textFieldParola.setBackground(Color.RED); toateDateleOk =false; } if(!toateDateleOk) return ; else System.out.println("Incepe Procesul de logare"); if(e.getSource().equals(buttonContNou)){ //this.dispose(); //dispose(); //new NewAccountPanel().setVisible(true); //new secondTab().show(); } } } } 

让我们开始,你应该尽可能避免直接从顶级容器扩展,比如JFrame 。 这将您绑定到单个使用组件,例如,您无法在另一个窗口(作为大型组件层次结构的一部分)或applet上下文中重用登录控件。 您也没有为类本身添加任何新function。

您还应该限制推送到用户的窗口数量,因为它可能会很快变得混乱。 看看多个JFrame的使用,好/坏练习? 更多细节。

相反,您应该考虑使用MVC( 模型 – 视图 – 控制器 )设计来减少类之间的耦合量以及组件暴露给不需要的/不期望的修改。

合同(查看)

让我们从定义合同开始,这定义了流程中每个元素应该做什么以及传递的信息

View

这定义了应用程序中每个视图的核心function。 每个视图都可以有一个控制器(由C定义),并且应该提供一个JComponent作为基本表示,用于将视图物理地添加到Container

 public interface View { public JComponent getView(); public void setController(C controller); public C getController(); } 

LoginView

这定义了登录视图预期提供的信息,在此示例中,我们提供用户名和密码信息,以及控制器可以通过其告知视图登录尝试失败的方法。 这允许视图重置视图并在需要时显示错误消息

 public interface LoginView extends View { public String getUserName(); public char[] getPassword(); public void loginFailed(String errorMessage); } 

LoginController

这定义了预期会发生登录视图的控制器的预期操作,视图调用它来告诉控制器它应该做什么……

 public interface LoginController { public void performLogin(LoginView view); public void loginCanceled(LoginView view); } 

ApplicationView

我没有举例说明这一点,但您可以想象您需要提供您可能希望为感兴趣的各方提供的详细信息,以便从视图中提取详细信息。

履行

LoginPane

这是基本的LoginView实现……

 public class LoginPane extends JPanel implements LoginView { private JTextField userName; private JPasswordField password; private JButton okButton; private JButton cancelButton; private LoginController controller; public LoginPane() { setLayout(new GridBagLayout()); userName = new JTextField(10); password = new JPasswordField(10); okButton = new JButton("Ok"); cancelButton = new JButton("Cancel"); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(2, 2, 2, 2); gbc.anchor = GridBagConstraints.WEST; add(new JLabel("User name: "), gbc); gbc.gridy++; add(new JLabel("Password: "), gbc); gbc.gridx = 1; gbc.gridy = 0; gbc.gridwidth = 2; add(userName, gbc); gbc.gridy++; add(password, gbc); gbc.gridwidth = 1; gbc.gridy++; add(okButton, gbc); gbc.gridx++; add(cancelButton, gbc); okButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getController().performLogin(LoginPane.this); } }); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getController().loginCanceled(LoginPane.this); } }); } @Override public String getUserName() { return userName.getText(); } @Override public char[] getPassword() { return password.getPassword(); } @Override public void loginFailed(String errorMessage) { JOptionPane.showMessageDialog(this, errorMessage, "Login failed", JOptionPane.ERROR_MESSAGE); } @Override public void setController(LoginController controller) { this.controller = controller; } @Override public JComponent getView() { return this; } @Override public LoginController getController() { return controller; } } 

ApplicationPane

基本应用程序View

 public class ApplicationPane extends JPanel implements View { public ApplicationPane() { setLayout(new GridBagLayout()); add(new JLabel("Welcome to my awesome application")); } @Override public JComponent getView() { return this; } @Override public void setController(Object controller) { // What ever controller you want to use... } @Override public Object getController() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } } 

把它们放在一起……

我们,这是很多信息,但你如何使用它?

 public class CoreApplicationCPane extends JPanel { protected static final String LOGIN_VIEW = "View.login"; protected static final String APPLICATION_VIEW = "View.application"; private LoginView loginView; private ApplicationPane applicationView; private CardLayout cardLayout; public CoreApplicationCPane() { cardLayout = new CardLayout(); setLayout(cardLayout); loginView = new LoginPane(); applicationView = new ApplicationPane(); add(loginView.getView(), LOGIN_VIEW); add(applicationView.getView(), APPLICATION_VIEW); loginView.setController(new LoginController() { @Override public void performLogin(LoginView view) { // Do what ever you need to do... String name = view.getUserName(); char[] password = view.getPassword(); //... cardLayout.show(CoreApplicationCPane.this, APPLICATION_VIEW); } @Override public void loginCanceled(LoginView view) { SwingUtilities.windowForComponent(CoreApplicationCPane.this).dispose(); } }); cardLayout.show(this, LOGIN_VIEW); } } 

这基本上就是所有东西都插在一起的地方。 LoginViewApplicationView被实例化并添加到主视图中,并且插入了控制器。

在此处输入图像描述在此处输入图像描述

看一眼:

  • 在容器中布置组件
  • 如何使用CardLayout

更多细节。

有关更详细的示例,请查看Java和GUI – ActionListeners根据MVC模式属于哪里?

你知道你怎么称呼

 setVisible(true); 

尝试

 setVisible(false); 

您可以使用JFrame的dispose()方法关闭当前的JFrame。
此外,您可以实例化一个新的JFrame并将其设置为可见:

 JFrame newFrame = new JFrame(); newFrame.setVisible(true); this.dispose(); 

更新通知 :虽然我提到了如何做 (因为这被问到),但这并不意味着它是最好的方法。 这被认为是一种不好的做法,因为拥有多个JFrame可能是维护的噩梦,并被认为是用户不友好的。 有关更多信息,请查看此处 。