如何删除JFileChooser上的Ctrl + C操作? [英] How do you remove the Ctrl+C action on a JFileChooser?

查看:138
本文介绍了如何删除JFileChooser上的Ctrl + C操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我自己的程序中使用框架中的其他自定义组件嵌入了 JFileChooser 。这是我的应用程序的设计,因为它可能有助于可视化我的问题:

I'm embedding a JFileChooser in my program in my own frame with other custom components in the frame. Here's a design of my app as it may help visualize my issues:

如果你说不清楚,直接在 JFrame 标题是 JFileChoosers 。这应该是有效的方法是您为目的地分配快捷方式,然后当您按下这些快捷键时,所选文件将移动到目的地。

If you can't tell, the lists directly under the JFrame titles are JFileChoosers. The way this is supposed to work is you assign shortcuts to destinations and then when you press those shortcut keys, the selected file moves to the destination.

我这样做的策略是将快捷方式分配给整个框架的 InputMap javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW 范围。

My strategy for doing this is to assign the shortcut to a javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW scope of the InputMap of the entire frame.

然而令人烦恼的是,某些东西(我假设 JFileChooser )继续响应/吸收按键我不喜欢我想要它。例如,如果我按 Ctrl + C 我的快捷操作不会运行。我用原生的外观(我使用的是Windows 7)和默认的L& F尝试了这个,两种情况都有同样的问题。我想它可能试图在 JFileChooser 中对所选文件进行复制操作,因为如果我点击其中一个按钮强制它失去焦点,那么突然间我的 Ctrl + C 命令执行我的操作。

But what's annoying is that something (I assume the JFileChooser) keeps on responding/absorbing key presses I don't want it to. For example, if I press Ctrl+C my shortcut action doesn't get run. I've tried this with the native Look and Feel (I'm using windows 7) and the default L&F and both situations have the same problem. I think it might be trying to do a copy action of the selected file in the JFileChooser because if I click on one of the buttons to force it to lose focus, all the sudden my Ctrl+C command does my action.

但是,我不确定 JFileChooser 是如何做到这一点的。当我在其上调用 getKeyListeners()时,它返回一个空数组。我也尝试在所有三个示波器上清除这个键组合的输入映射,它似乎仍然吸收了按键。

But, I'm not really sure how the JFileChooser is doing this. When I call getKeyListeners() on it, it returns an empty array. I've also tried clearing its input map for this key combination at all three scopes, and it still seems to be absorbing the keypress.

任何人都可以给我一些示例代码使 JFileChooser 忽略 Ctrl + C ?此外,如果有人能告诉我将来如何调试这样的问题,那将会很有帮助。

Can anyone give me some sample code that makes the JFileChooser ignore Ctrl+C? Also, it'd be helpful if someone could tell me how to debug problems like this in the future.

这是我到目前为止尝试过的一些代码。您也可以使用它来尝试自己测试,因为此代码编译并运行,原样:

Here is some code of what I've tried so far. You can also use this to try to test this on your own, since this code compiles and runs, as-is:

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;
    }
}






UPDATE :我已经走到递归清除inputMaps并删除JFileChooser及其所有子组件的keyListeners,而JFileChooser 仍然吞下我的Ctrl + C命令。这是我用来做这个的代码(我将JFileChooser传递给它):


UPDATE: I've gone as far as to recursively clear the inputMaps and remove the keyListeners of the JFileChooser and all of its child components and the JFileChooser still swallows my Ctrl+C command. Here's the code I've used to do this (I passed my JFileChooser into this):

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);
        }
    }
}


推荐答案


详细信息视图仍然会有一个填充的输入映射

the details view will still have a populated inputmap

我怀疑细节之间的区别视图和列表视图是一个使用JTable,另一个是JList。所以我猜你只需要从细节视图的JTable中删除绑定。

I suspect the difference between the details view and the list view is that one uses a JTable the other a JList. So I would guess you only need to remove the bindings from the JTable of the details view.

这可以在不创建详细信息面板的情况下完成:

This can be done without creating the details panel:

InputMap im = (InputMap)UIManager.get("Table.ancestorInputMap");
KeyStroke ctrlC = KeyStroke.getKeyStroke("control C");
//im.put(ctrlC, "none");
im.remove(ctrlC);

同样,应该注意此解决方案(以及您目前拥有的解决方案)将删除所有组件的默认Ctrl + C功能,而不仅仅是为JFileChooser实例化的功能。

Again, it should be noted that this solution (along with the solution you currently have) will remove the default Ctrl+C functionality for all components, not just the ones instantiated for the JFileChooser.

编辑:


它不应该只从我删除它的那个中删除它吗?

Shouldn't it only be removing it from the ones I remove it from?

你的代码使用的是getParent()方法获取包含绑定的InputMap。此InputMap由组件的所有实例共享。当您使用时,组件将只有唯一的绑定:

Your code uses the getParent() method to get the InputMap that contains the binding. This InputMap is shared by all instances of a component. A component will only have unique bindings when you use:

component.getInputMap(...).put(...);

也就是说,绑定被添加到组件InputMap中,而不是其父项InputMap。

That is, the binding is added to the components InputMap, not its parents InputMap.


你怎么知道你可以这样做,这是正确的做法

How did you know you could do this and this is the right thing to do

请参阅 UIManager Defaults 。这列出了给定LAF的默认值。我不知道这是否正确。据我所知,效果与您现在使用的代码相同。这只是另一种方法或从InputMap中删除绑定,而无需实际组件访问父InputMap。

See UIManager Defaults. This list the defaults for the given LAF. I don't know if this is the right thing to do. As far as I know the effect is the same as the code you use now. This is just another way or removing a binding from an InputMap without needing an actual component to access the parents InputMap.

第二次编辑:

显示InputMaps的一些简单代码是相同的:

Some simple code to show the InputMaps are the same:

public static void main(String[] args)
{
    JButton first = new JButton("button");
    System.out.println(first.getInputMap().getParent());

    InputMap im = (InputMap) UIManager.get("Button.focusInputMap");
    System.out.println(im);
}

这篇关于如何删除JFileChooser上的Ctrl + C操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