Feuern Sie einen JButton mit der Leertaste oder der Eingabetaste oder einem Mausklick ab

Ich versuche, einen einfachen JFrame mit einer einzigen Schaltfläche zu erstellen, um ein Ereignis auszulösen, wenn eines der folgenden Ereignisse eintritt:

Die Eingabetaste wird gedrückt UND der JButton hat den FokusDie Leertaste wird gedrückt UND der JButton hat den FokusDer JButton wird angeklickt.

Es scheint, dass die Eingabetaste und die Leertaste zusammen mit dem standardmäßigen Mausklick mit addActionListener auf dem JButton "kostenlos" sind. Das Problem ist, ich habe gelesen, dass die Tastenbelegung vom verwendeten Look and Feel abhängt.

Ich habe versucht, ein universelles Verhalten in LaF zu erreichen, indem ich der JButton-Aktionskarte die Eingabetaste und die Leertaste hinzufügte. Außerdem habe ich einen zufälligen Schlüssel ("m") hinzugefügt, um sicherzustellen, dass die ActionMap die Arbeit ausführt (es war), aber jetzt die Maus Klick ist verloren. Die einzige Möglichkeit, alle Tasten und Mausklicks abzurufen, ist die Verwendung von action map und addActionListener.

Gibt es eine Möglichkeit, diese Tasten- und Mausbindungen für alle LaFs konsistent zu verwenden, ohne zu versuchen, alle möglichen LaFs zu erkennen, die möglicherweise auftreten? Kann ich einen einzelnen Aktionslistener registrieren, der bei Tastatur- und Mausereignissen ausgelöst wird?

Meine bevorzugte Lösung wäre, der JButton-Aktionszuordnung einen Mausklick hinzuzufügen und zu ermitteln, welche Taste oder welcher Mausklick innerhalb der Aktion stattgefunden hat.

Ich lerne immer noch die Seile hier, also ist dies wahrscheinlich nicht die beste oder effizienteste Art, Dinge zu tun. Ich bin sicher, es ist überarbeitet. Dies ist eine Art Trainingsübung, bei der ich mit allem experimentiere, was ich in die Hände bekommen kann. Alle Kommentare zum Kodierungsstil sind willkommen!

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

public class Example extends JFrame {

// ============================
private class BtnListener extends AbstractAction {
    private static final long serialVersionUID = 1L;

    public void actionPerformed(ActionEvent ae) {
        System.out.println("\nclick button listener triggered");
        System.out.println(ae.getSource().getClass().toString());
    }
} // class BtnListener

private static final int NO_MODIFIER = 0;
private static final boolean ON_KEY_PRESS = false;
private static final KeyStroke ENTER_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_ENTER, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke M_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_M, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke SPACEBAR_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_SPACE, NO_MODIFIER, ON_KEY_PRESS);
private JButton btnButton;
private final AbstractAction btnListener = new BtnListener();
private JPanel buttonPanel;
private JFrame frmMain;

public static void main(String[] args) {
    Example ex = new Example();
    ex.displayFrame();
}

Action btnActionListener = new AbstractAction() {
    private static final long serialVersionUID = 1L;

    public void actionPerformed(ActionEvent e) {
        System.out.println("\nkey button action triggerred");
        System.out.println(e.getSource().getClass().toString());
        if (e.getSource() instanceof JButton) {
            System.out.println("button");
        } else {
            System.out.println("Something else");
        }
    }
};

public Example() {
    initialize();
}

public void displayFrame() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Throwable e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frmMain.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

private void initialize() {

    frmMain = new JFrame();
    btnButton = new JButton("Abutton");

    // Comment this out, you lose the mouse click
    btnButton.addActionListener(btnListener);

    // Comment out ActionMaps, but keep addActionListner (above), and
            // only lose M_PRESSED
    InputMap buttonFocusedMap = btnButton
            .getInputMap(JComponent.WHEN_FOCUSED);

    buttonFocusedMap.put(ENTER_PRESSED, "blah");
    btnButton.getActionMap().put("blah", btnActionListener);

    buttonFocusedMap.put(SPACEBAR_PRESSED, "blort");
    btnButton.getActionMap().put("blort", btnActionListener);

    buttonFocusedMap.put(M_PRESSED, "gaaak");
    btnButton.getActionMap().put("gaaak", btnActionListener);

    // Is there a way to add a mouse click to the ActionMap?

    buttonPanel = new JPanel();
    buttonPanel.add(btnButton);

    frmMain.getContentPane().add(buttonPanel);
    frmMain.setBounds(100, 100, 500, 432);
    frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage