【问题标题】:Allowing the "Enter" key to press the submit button, as opposed to only using MouseClick允许“Enter”键按下提交按钮,而不是仅使用 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

标签: java swing keylistener


【解决方案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 的需要。但是你能告诉我如何将密钥(假设它不是“默认”输入,而是其他一些密钥)传递给侦听器类吗?
            猜你喜欢
            • 2019-03-07
            • 2014-04-04
            • 1970-01-01
            • 2012-02-17
            • 2016-10-01
            • 2016-10-22
            • 2021-10-28
            • 2016-04-23
            • 1970-01-01
            相关资源
            最近更新 更多