允许“Enter”键按下提交按钮,而不是仅使用 MouseClick

Posted

技术标签:

【中文标题】允许“Enter”键按下提交按钮,而不是仅使用 MouseClick【英文标题】:Allowing the "Enter" key to press the submit button, as opposed to only using MouseClick 【发布时间】:2012-11-23 18:42:09 【问题描述】:

我现在正在学习 Swing 课程以及有关它的一切。我有一个我一直在整理的玩具程序,它会提示输入名称,然后显示一个带有消息“您已输入(您的姓名)”的 JOptionPane。 我使用的提交按钮只能单击,但我也想让它与 Enter 按钮一起使用。我尝试添加一个 KeyListener,正如我正在使用的 Java 书籍(Eventful Java、Bruce Danyluk 和 Murtagh)中所推荐的那样。

这是我的代码:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class NamePrompt extends JFrame


    private static final long serialVersionUID = 1L;

    String name;

    public NamePrompt()

        setLayout(new BorderLayout());

        JLabel enterYourName = new JLabel("Enter Your Name Here:");
        JTextField textBoxToEnterName = new JTextField(21);
        JPanel panelTop = new JPanel();
        panelTop.add(enterYourName);
        panelTop.add(textBoxToEnterName);

        JButton submit = new JButton("Submit");
        submit.addActionListener(new SubmitButton(textBoxToEnterName));
        submit.addKeyListener(new SubmitButton(textBoxToEnterName));
        JPanel panelBottom = new JPanel();
        panelBottom.add(submit);

        //Add panelTop to JFrame
        add(panelTop, BorderLayout.NORTH);
        add(panelBottom, BorderLayout.SOUTH);

        //JFrame set-up
        setTitle("Name Prompt Program");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);


    



    public static void main(String[] args) 
        NamePrompt promptForName = new NamePrompt();
        promptForName.setVisible(true); 
    



这是actionListener,keyListener类:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


public class SubmitButton implements ActionListener, KeyListener 

    JTextField nameInput;


    public SubmitButton(JTextField textfield)
        nameInput = textfield;
    

    @Override
    public void actionPerformed(ActionEvent submitClicked) 

        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());
    

    @Override
    public void keyPressed(KeyEvent e) 
        if (e.getKeyCode()==KeyEvent.VK_ENTER)
            System.out.println("Hello");
        
        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());

    

    @Override
    public void keyReleased(KeyEvent arg0) 
        // TODO Auto-generated method stub

    

    @Override
    public void keyTyped(KeyEvent arg0) 

    

【问题讨论】:

下次请发MCVE,以便我们轻松缩小范围。 @Marvin 这是六年前的回答 哦。没看到时间戳:P 【参考方案1】:
textField_in = new JTextField();
textField_in.addKeyListener(new KeyAdapter() 

    @Override
    public void keyPressed(KeyEvent arg0) 
        System.out.println(arg0.getExtendedKeyCode());
        if (arg0.getKeyCode()==10) 
            String name = textField_in.getText();
            textField_out.setText(name);
        

    

);
textField_in.setBounds(173, 40, 86, 20);
frame.getContentPane().add(textField_in);
textField_in.setColumns(10);

【讨论】:

【参考方案2】:

我知道这不是最好的方法,但是右键单击有问题的按钮、事件、键、键入的键。这是一种简单的方法,但对任何键都有反应

【讨论】:

【参考方案3】:

没有框架,这对我有用:

JTextField tf = new JTextField(20);
tf.addKeyListener(new KeyAdapter() 

  public void keyPressed(KeyEvent e) 
    if (e.getKeyCode()==KeyEvent.VK_ENTER)
       SwingUtilities.getWindowAncestor(e.getComponent()).dispose();
    
  
);
String[] options = "Ok", "Cancel";
int result = JOptionPane.showOptionDialog(
    null, tf, "Enter your message", 
    JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.QUESTION_MESSAGE,
    null,
    options,0);

message = tf.getText();

【讨论】:

【参考方案4】:

在 ActionListener 类中你可以简单地添加

public void actionPerformed(ActionEvent event) 
    if (event.getSource()==textField)
        textButton.doClick();
    
    else if (event.getSource()==textButton) 
        //do something
    

【讨论】:

【参考方案5】:
 switch(KEYEVENT.getKeyCode())
      case KeyEvent.VK_ENTER:
           // I was trying to use case 13 from the ascii table.
           //Krewn Generated method stub... 
           break;
 

【讨论】:

虽然这个代码块可能会回答这个问题,但如果你能提供一些解释为什么会这样,那将是一个更好的答案。【参考方案6】:

您可以使用***容器根窗格设置默认按钮,这将允许它响应输入。

SwingUtilities.getRootPane(submitButton).setDefaultButton(submitButton);

当然,这假设您已将按钮添加到有效容器中;)

更新

这是一个使用 JRootPane#setDefaultButton 和键绑定 API 的基本示例

public class DefaultButton 

    public static void main(String[] args) 
        new DefaultButton();
    

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

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            

        );
    

    public class TestPane extends JPanel 

        private JButton button;
        private JLabel label;
        private int count;

        public TestPane() 

            label = new JLabel("Press the button");
            button = new JButton("Press me");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridy = 0;
            add(label, gbc);
            gbc.gridy++;
            add(button, gbc);
            gbc.gridy++;
            add(new JButton("No Action Here"), gbc);

            button.addActionListener(new ActionListener() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    doButtonPressed(e);
                

            );

            InputMap im = button.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            ActionMap am = button.getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
            am.put("spaced", new AbstractAction() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    doButtonPressed(e);
                

            );

        

        @Override
        public void addNotify() 
            super.addNotify();
            SwingUtilities.getRootPane(button).setDefaultButton(button);
        

        protected void doButtonPressed(ActionEvent evt) 
            count++;
            label.setText("Pressed " + count + " times");
        

    


当然,这假设具有焦点的组件不消耗有问题的键事件(如第二个按钮消耗 spaceenter

【讨论】:

【参考方案7】:

有一个简单的技巧。在您使用所有按钮构建框架后,请执行以下操作:

frame.getRootPane().setDefaultButton(submitButton);

对于每一帧,您可以设置一个默认按钮,该按钮将自动侦听 Enter 键(可能还有其他一些我不知道的事件)。当您在该帧中按 Enter 键时,将调用 ActionListener 的 actionPerformed() 方法。


据我所知,您的代码的问题是每次您按下一个键时都会弹出对话框,因为您没有将它放在 if-body 中。尝试将其更改为:

@Override
public void keyPressed(KeyEvent e) 
    if (e.getKeyCode()==KeyEvent.VK_ENTER)
        System.out.println("Hello");

        JOptionPane.showMessageDialog(null , "You've Submitted the name " + nameInput.getText());
    



更新:我发现您的代码有什么问题。您将关键侦听器添加到提交按钮而不是文本字段。将您的代码更改为:

SubmitButton listener = new SubmitButton(textBoxToEnterName);
textBoxToEnterName.addActionListener(listener);
submit.addKeyListener(listener);

【讨论】:

有效!你能解释一下为什么会这样吗?另外,如果我想用空格键按下提交按钮怎么办? (即如果有多个按钮) 够清楚吗?很高兴帮助:) 实际上,在我实施您的解决方案之前,对话框没有弹出任何键(甚至 Enter)。出了什么问题? 另外,当我按回车时它应该输出“Hello”,但它不是。 好的,我知道发生了什么...'this.getRootPane().setDefaultButton(submit);'消除了对 KeyListener 的需要。但是你能告诉我如何将密钥(假设它不是“默认”输入,而是其他一些密钥)传递给侦听器类吗?

以上是关于允许“Enter”键按下提交按钮,而不是仅使用 MouseClick的主要内容,如果未能解决你的问题,请参考以下文章

在 HTML 表单提交上制作 Enter 键而不是激活按钮

除了提交按钮之外,还使用 ​​Enter 键提交 JQuery 表单

Jquery改变输入键按下制表键

用js怎么写一个回车键盘事件

如何在文本框中获取Enter键以触发函数而不是第一个/默认按钮

检测蓝牙键盘上的 Tab 键按下