2012-09-04 12 views
11

In meiner Anwendung verwende ich eine Standardschaltfläche. Ich möchte es reagieren, wenn ENTER Key ist freigegeben. Nicht bei ENTER Schlüssel ist gedrückt.Wie Sie die Java-Standardschaltfläche so einstellen, dass sie mit der ENTER-Taste reagiert _released_?

Ich entfernte die KeyStroke von InputMap der Schaltfläche. Aber es hat nicht für mich funktioniert. Wie soll ich das machen?


import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 

public class ButtonTest { 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       buildFrame(); 
      } 
     }); 
    } 

    private static void buildFrame() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     JButton button = new JButton(new AbstractAction("Button") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("ButtonTest::actionPerformed: CALLED"); 
      } 
     }); 

     JButton button2 = new JButton("Button 2"); 
     InputMap im = button.getInputMap(); 
     im.put(KeyStroke.getKeyStroke("ENTER"), "none"); 
     im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); 

     f.setLayout(new GridBagLayout()); 
     f.add(button); 
     f.add(button2); 
     f.getRootPane().setDefaultButton(button); 

     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 
} 

Dies ist der Beispielcode.

+0

Beitrag ein Teil von Code ... Ich macht einfach Ihre Lösung zu bekommen ... – Vinesh

+0

welchen Unterschied zwischen keyReleased und KeyPressed ist, weil diese JButton muss einmal Zeit KeyEvent von der Tastatur ENTER empfangen, nicht bedeutet, dass Sie repeatly Brennen die gleiche Aktion bis ENTER ... ???, – mKorbel

+0

in Mein Anwendungsdialog wird angezeigt, nachdem ich die Eingabetaste gedrückt habe, die einen "Suchen" -Button auslöst. Wenn ich die ENTER-Taste längere Zeit gedrückt halte, wird der angezeigte Dialog automatisch geschlossen. Da es Standard-Schaltfläche hat. – Hirantha

Antwort

20
JRootPane rootPane = SwingUtilities.getRootPane(/* Your JButton */); 
rootPane.setDefaultButton(/* Your JButton */); 
+2

Ihr Code gibt mir NPE, während dies funktioniert- JRootPane rootPane = SwingUtilities.getRootPane (/ * Your JFrame * /); ' – raghavsood33

+0

@ raghavsood33' SwingUtilities.getRootPane (yourJButton); 'funktioniert ohne NPE nur nach dem Aufruf von etwas mit dem Effekt' yourJFrame.add (yourJButton) ''. Vor dem Hinzufügen der Schaltfläche zu dem Rahmen (oder einem Container, der dem Rahmen hinzugefügt wurde) hat die Schaltfläche eindeutig keinen Stammbereich. – AJNeufeld

2
InputMap im = button.getInputMap(); 
    im.put(KeyStroke.getKeyStroke("ENTER"), "pressed"); 
    im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); 

Der Effekt davon ist, dass die Schaltfläche nur seine actionPerformed führt einmal, wenn die ENTER freigegeben wird (wenn ich richtig verstehe, das ist, was Sie wollen).

EDIT: der Lauf zeigt folgenden Code, der actionPerformed bei nur ausgeführt wird, Release ENTER (obwohl visuell die Taste bereits auf ENTER drücken gedrückt erscheint)

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 

public class ButtonTest { 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       buildFrame(); 
      } 
     }); 
    } 

    private static void buildFrame() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     JButton button = new JButton(new AbstractAction("Button") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("ButtonTest::actionPerformed: CALLED"); 
      } 
     }); 

     InputMap im = button.getInputMap(); 
     im.put(KeyStroke.getKeyStroke("ENTER"), "pressed"); 
     im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); 

     f.add(button); 
     f.getRootPane().setDefaultButton(button); 

     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 
} 
+0

Ich versuchte dies aber es hat nicht funktioniert. – Hirantha

+0

Ich möchte Standard-Taste, um nur auf Enter-Taste Release reagieren. Es sollte nicht auf die Eingabetaste drücken. – Hirantha

+0

Was meinst du mit "reagieren"? Ich habe ein ausführliches Beispiel hinzugefügt, in dem Sie sehen, dass actionPerformed nur bei ENTER ausgeführt wird (obwohl die Schaltfläche bereits gedrückt erscheint, wenn Sie die EINGABETASTE drücken). – lbalazscs

1

Sie die Version von getKeyStroke() verwenden können, mit dem Sie festlegen onKeyRelease zu true, wie in dieser answer

Edit: Sie können die Wiederholungen stoppen, wie in diesen answer.

+0

mit eingebauten boolean in Swing Aktion wie Code von @kleopatra – mKorbel

+0

@mKorbel Danke! Ich habe einen Link zu dieser Antwort hinzugefügt. –

7

Die Schlüssel für die Standardschaltfläche (dh die Schaltfläche, die bei der Eingabe ausgelöst wird, unabhängig davon, welche Komponente focusOwner ist) sind in der Komponente componentInputMap des rootPane gebunden, dh der EingabeMap des Typs WHEN_IN_FOCUSED_WINDOW. Technisch gesehen, ist, dass der Ort zu zwicken:

JComponent content = new JPanel(); 
content.add(new JTextField("some focusable")); 
content.add(new JTextField("something else")); 

JXFrame frame = wrapInFrame(content, "default button on released"); 
Action action = new AbstractAction("do something") { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     LOG.info("clicked"); 
    } 
}; 
JButton button = new JButton(action); 
content.add(button); 
frame.getRootPane().setDefaultButton(button); 
// remove the binding for pressed 
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) 
    .put(KeyStroke.getKeyStroke("ENTER"), "none"); 
// retarget the binding for released 
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) 
    .put(KeyStroke.getKeyStroke("released ENTER"), "press"); 

Vorsicht: Dies aus dem Drücken/Loslassen Verhalten einer Nicht-Standard-Schaltfläche noch anders, weil die rootPane Aktion einfach button.doClick nennen, ohne sie durch die Bewegungen der Bewaffnung zu gehen/Drücken Sie das ButtonModel, um die Aktion indirekt auszulösen.

+0

excellent description +1 – mKorbel