2012-12-05 11 views
35

Uczę się teraz klasy Swing i wszystkiego na ten temat. Mam ten program zabawkowy, który układałem, który podpowiada nazwę, a następnie przedstawia JOptionPane z komunikatem "Wprowadziłeś (twoje imię)". Przycisk przesyłania, którego używam, można kliknąć tylko, ale chciałbym, aby działał również za pomocą przycisku Enter. Próbowałem dodać KeyListener, jak zaleca się w książce Java używam (Eventful Java, Bruce Danyluk i Murtagh).Po naciśnięciu przycisku "Wyślij" przycisk "Enter", a nie tylko za pomocą MouseClick

NamePrompt enter image description here

To jest mój kod:

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


} 

I to jest klasa 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) { 

    } 
} 

Odpowiedz

88

Istnieje prosty trik do tego. Po skonstruowana ramkę ze wszystkich przycisków it to zrobić:

frame.getRootPane().setDefaultButton(submitButton); 

Dla każdej ramki, można ustawić domyślny przycisk, który automatycznie wysłuchać klawisz Enter (a może jakieś inne wydarzenia nie jestem świadomy) . Po naciśnięciu Enter w tej ramce zostanie wywołana metoda ActionListeners ich metoda actionPerformed().


A problem z kodem miarę widzę jest to, że dialog wyskakuje za każdym razem trafisz na klucz, bo nie umieścić go w IF-ciele. Spróbuj zmienić go na to:

@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: znalazłem to, co jest złego w kodzie. Dodajesz kluczowego odbiornika do przycisku Prześlij zamiast do Pola tekstowego. Zmienić swój kod do tego:

SubmitButton listener = new SubmitButton(textBoxToEnterName); 
textBoxToEnterName.addActionListener(listener); 
submit.addKeyListener(listener); 
+1

To działa! Czy możesz wyjaśnić, dlaczego to działa? Co się stanie, jeśli chcę, aby przycisk Wyślij został naciśnięty klawiszem spacji? (tj. gdyby było więcej niż jeden przycisk). – CodyBugstein

+0

Wystarczająco jasne? Chętnie pomogę :) –

+0

Właściwie, zanim zaimplementowałem twoje rozwiązanie, okno dialogowe nie pojawiło się dla żadnego klawisza (nawet Enter). Co było nie tak? – CodyBugstein

12

Można użyć panelu górnego pojemniki poziomie głównym, aby ustawić domyślny przycisk, który pozwoli odpowiedzieć na to enter.

SwingUtilities.getRootPane(submitButton).setDefaultButton(submitButton); 

To, oczywiście, zakłada dodaniu przycisku do ważnego pojemnika;)

AKTUALIZACJA

Jest to prosty przykład za pomocą JRootPane#setDefaultButton i klawiszy 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"); 
     } 

    } 

} 

Zakłada to oczywiście, że komponent z fokusem nie zużywa kluczowego zdarzenia (jak drugiego przycisku spożywającej przestrzeń lub wprowadzić klucze

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

Podczas gdy ten blok kodu może odpowiedzieć na pytanie, byłoby lepiej, gdybyś mógł podać wyjaśnienie, dlaczego tak się dzieje. – DavidPostill

-2

Najłatwiej byłoby zrobić ...

textBoxToEnterName.addActionListener(new ActionListener() 

... wiesz, co zrobić, stąd

+1

Nie, właściwie nie wiem, co robić. –

1

W klasie ActionListener można po prostu dodać

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

bez ramy tego działa dla mnie:

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

wiem, że to nie jest najlepszy sposób, aby to zrobić, ale kliknij prawym przyciskiem myszy przycisk, zdarzenia, klucz, wpisane klawisze. Jest to prosty sposób na zrobienie tego, ale reaguje na każdy klucz

Powiązane problemy