Позволяя клавише «Ввод» нажать кнопку «Отправить», в отличие от использования только MouseClick
Сейчас я изучаю class Swing и все об этом. У меня есть эта игрушечная программа, которую я собирал, которая запрашивает имя, а затем представляет JOptionPane сообщение «Вы ввели (ваше имя)». Кнопка отправки, которую я использую, может быть нажата, но я хотел бы заставить ее работать с кнопкой «Ввод». Я попытался добавить KeyListener, как это рекомендуется в Java-книге, которую я использую (Eventful Java, Bruce Danyluk и Murtagh).
Это мой код:
- Java / Swing: низкопрофильная высота кнопки?
- Обновляйте JLabel несколько раз с результатами многолетней задачи
- Получить выделенные строки в JTable с помощью AbstractTableModel
- Программа не получает доступ к методу paintComponent () расширенного classа JPanel
- Как обновить поле метки каждые 2 секунды в java fx?
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); } }
И это class 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) { } }
- Показать столбец столбца при перетаскивании столбца
- Создайте текстовое поле автозаполнения на Java с выпадающим списком
- как перетаскивать файлы из каталога в java
- Как ограничить JFileChooser каталогом?
- Как правильно использовать собственные средства визуализации для рисования конкретных ячеек в JTable?
- Печать JFrame и его компонентов
- Cytoscape как инструменты в java для построения графика
- Как определить несколько действий JButton из другого classа
Для этого есть простой трюк. После того как вы создали кадр со всеми его кнопками, выполните следующие действия:
frame.getRootPane().setDefaultButton(submitButton);
Для каждого фрейма вы можете установить кнопку по умолчанию, которая будет автоматически прослушивать клавишу Enter (и, возможно, какое-то другое событие, о котором я не знаю). Когда вы нажмете enter в этом фрейме, actionPerformed()
их 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()); } }
UPDATE: Я нашел, что не так с вашим кодом. Вы добавляете ключевой прослушиватель в кнопку «Отправить», а не в «TextField». Измените свой код на это:
SubmitButton listener = new SubmitButton(textBoxToEnterName); textBoxToEnterName.addActionListener(listener); submit.addKeyListener(listener);
Вы можете использовать корневую панель контейнеров верхнего уровня, чтобы установить кнопку по умолчанию, которая позволит ему отвечать на ввод.
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"); } } }
Это, конечно, предполагает, что компонент с фокусом не потребляет ключевое событие, о котором идет речь (например, вторая кнопка, потребляющая пространство или ввод ключей
В classе ActionListener вы можете просто добавить
public void actionPerformed(ActionEvent event) { if (event.getSource()==textField){ textButton.doClick(); } else if (event.getSource()==textButton) { //do something } }
switch(KEYEVENT.getKeyCode()){ case KeyEvent.VK_ENTER: // I was trying to use case 13 from the ascii table. //Krewn Generated method stub... break; }
Без frameworks это работает для меня:
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();
Я знаю, что это не лучший способ сделать это, но щелкните правой кнопкой мыши соответствующую кнопку, события, ключ и ключ. Это простой способ сделать это, но реагирует на любой ключ
Самый простой способ – сделать …
textBoxToEnterName.addActionListener(new ActionListener()
… вы знаете, что делать дальше