Разрешить клавише "Enter" нажать кнопку отправки, в отличие от использования только MouseClick
Сейчас я изучаю класс Swing и все об этом. У меня есть эта игрушечная программа, которую я собирал, которая запрашивает имя, а затем представляет JOptionPane сообщение "Вы ввели (ваше имя)".
Кнопка отправки, которую я использую, может быть нажата, но я хотел бы заставить ее работать с кнопкой "Enter". Я попытался добавить KeyListener, как это рекомендуется в книге Java, которую я использую (Eventful Java, Bruce Danyluk и Murtagh).
![NamePrompt]()
![enter image description here]()
Это мой код:
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) {
}
}
Ответы
Ответ 1
Для этого есть простой трюк. После того, как вы создали кадр со всеми его кнопками, выполните следующие действия:
frame.getRootPane().setDefaultButton(submitButton);
Для каждого фрейма вы можете установить кнопку по умолчанию, которая будет автоматически прослушивать клавишу Enter (и, возможно, какое-то другое событие, о котором я не знаю). Когда вы нажмете enter в этом фрейме, будут активированы ActionListeners их метод actionPerformed()
.
И проблема с вашим кодом, насколько я вижу, заключается в том, что ваш диалог появляется каждый раз, когда вы нажимаете клавишу, потому что вы не помещали его в if-тело. Попробуйте изменить его на это:
@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());
}
}
ОБНОВЛЕНИЕ: Я нашел, что не так с вашим кодом. Вы добавляете ключевой прослушиватель в кнопку "Отправить", а не в "TextField". Измените свой код на это:
SubmitButton listener = new SubmitButton(textBoxToEnterName);
textBoxToEnterName.addActionListener(listener);
submit.addKeyListener(listener);
Ответ 2
Вы можете использовать корневую панель контейнеров верхнего уровня, чтобы установить кнопку по умолчанию, которая позволит ему отвечать на ввод.
SwingUtilities.getRootPane(submitButton).setDefaultButton(submitButton);
Это, конечно, предполагает, что вы добавили кнопку в действительный контейнер;)
ОБНОВЛЕНО
Это базовый пример с использованием API JRootPane#setDefaultButton
и ключевых привязок
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
Ответ 3
В классе ActionListener вы можете просто добавить
public void actionPerformed(ActionEvent event) {
if (event.getSource()==textField){
textButton.doClick();
}
else if (event.getSource()==textButton) {
//do something
}
}
Ответ 4
switch(KEYEVENT.getKeyCode()){
case KeyEvent.VK_ENTER:
// I was trying to use case 13 from the ascii table.
//Krewn Generated method stub...
break;
}
Ответ 5
Без рамки это работает для меня:
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();
Ответ 6
Я знаю, что это не лучший способ сделать это, но щелкните правой кнопкой мыши на соответствующей кнопке, событиях, ключах и ключах. Это простой способ сделать это, но реагирует на любой ключ
Ответ 7
Самый простой способ - сделать...
textBoxToEnterName.addActionListener(new ActionListener()
...
вы знаете, что делать отсюда