我有JFileChooser
一个JFrame
。我添加了一个ActionListener
,JFileChooser
以便“取消”按钮在单击时起作用。我也可以选择“取消”按钮,但是当我按下“Enter”键时,什么也没有发生(即,ActionListener
不使用事件命令调用JFileChooser.CANCEL_SELECTION
)。我必须怎么做才能JFileChooser
在“取消”按钮上按“Enter”键等同于单击“取消”按钮?
这是我看到的(错误)行为的一个简单示例:
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();
}
}
});
}
}
要查看(错误)行为,请执行程序,选择“取消”,然后按“Enter”键。该程序不会在我的平台上终止——尽管当我单击“取消”按钮时它会终止。
扩展JFileChooser
和覆盖cancelSelection()
也不起作用(显然,当在“取消”按钮上按下“Enter”键时不会调用该函数)。
(错误)行为发生在我的带有 Java 5、6 和 7 的 Fedora 10 x86_64 系统上。
附录:以下内容添加KeyEventPostProcessor
到当前KeyboardFocusManager
并且似乎可以执行我想要的操作:
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();
}
}
});
}
}
然而,这似乎需要做很多工作,只是为了能够区分按下“取消”按钮上的回车键和其他任何地方。
你觉得它有什么问题吗?
发现的解决方案:将 GUI 外观设置为我的系统 (Linux) 的原生外观和感觉可以满足我的需求,而无需其他任何东西。这是我所不知道的,也是我一直在寻找的。解决方案是具有以下
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
作为该main()
方法的第一个可执行语句。然后可以省去所有焦点侦听器、关键事件处理器等。
我已将 100 分奖励给最有帮助的受访者。