2012-12-05 201 views
35

我現在正在學習Swing類和它的一切。我有這個玩具程序,我一直在提示一個名字,然後給出一個消息「你輸入了(你的名字)」的JOptionPane。 我使用的提交按鈕只能被點擊,但我想讓它與Enter按鈕一起工作。我嘗試添加一個KeyListener,正如我正在使用的Java書(Eventful Java,Bruce Danyluk和Murtagh)中推薦的那樣。允許「Enter」鍵按下提交按鈕,而不是僅使用MouseClick

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

    } 
} 

回答

88

沒有爲這個簡單的一招。你所有的按鈕來構建的框架之後:

frame.getRootPane().setDefaultButton(submitButton); 

對於每一幀,你可以設置一個默認的按鈕,將自動聽Enter鍵(也許其他一些事件的我不知道的) 。當你在該框中輸入時,ActionListeners的方法將被調用。


而且據我看到你的代碼的問題是,你的對話框每次命中關鍵時間彈出,因爲你沒有把它放在如果體。嘗試將其更改爲這樣:

@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); 
+1

它的工作原理!你能解釋爲什麼這個工作嗎?另外,如果我想使用空格鍵按下「提交」按鈕,該怎麼辦? (即如果有多個按鈕) – CodyBugstein

+0

夠清楚嗎?很高興幫助:) –

+0

其實,在我實現你的解決方案之前,對話框並沒有彈出任何鍵(甚至是Enter)。什麼問題? – CodyBugstein

12

您可以使用頂級容器根目錄窗格來設置默認按鈕,這將允許它響應輸入。

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"); 
     } 

    } 

} 

這當然,假定具有焦點的組件不消耗有問題的關鍵事件(像第二個按鈕消耗空間進入

0
switch(KEYEVENT.getKeyCode()){ 
     case KeyEvent.VK_ENTER: 
      // I was trying to use case 13 from the ascii table. 
      //Krewn Generated method stub... 
      break; 
} 
+2

雖然這個代碼塊可能會回答這個問題,但如果您可以提供一些解釋爲什麼它會這樣做,這將是一個更好的答案。 – DavidPostill

-2

會做的最簡單的方法...

textBoxToEnterName.addActionListener(new ActionListener() 

... 你知道該怎麼做,從這裏

+1

不,我其實不知道該怎麼做。 –

1

在ActionListener的類,你可以簡單地添加

public void actionPerformed(ActionEvent event) { 
    if (event.getSource()==textField){ 
     textButton.doClick(); 
    } 
    else if (event.getSource()==textButton) { 
     //do something 
    } 
} 
0

沒有這個框架爲我工作:

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(); 
0

我知道這是不是最好的方法來做到這一點,但右鍵點擊問題按鈕,事件,鍵,鍵入類型。這是一個簡單的方法來做到這一點,但對任何鍵都有反應