JLrame actionlistener активируется перед идентичным / связанным JPanel actionlistener - PullRequest
0 голосов
/ 27 мая 2019

Я новичок в программировании и пробую себя в качелях. У меня есть JFrame, который служит меню по умолчанию, и у меня есть JPanel, который появляется в нем для обработки входов в систему. После успешного входа в систему JPanel должен отправить информацию о входе в систему JFrame, чтобы он знал, кто в данный момент вошел в систему.

Проблема в том, что JButton при нажатии активирует часть отправки (код которой является JFrame), прежде чем JPanel сможет проверить учетные данные. Они оба используют один и тот же список действий, поэтому я не знаю, как контролировать порядок.

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);


    logIn.addActionListener( (e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())){
                if (passField.getText().equals(logInMap.get(nameField.getText()))){
                    //logged in
                    curUsername = nameField.getText();
                }
                else{
                    //wrong password, logged out
                    curUsername = "";

                }
            }
            else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }


        } );

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }
    public void addActionListener(ActionListener al)
    {
        logIn.addActionListener(al);
    }
}

при успешном входе в систему DetailsPanel должен отправить информацию в GUIFrame, а затем войти в GUIFrame.

Вместо этого, когда возникает actionlistener, GUIFrame пытается войти в систему до того, как DetailsPanel проверяет учетные данные и отправляет его в GUIFrame.

Есть ли способ заставить DetailsPanel.addActionListener () прийти ПОСЛЕ logIn.addActionListener ()?

1 Ответ

2 голосов
/ 27 мая 2019

Порядок событий обычно не гарантируется. Наблюдательно, как правило, они запускаются в порядке FILO (сначала в, затем в выход).

Лучшим решением было бы разделить процесс, поэтому все заинтересованные стороны не полагаются на действие кнопки, а вместо этого на компонент, сообщающий им, когда произошла проверка.

«Простое» решение - использовать существующие функции API

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;

    JButton logIn;

    public DetailsPanel() {
        nameField = new JTextField(0);
        passField = new JTextField(0);

        logIn.addActionListener((e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())) {
                if (passField.getText().equals(logInMap.get(nameField.getText()))) {
                    //logged in
                    curUsername = nameField.getText();
                    fireActionPerformed();
                } else {
                    //wrong password, logged out
                    curUsername = "";

                }
            } else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }

        });

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }

    public void addActionListener(ActionListener al) {
        listenerList.add(ActionListener.class, al);
    }

    protected void fireActionPerformed() {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        if (listeners.length == 0) {
            return;
        }
        ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "validated");
        for (ActionListener listener : listeners) {
            listener.actionPerformed(evt);
        }
    }

}

Таким образом, в основном, или это делает, это сохраняет «зарегистрированные» ActionListener s в доступных listenerList. Это API, предоставляемый Swing, доступный для всех компонентов Swing.

При нажатии кнопки и подтверждении личности все зарегистрированные стороны уведомляются с помощью метода fireActionPerformed.

Более полное решение, вероятно, будет включать ваш собственный прослушиватель событий interface, который может включать validationSuccess и validationUnsuccessful и может передавать учетные данные пользователя как часть объекта события

...