【问题标题】:Open a JPanel after pressing a button in a JFrame [duplicate]按下 JFrame 中的按钮后打开 JPanel [重复]
【发布时间】:2015-02-24 03:07:48
【问题描述】:

我知道有人问过这个问题,但我没有找到解决办法。

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

【问题讨论】:

  • 我忘记输入 Jpanel 的代码
  • 避免使用null 布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正
  • 谢谢,我不知道该选择什么布局,所以我使用了null。我现在试着改一下:)

标签: java swing


【解决方案1】:

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

您还应该限制推送给用户的窗口数量,因为它很快就会变得混乱。更多详情请查看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 被实例化并添加到主视图中,并且控制器被插入。

看看:

了解更多详情。

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

【讨论】:

    【解决方案2】:

    你知道你是怎么称呼的

    setVisible(true);
    

    ?

    试试

    setVisible(false);
    

    【讨论】:

    • 如果open没有在Login实例上调用setVisible(true),它就不会显示登录框...
    • 是的,我知道它设置为真,但这就是为什么我放 dispose();如果按下按钮..以这种方式应该关闭登录窗口..并且应该打开新帐户窗口
    • 我的意思是用setVisible(false)删除原来的窗口,用完后——setVisible(true)显示,setVisible(false)删除。我自己在使用 dispose() 之前执行了 setVisible(false),但很可能没有必要。
    【解决方案3】:

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

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

    更新注意:虽然我提到了怎么做(正如有人问的那样),但这不是 表示这是最好的方法。 这被认为是一种不好的做法,因为拥有多个 JFrame 可能是维护的噩梦,并且被认为对用户不友好。更多信息,请查看here

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2018-10-05
    相关资源
    最近更新 更多