繁体   English   中英

改变JFileChooser行为:阻止在文件路径JTextField中输入“choose”

[英]altering JFileChooser behaviour : preventing “choose” on enter in file path JTextField

向Swing Pros致以问候,这是一个很好的(我希望)问题。

以下是我看到的任务要求和可能的解决方案。 我想有人有这样的铁杆经验来分享一些关于这个的想法。

这不需要编码或类似的东西,我只需要一般性的建议 ,关于我需要使用驻留在sun.swing和/或javax.swing.plaf包中的私有符号的事实,哪种方法更可靠。

任务是修改/改变JFileChooser行为(实际上只是一点点)。

  1. 当用户在文件名JTextField中按Enter键,并且该字段包含dir的路径时,不要“选择”目录,而是切换到它。 是的,对话框配置为接受目录,但我们只需要接受“打开”按钮的点击,并且(可能)双击文件列表表。

  2. 通过在文件名文本字段中输入,阻止用户选择数据超过1GB的目录/文件

以下是一些常规解决方案选项:

一个。 聆听JFileChooser提供的基于属性的更改(事后触发哪个AFAICS,并且不会提供我们需要的控制程度)。

修改javax.swing.plaf.basic.BasicFileChooserUI(通过refrection,打破私有级封装)并修改引用

private Action approveSelectionAction = new ApproveSelectionAction();

这样我们的自定义操作就会对1和2进行额外检查。这种方法与plaf包链接,如果在此UI类下面的某个类中以某种方式覆盖此操作,则可能会失败。

C。 遍历JFileChooser组件层次结构,找到JTextField(显然应该只在组件树中出现一次),使用我们的自定义检查装饰挂在JTextField上的所有动作侦听器。 我的调试会话显示这个JTextField是生活在sun.swing.FilePane中的JTextField的一些匿名子类。 这种方法似乎更友好,但是对于某些操作系统来说,这个文本字段可能不存在,或者其他一些JTextField也存在于层次结构中。

好吧,似乎公共JFileChooser API不足以实现这种行为,而其他两个选项要么是深度魔术还是不可移植(长期),要么两者兼而有之。

所以,问题是:你会选择哪种方法?为什么?

关于option2,您不需要使用反射来自定义accept Action。 您可以覆盖approveSelection()方法。 就像是:

JFileChooser chooser = new JFileChooser( new File(".") )
{
    public void approveSelection()
    {
        if (getSelectedFile().exists())
        {
            System.out.println("duplicate");
            return;
        }
        else
            super.approveSelection();
    }
};

我最近遇到了同样的要求,即在JFileChooser的JTextField中按Enter键会导致显示的对话框遍历目录而不是从对话框返回。 只需单击“打开”按钮即可进行最终选择。

解决方案相当简单(至少对我的应用程序而言)并且有两个组件(请原谅混乱的格式化。我是这个论坛的新手,我不知道为什么代码没有正确显示)。

1 - 注册AWTListener以跟踪用户生成的最后一个事件类型

class MyChooser extends JFileChooser implements java.awt.AWTEventListener {

    ...
    MyChooser(){
        Toolkit.getDefaultToolkit().addAWTEventListener(this,
        AWTEvent.MOUSE_EVENT_MASK + AWTEvent.KEY_EVENT_MASK);
        ...

    }

    int lastEventId;

    public void eventDispatched(AWTEvent e) {
        lastEventId=e.getID();
    }
}

2 - 覆盖JFileChooser的approveSelection()方法,并检查批准请求是否是鼠标事件的结果(可能是由用户单击“打开”按钮引起的)或用户按Enter键导致的键事件。 'lastEventId'变量提供对此信息的访问。 我自己的批准选择看起来如下:

public void approveSelection() {
    File f=getSelectedFile();
    if (f.exists() && isTraversable(f) && lastEventId ==
        KeyEvent.KEY_PRESSED) {
        setCurrentDirectory(f);
        return;
    }
    super.approveSelection(); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM