Нажатие ввода в любом текстовом поле возвращает нажатие кнопки

У меня есть простой jFrame с кнопкой входа в систему, и я пытаюсь запустить свое событие ActionPerformed, нажав клавишу ввода. Я не хочу сначала нажимать «вкладку», чтобы сфокусировать кнопку, но она должна срабатывать всякий раз, когда кто-то нажимает клавишу ввода. Что мне здесь не хватает?

Изменить: если это проще сделать, это может также вызвать событие, когда фокус находится на «PasswordField», поскольку это последнее поле, которое имеет фокус перед нажатием кнопки входа

По запросу. Вот полный код loginGUI:

package unive.facturatie.boundary;

import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import unive.facturatie.control.LoginManager;

/**
 *
 * @author Forza
 */
public class LoginGUI extends javax.swing.JFrame {

JFrame frame = new JFrame();
JRootPane rootPane = frame.getRootPane();
//JButton inloggenButton = new JButton("Login");
//frame.getRootPane().setDefaultButton(inloggenButton);

/**
 * Creates new form LoginGUI
 */
public LoginGUI() {
    frame.getRootPane().setDefaultButton(inloggenButton);
     try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(LoginGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(LoginGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(LoginGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(LoginGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    initComponents();
    this.setLocation(320, 160);
}

/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    inlogLabel = new javax.swing.JLabel();
    gebruikersnaamLabel = new javax.swing.JLabel();
    wachtwoordLabel = new javax.swing.JLabel();
    gebruikersnaamTextField = new javax.swing.JTextField();
    wachtwoordPasswordField = new javax.swing.JPasswordField();
    inloggenButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Facturatie inlogscherm");

    inlogLabel.setFont(new java.awt.Font("Tahoma", 0, 36)); // NOI18N
    inlogLabel.setText("Inloggen");

    gebruikersnaamLabel.setText("Gebruikersnaam:");

    wachtwoordLabel.setText("Wachtwoord:");

    wachtwoordPasswordField.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            wachtwoordPasswordFieldActionPerformed(evt);
        }
    });

    inloggenButton.setText("Inloggen");
    inloggenButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            inloggenButtonActionPerformed(evt);
        }
    });
    inloggenButton.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent evt) {
            inloggenButtonKeyPressed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(inlogLabel)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(inloggenButton)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(gebruikersnaamLabel)
                            .addComponent(wachtwoordLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(gebruikersnaamTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 171, Short.MAX_VALUE)
                            .addComponent(wachtwoordPasswordField)))))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(inlogLabel)
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(gebruikersnaamLabel)
                .addComponent(gebruikersnaamTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(wachtwoordLabel)
                .addComponent(wachtwoordPasswordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(inloggenButton)
            .addContainerGap(25, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>

private void inloggenButtonActionPerformed(java.awt.event.ActionEvent evt) {                                               
    //frame.getRootPane().setDefaultButton(inloggenButton);
    boolean isValid = false;
    String username = gebruikersnaamTextField.getText();
    String password = wachtwoordPasswordField.getText();

    LoginManager loginManager = new LoginManager();
    isValid = loginManager.Inloggen(username, password);
    if (isValid == true)
    {
        new MainGUI().setVisible(true);
        dispose();
    }
    else
    {
        JOptionPane.showMessageDialog(frame, "Gebruikersnaam en/of wachtwoord onjuist!", "Insane error", JOptionPane.ERROR_MESSAGE);
    }
}                                              

private void inloggenButtonKeyPressed(java.awt.event.KeyEvent evt) {                                          
      //frame.getRootPane().setDefaultButton(inloggenButton);
      //inloggenButton.registerKeyboardAction(inloggenButton.getActionForKeyStroke(
      //KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false)),
      //KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false),
      //JButton.WHEN_IN_FOCUSED_WINDOW);

      //inloggenButton.registerKeyboardAction(inloggenButton.getActionForKeyStroke(
      //KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)),
      //KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),
      //JButton.WHEN_IN_FOCUSED_WINDOW);

}                                         

private void wachtwoordPasswordFieldActionPerformed(java.awt.event.ActionEvent evt) {
    // TODO add your handling code here:
}

// Variables declaration - do not modify
private javax.swing.JLabel gebruikersnaamLabel;
private javax.swing.JTextField gebruikersnaamTextField;
private javax.swing.JLabel inlogLabel;
private javax.swing.JButton inloggenButton;
private javax.swing.JLabel wachtwoordLabel;
private javax.swing.JPasswordField wachtwoordPasswordField;
// End of variables declaration
}

person Forza    schedule 11.10.2012    source источник
comment
Я предполагаю, что у вас есть функция keyPressed, потому что вы реализовали KeyEvent. Если все, что вы хотите сделать, это функциональность Enter, вам это не нужно.   -  person davidXYZ    schedule 12.10.2012
comment
Удалить inloggenButton.addKeyListener. Вам это не нужно после добавления прослушивателя действий.   -  person davidXYZ    schedule 12.10.2012
comment
Сделайте setDefaultButton() после initComponents(). Кроме того, где вы настраиваете видимость JFrame? У вас нет основной функции?   -  person davidXYZ    schedule 12.10.2012
comment
Хм, это нередактируемый код из конструктора графического интерфейса, и по какой-то причине он не позволяет мне безопасно удалить его.   -  person Forza    schedule 12.10.2012
comment
Основная функция находится в основном классе. Вы хотите, чтобы я добавил это в ОП?   -  person Forza    schedule 12.10.2012
comment
В построителе графического интерфейса должен быть способ удалить keyEvent так же, как вы добавили его в 1-е место.   -  person davidXYZ    schedule 12.10.2012
comment
Просто убедитесь, что в вашем основном классе вы получаете этот JFrame и делаете его видимым.   -  person davidXYZ    schedule 12.10.2012
comment
Я не знаю как. Все, что я пробую, блокируется Netbeans... Теперь я начинаю понимать, почему все говорят, что мне нужно использовать Eclipse в будущем.   -  person Forza    schedule 12.10.2012
comment
Я сделал indd видимым в основном ;)   -  person Forza    schedule 12.10.2012
comment
Да. Вам лучше пройти учебные пособия по Swing и сделать это вручную. Исходя из опыта, мой первый графический интерфейс был создан с помощью построителя графического интерфейса Netbeans. Я так расстроился, что перенес весь свой код в Notepad++ и сделал все вручную. Размер вашего Swing-кода также резко уменьшится, если вы будете меньше зависеть от конструктора GUI.   -  person davidXYZ    schedule 12.10.2012
comment
Хорошо, я обязательно сделаю это в будущем ;) Но для этого проекта уже слишком поздно. Такие вещи, как вход в систему при нажатии клавиши ввода, являются последними штрихами. Я не знаю, есть ли у вас еще варианты, которые я могу попробовать, но если нет, я предлагаю оставить все как есть. Проект работает и почти готов. Спасибо за вашу настойчивость в помощи мне!   -  person Forza    schedule 12.10.2012
comment
Итак, текущая проблема: графический интерфейс отображается, но функция ввода не работает. Это верно?   -  person davidXYZ    schedule 12.10.2012
comment
Да, это правильно;) с комментированием InloggenButtonKeyPressed функция ввода вообще не работает. Но @MadProgrammer только что опубликовал здесь что-то многообещающее, поэтому я сначала проверю завтра, смогу ли я заставить это работать над моим проектом.   -  person Forza    schedule 12.10.2012


Ответы (3)


Это довольно просто:

JFrame frame = new JFrame();
JButton btn = new JButton("Login");
frame.getRootPane().setDefaultButton(btn);

Вот и все. Вам не нужны KeyListener, registerKeyBoardAction или getKeyStroke... Просто установите ActionEvent для своей кнопки и установите эту кнопку по умолчанию. Нажатие Enter при открытом окне активирует кнопку по умолчанию.

person davidXYZ    schedule 11.10.2012
comment
У меня это уже реализовано... но не работает. Также, если я попробую именно так, я получаю «фрейм пакета не существует» - person Forza; 12.10.2012
comment
Это зависит от того, как вы определили свой JFrame. Вы создали экземпляр или расширили его? Ваш код не показывает, как вы определили свою переменную rootPane. Пожалуйста, опубликуйте более полный код, показывающий определение и развертывание вашего фрейма. - person davidXYZ; 12.10.2012
comment
Я добавил к вопросу создание JFrame и JRootPane. У меня именно так сейчас. Но, может быть, мне нужно сказать вам, что графический интерфейс создается с помощью построителя графического интерфейса Netbeans. Кнопка уже определена, поэтому я не могу сказать JButton btn = new JButton(Login); там - person Forza; 12.10.2012
comment
Почему у вас есть rootPane.setDefaultButton(inloggenButton); в событии keyPressed? - person davidXYZ; 12.10.2012
comment
Кроме того, использование построителя графического интерфейса Netbeans не является хорошей идеей. Лучше научитесь писать от руки. Netbeans не позволяет редактировать автоматически сгенерированный код. - person davidXYZ; 12.10.2012
comment
Я не знаю, куда еще его поставить. Я все еще учусь, так что простите меня, если я глуп, но если я помещу его под JRootPane rootPane = frame.getRootPane(); затем я получаю ожидаемый ‹идентификатор› и ; ожидал.. - person Forza; 12.10.2012
comment
Я знаю;) но у меня есть только ограниченное время для этого проекта (для этапа для страховой компании), и конструктор графического интерфейса кажется здесь самым быстрым вариантом. - person Forza; 12.10.2012
comment
Это потому, что вы не пишете его внутри функции, поэтому он ожидает идентификатор private/public/protected. Попробуйте поместить эту строку в свою основную функцию (до вызова frame.setVisible(true)). - person davidXYZ; 12.10.2012
comment
@ForzaForza, кажется, теперь это превратилось в другой вопрос, который больше касается общего программирования на Java. На исходный вопрос был дан четкий ответ. Если вам нужна помощь с Java, я предлагаю вам взглянуть на учебные пособия (docs.oracle.com/javase/ учебник) или посмотрите другие вопросы на SO. - person Joshua; 12.10.2012
comment
davidXYZ вы дали мне ответ. У меня это еще не работает, но мы можем перенести это обсуждение в чат, если хотите? - person Forza; 12.10.2012
comment
От @davidXYZ Why do you have rootPane.setDefaultButton(inloggenButton); in a keyPressed event? Да, @Forza, просто переместите эту строку из прослушивателя, чтобы она стала третьей строкой, сразу после JRootPane rootPane = frame.getRootPane(); -- закомментируйте всю inloggenButtonKeyPressed - person Stephen P; 12.10.2012
comment
Хорошо, я сделал это, но теперь все событие нажатия клавиши больше не работает. Я переместил frame.getRootPane().setDefaultButton(inloggenButton); в основную функцию, и она принята там. Но каков последний шаг, чтобы заставить это работать? - person Forza; 12.10.2012
comment
@Forza Извините, я не могу общаться в чате на компьютере моей компании. - person davidXYZ; 12.10.2012
comment
@Forza Пожалуйста, опубликуйте полный рабочий код сверху вниз. Мы можем сказать, откуда исходит ошибка, только когда мы видим весь материал. Обновите код в исходном вопросе. - person davidXYZ; 12.10.2012
comment
Хорошо, проверьте OP, я добавил в него весь код LoginGUI. - person Forza; 12.10.2012
comment
@Forza Вот почему важно опубликовать полный рабочий пример, демонстрирующий проблему, с которой вы столкнулись, тогда нам не нужно гадать;) - person MadProgrammer; 12.10.2012

