允许“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");
当然,这假设具有焦点的组件不消耗有问题的键事件(如第二个按钮消耗 space 或 enter 键
【讨论】:
【参考方案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的主要内容,如果未能解决你的问题,请参考以下文章
除了提交按钮之外,还使用 Enter 键提交 JQuery 表单