JFrame 动作侦听器在相同/链接的 JPanel 动作侦听器之前激活

我是编程新手,正在尝试挥杆。我有一个用作默认菜单的 JFrame,还有一个出现在其中的 JPanel 来处理登录。成功登录后,JPanel 应该将登录信息发送到 JFrame,以便它知道当前登录的用户。


问题是,在 JButton 被单击时,在 JPanel 有机会检查凭据之前激活发送部分(其代码是 JFrame)。他们都使用相同的 actionlistener,所以我不知道如何控制顺序。


public class GUIFrame extends JFrame {

    private DetailsPanel detailsPanel;

    private String curUsername;

    public GUIFrame(String title){

        super(title);

        detailsPanel = new DetailsPanel();

        setLayout(new BorderLayout());

        Container c = getContentPane();

        c.add(detailsPanel, BorderLayout.EAST);



        detailsPanel.addActionListener(new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                if (!(detailsPanel.getCurUsername() == "")){

                    randomToBeImplementedFunctionThatWillLogIn();

                //TODO: 

                // The check here happens BEFORE the detailsPanel processes everything

                // so the first time they create an account it won't log them in

                // and every subsequent time the PREVIOUS login creds will be used. 

            }

        }

    });






public class DetailsPanel extends JPanel {


    private HashMap<String, String> logInMap = new HashMap<String, String>();


    private String curUsername = "";//the current logged in username

    public String getCurUsername(){

        return curUsername;

    }

    JTextField nameField;

    JTextField passField;

    public DetailsPanel(){

        nameField = new JTextField(0);

        passField = new JTextField(0);

         

    }

  

成功登录后,DetailsPanel 应该将信息发送到 GUIFrame,然后 GUIFrame 登录。


相反,当发生 actionlistener 时,GUIFrame 会在 DetailsPanel 开始检查凭据并将其发送到 GUIFrame 之前尝试登录。


有没有办法让 DetailsPanel.addActionListener() 在 logIn.addActionListener() 之后出现?


有只小跳蛙
浏览 92回答 1
1回答

哆啦的时光机

通常不能保证事件的顺序。从观察上看,它们倾向于按 FILO(先进后出)顺序触发。更好的解决方案是将流程解耦,这样任何感兴趣的各方都不会依赖按钮操作,而是依赖组件告诉他们验证何时发生。一个“简单”的解决方案是使用现有的 API 功能public class DetailsPanel extends JPanel {&nbsp; &nbsp; private HashMap<String, String> logInMap = new HashMap<String, String>();&nbsp; &nbsp; private String curUsername = "";//the current logged in username&nbsp; &nbsp; public String getCurUsername() {&nbsp; &nbsp; &nbsp; &nbsp; return curUsername;&nbsp; &nbsp; }&nbsp; &nbsp; JTextField nameField;&nbsp; &nbsp; JTextField passField;&nbsp; &nbsp; JButton logIn;&nbsp; &nbsp; public DetailsPanel() {&nbsp; &nbsp; &nbsp; &nbsp; nameField = new JTextField(0);&nbsp; &nbsp; &nbsp; &nbsp; passField = new JTextField(0);&nbsp; &nbsp; &nbsp; &nbsp; logIn.addActionListener((e) -> {//login attempted&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (logInMap.containsKey(nameField.getText())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (passField.getText().equals(logInMap.get(nameField.getText()))) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //logged in&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curUsername = nameField.getText();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fireActionPerformed();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //wrong password, logged out&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curUsername = "";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logInMap.put(nameField.getText(), passField.getText());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curUsername = nameField.getText();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //create new account&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; GridBagConstraints gCons = new GridBagConstraints();&nbsp; &nbsp; &nbsp; &nbsp; gCons.gridy = 0;&nbsp; &nbsp; &nbsp; &nbsp; gCons.gridx = 0;&nbsp; &nbsp; &nbsp; &nbsp; add(nameField, gCons);&nbsp; &nbsp; &nbsp; &nbsp; gCons.gridy = 1;&nbsp; &nbsp; &nbsp; &nbsp; add(passField, gCons);&nbsp; &nbsp; }&nbsp; &nbsp; public void addActionListener(ActionListener al) {&nbsp; &nbsp; &nbsp; &nbsp; listenerList.add(ActionListener.class, al);&nbsp; &nbsp; }&nbsp; &nbsp; protected void fireActionPerformed() {&nbsp; &nbsp; &nbsp; &nbsp; ActionListener[] listeners = listenerList.getListeners(ActionListener.class);&nbsp; &nbsp; &nbsp; &nbsp; if (listeners.length == 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "validated");&nbsp; &nbsp; &nbsp; &nbsp; for (ActionListener listener : listeners) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listener.actionPerformed(evt);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}所以,基本上,或者这样做,是将“已注册”存储ActionListener在 available 中listenerList。这是 Swing 提供的可用于所有 Swing 组件的 API。单击按钮并验证身份后,将通过该fireActionPerformed方法通知所有注册方。一个更完整的解决方案可能会涉及您自己的事件侦听interface器,它可以包括validationSuccess并且validationUnsuccessful可以将用户凭据作为事件对象的一部分传回
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java