PDA

Visualizza la versione completa : [JAVA] KeyListeners e combinazioni di tasti


AlexMfM
27-11-2001, 12:44
Salve salvino gente del forum.
Volevo aggiungere ad un programma la possibilita' di compiere azioni tramite le consuete combinazioni di tasti tipo 'Ctrl-N', 'Ctrl-S' e cosi' via.
Dato che non avevo mai spippolato con i KeyListeners ho preso manuale e documentazioni e ho provato a vedere che succede.
Mi torna la pressione di un tasto soltanto, ma le combinazioni di tasti non ne vogliono sapere.
Ad esempio dentro il metodo keyPressed (lo metto qui perche' le combinazioni di tasti non generano eventi gestibili da keyTyped)
ho fatto una cosa del genere. Chiamata 'tasto' la variabile che mi cattura il carattere premuto...

if((tasto=='n')&&(KeyEvent.isControlDown))
{
//codice
}

non funziona, e nemmeno se uso le maschere dei caratteri, prendendo il loro valore intero da KeyEvent.CONTROL_MASK ecc.
(mi pare che il nome delle maschere sia giusto, ma non e' quello il probl. e' solo che ora non me le ricordo e non ho a portata di mano documentazione)

Qualcuno mi dice quella cosa tanto ovvia e che fa funzionare il tutto ma che io non vedo con queste due fette di prosciutto davanti agli occhi?

P.S.
'Rifiuto' cordialmente le risposte con i .setMnemonics() non perche' non vadano, anzi, li ho gia' usati, ma mi serviva qualcosa per arrivare direttamente alla funzione contenuta in alcuni sottomenu senza aprirne altri... e soprattutto usando le combinazioni di tasti con 'Ctrl'!

fabio milazzo
01-06-2002, 17:22
Probabilmente è un problema di focus.
Per installare un sensore di eventi Tasto è necessario che
la classe implementi l'interfaccia keyListener;
quindi sul componente, che deve compiere una determinata azione
in seguito alla pressione di determinati tasti, bisogna
chiamare il metodo addKeyListener. Tutto funzione, però se questo
componente ha il focus. In alcuni casi questo procedimento
funziona ma in altri no.
Per esempio se hai un pannello con tre tasti, ognuno dei quali
determina il colore del pannello, dovrai procedere in questo modo:

crea un oggetto Action che imposta il colore, uno per ogni tasto.

per il pannello devi creare degli oggetti KeyStroke che permettono
di incapsulare la pressione di determinati tasti.

poi devi creare un oggetto InputMap, attraverso
getInputMap(JComponent.COSTANTE), che permette di mappare
gli oggetti KeyStroke su oggetti arbitrari.
(ci sono tre modi differenti di mappare le pressioni di tasti)

crea anche un oggetto ActionMap che invece associa questi oggetti
arbitrari sugli oggetti Action.

L'oggetto InputMap non associa direttamente gli Oggetti KeyStroke
su oggetti Action perchè così è più facile condividere le stesse
azioni tra pressioni di tasti che provengono da mappe di input
diverse.

Tutto questo sembra un po' astratto, per questo ti faccio un esempio:

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

public class ActionTest
{
public static void main(String args[])
{
ActionFrame frame = new ActionFrame();
frame.show();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
}
}

class ActionFrame extends JFrame
{
public ActionFrame()
{
setTitle("ActionFrame");
setSize(WIDTH, HEIGHT);
ActionPanel panel = new ActionPanel();
Container contentPane = getContentPane();
contentPane.add(panel);
}
public static final int WIDTH = 400,
HEIGHT = 300;
}

class ActionPanel extends JPanel
{
public ActionPanel()
{
Action yellowAction = new ColorAction
("yellow", new ImageIcon("yellow-ball.gif"), Color.yellow);
Action redAction = new ColorAction
("red", new ImageIcon("red-ball.gif"), Color.red);
Action blueAction = new ColorAction
("blue", new ImageIcon("blue-ball.gif"), Color.blue);

JButton yellowButton = new JButton(yellowAction);
JButton redButton = new JButton(redAction);
JButton blueButton = new JButton(blueAction);

add(yellowButton);
add(redButton);
add(blueButton);

InputMap imap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_CO MPONENT);
//associa i tasti ai nomi
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "pannel.yellow");
imap.put(KeyStroke.getKeyStroke("ctrl R"), "pannel.red");
imap.put(KeyStroke.getKeyStroke("ctrl B"), "pannel.blue");
//assoica i nomi a azioni
ActionMap amap = getActionMap();
amap.put("pannel.yellow", yellowAction);
amap.put("pannel.red", redAction);
amap.put("pannel.blue", blueAction);
}

private class ColorAction extends AbstractAction
{
public ColorAction(String name, ImageIcon icon, Color backGroundColor)
{
putValue(Action.NAME, name);
putValue(Action.SMALL_ICON, icon);
putValue("Color", backGroundColor);
putValue(Action.SHORT_DESCRIPTION,
"Imposta il colore del pannello a " +
name.toUpperCase());
}

public void actionPerformed(ActionEvent e)
{
Color c = (Color)getValue("Color");
setBackground(c);
}
}
}

AlexMfM
03-06-2002, 09:09
Grazie mille per la spiegazione completa di codice!
Appena ho un filo di tempo (chiamasi fine settimana sob!) provo subito a fare come mi hai suggerito e poi ti faccio sapere l'esito!

Mi togli una curiosita'?
Come hai fatto a ripescare questo post sperso nella preistoria?
:gren:

fabio milazzo
03-06-2002, 18:45
ho fatto una ricerca dei messaggi che contengono la parola java.
la data non mi importava.

Loading