Come posso assegnare Enter come chiave di attivazione di tutti i JButton nella mia applicazione Java?

StackOverflow https://stackoverflow.com/questions/440209

  •  22-07-2019
  •  | 
  •  

Domanda

Sto scrivendo un'applicazione Java Swing usando il look-and-feel Metal. Ogni volta che c'è un JButton nella mia applicazione, l'utente usa il tasto Tab per spostare lo stato attivo sul pulsante e quindi preme il tasto Invio. Non accade nulla! Se preme il tasto Spazio, gli eventi dei pulsanti vengono attivati. Come posso assegnare il tasto Invio per attivare gli stessi eventi del tasto Spazio? Grazie per il tuo aiuto.

È stato utile?

Soluzione

Ho trovato quanto segue:

http://tips4java.wordpress.com/2008 / 10/25 / enter-key-and-tasto /

Dove Rob Camick scrive che quando si utilizza JDK5 e successivamente si aggiunge semplicemente ...

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);

... all'applicazione per risolvere il problema. Questo ha fatto il trucco per me! E non riesco a immaginare niente di più semplice. Tuttavia, quando usi le versioni precedenti di Java dovrai fare qualcosa come Richard e Peter descrivono nelle loro risposte a questa domanda.

Altri suggerimenti

Ecco un esempio completo. Richard era vicino, ma devi anche mappare INVIO all'azione, non solo rilasciato. Per farlo funzionare per TUTTI i pulsanti, ho messo questa mappatura sulla mappa di input predefinita per i pulsanti. Aggiungi le importazioni e dovrebbe essere eseguibile.


public class Main implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Main());
    }

    @Override
    public void run() {
        setupEnterActionForAllButtons();

        JFrame frame = new JFrame("Button test");
        frame.getContentPane().add(createButton(), BorderLayout.NORTH);
        frame.getContentPane().add(createButton(), BorderLayout.SOUTH);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

    private void setupEnterActionForAllButtons() {
        InputMap im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
        Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
        Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));

        im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
        im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
    }

    private JButton createButton() {
        JButton b = new JButton("press enter");
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed");
            }
        });

        return b;
    }
}

In realtà, questo è un problema di aspetto. È (e dovrebbe essere) all'altezza dell'aspetto e della sensibilità di quale tasto attiva il pulsante di messa a fuoco.

Il pulsante " predefinito " la soluzione alternativa funziona dal momento che la L & F; F che stai utilizzando utilizza invio per il pulsante predefinito.

La soluzione alternativa di Peter modifica esplicitamente l'azione di messa a fuoco predefinita di L & amp; F " focus " chiave - che è un po 'più convincente se me lo chiedi.

Aggiungo che non penso che molti utenti vorrebbero fare clic sul pulsante e quindi premere invio (la maggior parte non noterà nemmeno l'indicatore di messa a fuoco): vogliono che l'azione predefinita sia "destra". uno e lavora ovunque premano invio. Questo può essere fatto solo con le mappe di input come suggerisce Richard.

Suggerirei sicuramente di ottenere un'immagine molto chiara di ciò che i tuoi utenti desiderano e si aspettano (preferibilmente con riferimento ad altre app che usano) prima di cambiare qualcosa a livello globale.

Lo fai assegnando una mappa di input / azione per il tasto Invio. Qualcosa di simile al seguente:

// save the command mapping for space
Object spaceMap = button.getInputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true));
// add a mapping from enter to the same command.
button.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),spaceMap); 

Puoi anche impostare il pulsante " predefinito " al pulsante focalizzato più di recente.

L'ho fatto su un'applicazione e tutti i metodi per farlo sono un incubo da mantenere ed eseguire il debug. Il fatto è che questo non è chiaramente ciò che i progettisti di Swing intendevano accadere.

Estensione alle risposte sopra per fare lo stesso con la radio, caselle di controllo. Chiamato prima di creare componenti

void setupEnterAction(String componentName){
    String keyName = componentName + ".focusInputMap";
    InputMap im = (InputMap) UIManager.getDefaults().get(keyName);
    Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
    Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));
    im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
    im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
}

public void setEnterEvent(){
    setupEnterAction("Button");
    setupEnterAction("RadioButton");
    setupEnterAction("CheckBox");
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top