Вот A проблема...

Ваш класс начинается с JFrame

public class LoginGUI extends javax.swing.JFrame {

Но затем вы создаете ДРУГОЙ кадр внутри него...

JFrame frame = new JFrame();
JRootPane rootPane = frame.getRootPane();

Затем в конструкторе вы регистрируете свою кнопку против «фальшивой» ссылки.

public LoginGUI() {
    frame.getRootPane().setDefaultButton(inloggenButton);

ОБНОВЛЕНО

Это прекрасно работает...

public class TestDefaultButton {

    public static void main(String[] args) {
        new TestDefaultButton();
    }

    public TestDefaultButton() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestForm());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class TestForm extends JPanel {

        private JButton myDefault;
        private JTextField myText;

        public TestForm() {
            myDefault = new JButton("By Default");
            myDefault.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(TestForm.this, "By default");
                }
            });

            myText = new JTextField(12);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(8, 8, 8, 8);

            add(myText, gbc);

            gbc.gridy++;
            add(myDefault, gbc);
        }

        @Override
        public void addNotify() {
            super.addNotify();
            SwingUtilities.getRootPane(this).setDefaultButton(myDefault);
        }
    }
}
person MadProgrammer    schedule 11.10.2012
comment
Хм, хорошо, никогда не думал об этом .. Спасибо за пример! Я попробую это завтра ;) - person Forza; 12.10.2012
comment
@Forza: в дополнение к setDefaultButton() здесь здесь показана привязка клавиш. - person trashgod; 12.10.2012
comment
@trashgod использует аналогичное решение для привязки клавиши escape для отмены в диалогах. Приятно знать, что я делаю что-то правильно :P - person MadProgrammer; 12.10.2012
comment
Звучит правильно; Я вижу, что JOptionPane по умолчанию обычно закрывается при отмене. - person trashgod; 12.10.2012

в моем проекте я использую этот простой код с помощью netbeans:

    private void txt_passwordKeyPressed(java.awt.event.KeyEvent evt)
    {                                    
        if (evt.getKeyCode()==KeyEvent.VK_ENTER){
        btn_login.doClick();
        }
    }
person Daniel    schedule 19.11.2013