2010-11-20 23 views
5

对Swing Pros的问候,这是一个很好的(我希望)问题。改变JFileChooser的行为:防止在文件路径中输入“选择”JTextField

以下是我看到的任务要求和可能的解决方案。我希望有人有这样的核心经验分享一些想法。

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

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

  1. 当用户按下文件名的JTextField进入,并且该字段包含的目录路径

    ,没有“选择”的目录,但切换到它代替。是的,该对话框被配置为接受目录,但我们只需要接受点击“打开”按钮,并(可能)双击文件列表表格。

    一个:

  2. 通过打击在文件名的文本字段

我这里还有几个通用的解决方案选项输入阻止用户选择与超过1GB的数据更多的是目录/文件。听取JFileChooser提供的基于属性的更改(其中AFAICS是事后触发的,并且不会提供我们需要的控制级别)。

b。与javax.swing.plaf.basic.BasicFileChooserUI中鼓捣(通过refrection,打破了私有级封装),并改变参考

private Action approveSelectionAction = new ApproveSelectionAction(); 

使我们的自定义操作做额外的检查1和2本与plaf包链接,并且可能会失败,如果在此UI类下面的某个类中以某种方式覆盖此操作。

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

好吧,公共JFileChooser API似乎不足以实现这种行为,而另外两种选择是深魔法或不可移植(长期),或者甚至两者。

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

回答

5

关于选项2,您不需要使用反射来自定义接受操作。您可以重写approveSelection()方法。例如:

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

哦,我dumbo,我会测试,并报告我的发现。 – 2010-11-21 22:12:25

+0

嗯,我完全可以通过在某些应该被认为无效的情况下不调用super.approveSelection()来拦截和解除批准选择事件。这是一个不错的解决方案,再次感谢。 – 2010-12-09 22:03:43

3

我最近遇到了同样的要求,即,在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(); } 
+0

精美的作品。作为一个鼠标 - 憎恨的默认功能真的很烦人,我担心找到解决方案会很困难。 – 2016-02-24 20:16:33