Como agir ao pressionar “Enter” quando no botão “Cancelar” no JFileChooser?
eu tenho umJFileChooser
em umJFrame
. Eu adicionei umActionListener
aoJFileChooser
para que o botão "Cancelar" funcione quando clicado. Também posso clicar no botão "Cancelar", mas quando pressiono a tecla "Enter", nada acontece (ou seja, oActionListener
não é chamado com o comando eventJFileChooser.CANCEL_SELECTION
) O que devo fazer com oJFileChooser
para que pressionar a tecla "Enter" quando estiver no botão "Cancelar" seja equivalente a clicar no botão "Cancelar"?
Aqui está um exemplo simples do (mis) comportamento que estou vendo:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public final class TestApp {
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
final JFileChooser chooser = new JFileChooser();
chooser.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
System.exit(0);
}
});
final JFrame frame = new JFrame();
frame.add(chooser);
frame.pack();
frame.setVisible(true);
}
catch (final Throwable t) {
t.printStackTrace();
}
}
});
}
}
Para ver o (des) comportamento, execute o programa, selecione "Cancelar" e pressione a tecla "Enter". O programa não termina na minha plataforma - embora seja quando clico no botão "Cancelar".
EstendendoJFileChooser
e substituindocancelSelection()
também não funciona (aparentemente, essa função não é chamada quando a tecla "Enter" é pressionada enquanto você pressiona o botão "Cancelar").
O (mis) comportamento ocorre no meu sistema Fedora 10 x86_64 com Java 5, 6 e 7.
ADENDO: O seguinte adiciona umKeyEventPostProcessor
para o atualKeyboardFocusManager
e parece fazer o que eu quero:
import java.awt.Component;
import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public final class TestApp {
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
final JFileChooser chooser = new JFileChooser();
chooser.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
System.out.println(e.paramString());
System.exit(0);
}
});
final KeyboardFocusManager kfm = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
kfm.addKeyEventPostProcessor(new KeyEventPostProcessor() {
@Override
public boolean postProcessKeyEvent(final KeyEvent e) {
if (e.getID() == KeyEvent.KEY_RELEASED
&& e.getKeyCode() == KeyEvent.VK_ENTER) {
final Component comp = e.getComponent();
if (chooser.isAncestorOf(comp)) {
if (!(comp instanceof JButton)) {
chooser.approveSelection();
}
else {
final JButton button = (JButton) comp;
if ("Cancel".equals(button.getText())) {
chooser.cancelSelection();
}
else {
chooser.approveSelection();
}
}
}
}
return false;
}
});
final JFrame frame = new JFrame();
frame.add(chooser);
frame.pack();
frame.setVisible(true);
}
catch (final Throwable t) {
t.printStackTrace();
}
}
});
}
}
Parece muito trabalho, no entanto, apenas para distinguir entre pressionar a tecla Enter no botão "Cancelar" em comparação com qualquer outro lugar.
Você vê algum problema com isso?
SOLUÇÃO DESCOBERTA: Definir a aparência da GUI como nativa para o meu sistema (Linux) faz o que eu quero sem a necessidade de mais nada. Era disso que eu ignorava e procurava. A solução é ter o seguinte
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
como a primeira declaração executável domain()
método. Pode-se então dispensar todos os ouvintes focados, processadores de eventos importantes, etc.
Concedi os 100 pontos ao respondente mais útil.