按下JFrame中的按钮后打开JPanel

时间:2014-12-27 00:26:14

标签: java swing

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

我为登录创建了一个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();
            }   
         }
   }
}

3 个答案:

答案 0 :(得分:9)

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

您还应该限制推送到用户的窗口数量,因为它可能会很快变得混乱。有关详细信息,请查看The Use of Multiple JFrames, Good/Bad Practice?

相反,您应该考虑使用MVC(Model-View-Controller)设计来减少类之间的耦合量以及将组件暴露给无法修改/不合需要的修改。

合同(查看)

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

View

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

public interface View<C> {

    public JComponent getView();
    public void setController(C controller);
    public C getController();

}

LoginView

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

public interface LoginView extends View<LoginController> {

    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被实例化并添加到主视图中,并且插入了控制器。

enter image description here enter image description here

看看:

了解更多详情。

有关更详细的示例,请查看Java and GUI - Where do ActionListeners belong according to MVC pattern?

答案 1 :(得分:0)

你知道你怎么称呼

setVisible(true);

尝试

setVisible(false);

答案 2 :(得分:0)

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

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

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

相关问题