【发布时间】:2011-03-23 16:04:38
【问题描述】:
我在JFrame 中有一个JFileChooser。我在JFileChooser 中添加了一个ActionListener,以便单击“取消”按钮时起作用。我也可以选择“取消”按钮,但是当我按下“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”键时不会调用该函数)。
(错误)行为发生在我的 Fedora 10 x86_64 系统上,使用 Java 5、6 和 7。
附录:以下内容将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 分奖励给最有帮助的受访者。
【问题讨论】:
-
谢谢,我很高兴有机会研究这个有趣的问题。这不是默认的 L&F 吗?
-
@trashgod 默认 L&F 取决于 OS/JVM 组合:对于 Linux 或 Solaris 和 Sun 的 JVM,它是 Java(跨平台)L&F;对于 Windows/Sun,它是 Windows L&F;对于 Mac OS/X 和 Mac 的 JVM,它是 Mac L&F。请参阅 download.oracle.com/javase/tutorial/uiswing/lookandfeel/…> 了解更多信息。
标签: java swing keyboard look-and-feel jfilechooser