【问题标题】:Pressing enter on any textfield returns button click在任何文本字段上按回车键返回按钮单击
【发布时间】:2012-10-11 19:34:57
【问题描述】:

我有一个带有登录按钮的简单 jFrame,我试图通过按 enter 键来触发我的 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
}

【问题讨论】:

  • 我假设你有keyPressed 函数,因为你实现了KeyEvent。如果您只想使用 Enter 功能,则不需要。
  • 删除inloggenButton.addKeyListener。添加动作监听器后就不需要了。
  • initComponents() 之后执行setDefaultButton()。另外,您在哪里将 JFrame 设置为可见?你没有main函数?
  • 嗯,这是来自 gui 构建器的不可编辑代码,它不会让我出于某种原因安全删除..
  • 是的。您最好阅读 Swing 教程并手动完成。根据经验,我的第一个 GUI 是使用 Netbeans GUI builder。我很沮丧,把我所有的代码都移到了 Notepad++ 上,然后全部手动完成。当您减少对 GUI builder 的依赖时,Swing 代码的大小也会大幅减少。

标签: java swing jbutton key-bindings keystroke


【解决方案1】:

这很简单:

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

就是这样。您不需要 KeyListenerregisterKeyBoardActiongetKeyStroke... 只需为您的按钮设置一个 ActionEvent 并将该按钮设置为默认值。窗口打开时按 Enter 将激活默认按钮。

【讨论】:

  • 我已经实现了..但不起作用。另外,如果我完全像这样尝试,我会得到“包框架不存在”
  • 这取决于你如何定义你的JFrame。您是创建了一个实例还是扩展了它?您的代码未显示您如何定义变量 rootPane。请发布更完整的代码,显示框架的定义和部署。
  • 为什么rootPane.setDefaultButton(inloggenButton); 出现在keyPressed 事件中?
  • @Forza 现在这似乎变成了一个不同的问题,更多的是关于一般 Java 编程。最初提出的问题已明确回答。如果您需要 Java 方面的帮助,我建议您查看教程 (docs.oracle.com/javase/tutorial) 或查看有关 SO 的其他问题。
  • @Forza 请从上到下发布完整的工作代码。当我们看到整个东西时,我们只能知道错误来自哪里。更新原始问题中的代码。
【解决方案2】:

这是一个问题...

你的课程从JFrame延伸

public class LoginGUI extends javax.swing.JFrame {

但随后您在其中创建另一个框架...

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

然后在 constrcutor 中,针对“假”引用注册按钮

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

【讨论】:

  • 嗯,好吧,从来没有想过这个.. 举个例子,谢谢!我明天试试这个;)
  • @Forza:除了setDefaultButton(),还显示了一个键绑定here
  • @trashgod 使用类似的解决方案将转义键绑定到对话框上的“取消”。很高兴知道我做对了:P
  • 听起来不错;我看到JOptionPane 通常默认在取消时绑定关闭。
【解决方案3】:

在我的项目中,我使用 netbeans 使用这个简单的代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2012-02-09
    • 2018-06-05
    • 2021-05-09
    相关资源
    最近更新 更多