java - 按下 JFrame 中的按钮后打开 JPanel

标签 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();
            }   
         }
   }
}

最佳答案

让我们开始吧,您应该尽可能避免直接从顶级容器扩展,例如 JFrame。这将您束缚在单一用途的组件上,例如,您不能在另一个窗口(作为大型组件层次结构的一部分)或小程序上下文中重复使用登录控件。您也没有向类本身添加任何新功能。

您还应该限制向用户推送的窗口数量,因为它很快就会变得困惑。看看The Use of Multiple JFrames, Good/Bad Practice?了解更多详情。

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

契约(Contract)( View )

让我们从定义契约开始,这定义了流程中的每个元素可以做什么和期望做什么以及传递的信息

查看

这定义了应用程序中每个 View 的核心功能。每个 View 都可以有一个 Controller (由 C 定义),并期望提供一个 JComponent 作为基本表示,用于将 View 物理添加到 容器

public interface View<C> {

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

登录 View

这定义了登录 View 期望提供的信息,在这个例子中,我们提供了用户名和密码信息以及 Controller 可以告诉 View 登录尝试失败的方法。这允许 View 重置 View 并在需要时显示错误消息

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

登录 Controller

这定义了登录 View 的 Controller 预期发生的预期操作, View 调用它来告诉 Controller 它应该做某事...

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

应用 View

我没有提供这方面的示例,但您可以想象您需要提供您可能希望提供的详细信息,以便感兴趣的各方从 View 中提取详细信息。

实现

登录面板

这是基本的 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;
    }
    
}

应用面板

基本应用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 被实例化并添加到主视图, Controller 被插入。

enter image description here enter image description here

看看:

了解更多详情。

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

关于java - 按下 JFrame 中的按钮后打开 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27663306/

相关文章:

java - eclipse.ini中的 "XXMaxPermSize"和 "xmx"有什么区别?

java - 我怎样才能知道点击了哪个按钮?

即使信任库中的根证书,java 也会引发 SSLHandshakeException

java - 禁用 JList 单元格选择属性

java - 为什么引用文献会自动更新?

java - WebLogic 上 Jenkins 的 LinkageError

java - 按下回车后的 JTextArea

java - 如何在java中的点击事件中获取按钮名称

java - 如何在运行 java 应用程序时获取当前 Activity 窗口

java - 使用 JOptionPane 图标和 Math.random 呈现随机图片