JFileChooser
我在我自己的框架中的程序中嵌入了一个框架中的其他自定义组件。这是我的应用程序的设计,因为它可能有助于可视化我的问题:
如果你看不出来,直接在JFrame
标题下的列表是JFileChoosers
. 这应该工作的方式是您将快捷方式分配给目的地,然后当您按下这些快捷键时,所选文件将移动到目的地。
我这样做的策略是将快捷方式分配给整个框架 的javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW
范围。InputMap
但令人讨厌的是,某些东西(我认为JFileChooser
)不断响应/吸收我不希望的按键。例如,如果我按下Ctrl+C
我的快捷操作不会运行。我已经用原生的外观和感觉(我使用的是 Windows 7)和默认的 L&F 进行了尝试,这两种情况都有同样的问题。我认为它可能正在尝试对所选文件执行复制操作,JFileChooser
因为如果我单击其中一个按钮以强制它失去焦点,我的Ctrl+C
命令会突然执行我的操作。
但是,我不确定这JFileChooser
是如何做到的。当我调用getKeyListeners()
它时,它返回一个空数组。我还尝试在所有三个范围内清除此组合键的输入映射,它似乎仍在吸收按键。
谁能给我一些使JFileChooser
忽略的示例代码Ctrl+C
?另外,如果有人能告诉我将来如何调试这样的问题,那将会很有帮助。
这是我迄今为止尝试过的一些代码。您也可以使用它来尝试自己测试它,因为此代码按原样编译和运行:
package com.sandbox;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class Sandbox {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control C"), "println");
panel.getActionMap().put("println", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.out.println("The JPanel action was performed!");
}
});
panel.add(buildFileChooser()); //if you comment out this line, Ctrl+C does a println, otherwise my action is ignored.
frame.setContentPane(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static JFileChooser buildFileChooser() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.getActionMap().clear(); //I've tried lots of ideas like this, but the JFileChooser still responds to Ctrl+C
return fileChooser;
}
}
更新:我已经递归地清除 inputMaps 并删除 JFileChooser 的 keyListeners 及其所有子组件,而 JFileChooser仍然吞下我的 Ctrl+C 命令。这是我用来执行此操作的代码(我将 JFileChooser 传递给此代码):
private static void removeKeyboardReactors(JComponent root) {
System.out.println("I'm going to clear the inputMap of: " + root);
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).clear();
root.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).clear();
root.getInputMap(JComponent.WHEN_FOCUSED).clear();
root.getActionMap().clear();
if (root.getRootPane() != null) {
removeKeyboardReactors(root.getRootPane());
}
for (KeyListener keyListener : root.getKeyListeners()) {
root.removeKeyListener(keyListener);
}
for (Component component : root.getComponents()) {
if (component instanceof JComponent) {
removeKeyboardReactors((JComponent) component);
} else if (component instanceof Container) {
Container container = (Container) component;
for (Component containerComponent : container.getComponents()) {
if (containerComponent instanceof JComponent) {
removeKeyboardReactors((JComponent) containerComponent);
} else {
System.out.println("This Container Component was not a JComponent: " + containerComponent);
}
}
} else {
System.out.println("This was not a JComponent: " + component);
}
}
}