Подтвердить что ты не робот

Разрешить клавише "Enter" нажать кнопку отправки, в отличие от использования только MouseClick

Сейчас я изучаю класс Swing и все об этом. У меня есть эта игрушечная программа, которую я собирал, которая запрашивает имя, а затем представляет JOptionPane сообщение "Вы ввели (ваше имя)". Кнопка отправки, которую я использую, может быть нажата, но я хотел бы заставить ее работать с кнопкой "Enter". Я попытался добавить KeyListener, как это рекомендуется в книге Java, которую я использую (Eventful Java, Bruce Danyluk и Murtagh).

NamePromptenter 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) {

    }
}
4b9b3361

Ответ 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()

... вы знаете, что делать отсюда