JFileChooser按您键入的名称过滤文件



我已经弄清楚如何按文件类型过滤,但我无法弄清楚如何过滤掉文件,因为我在键盘上键入文件名文本字段。如果我的目录中有1000个文件,其中两个以字母q开头,那么我希望当我在JFileChooser中键入q这个词时,它将过滤掉所有不以q开头的文件,并且在我键入时应该继续,并且应该选择最佳匹配。难道就没有这样的例子吗?似乎每个JFileChooser问题和教程都只关注按文件类型过滤,而不是按名称过滤。

这行得通(对于Metal LAF)。虽然它本身是一个糟糕的解决方案,但其他选择并不比它更诱人。

public class FilterChooser {
    JFileChooser chooser = new JFileChooser();
    JTextField tf = (JTextField) ((JPanel) ((JPanel) chooser.getComponent(3)).getComponent(0)).getComponent(1);
    FilterChooser() {
        tf.getDocument().addDocumentListener(new DocumentListener() {
            public void insertUpdate(DocumentEvent e) {
                modifyFilter();
            }
            public void removeUpdate(DocumentEvent e) {
                modifyFilter();
            }
            public void changedUpdate(DocumentEvent e) {
                modifyFilter();
            }
        });
        JFrame f = new JFrame();
        chooser.showOpenDialog(f);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
    void modifyFilter() {
        final String text = tf.getText();
        chooser.setFileFilter(new FileFilter() {
            @Override
            public String getDescription() {
                return null;
            }
            @Override
            public boolean accept(File f) {
                return (f.isDirectory() || f.getName().startsWith(text));
            }
        });
    }
    public static void main(String[] args) {
        new FilterChooser();
    }
}

注释和解释:

  • JFileChooser中的文本字段在MetalFileChooserUI类中声明为private字段,因此没有简单的方法可以达到它。我把它取到tf中,因为我做了功课,检查了它的位置——如果布局改变了(由于向后兼容性,在未来几年不会发生),这个中断。你也可以递归地迭代子组件。
  • 我只对文件设置过滤器。如果你想把它应用到目录,改变FileFilteraccept方法。
  • 过滤器是区分大小写的,因为它是目前实现的。您可以通过更改FileFilteraccept方法来修改此行为。
  • 我添加了空框架,这样JVM就会在你关闭它时退出(文件选择器,作为一个对话框,不会这样做)。
  • 根据更大的画面,设置字段和方法的修饰符以满足您的需要。

我认为为JFileChooser实现全面自动完成可能不是一件小事。您需要访问选择器的JTextField,但这不是现成的(尽管并非不可能)。然后,您可以将自定义DocumentFilter应用于该字段,然后自动填充(并部分选择单词的后端)作为用户类型。

进一步阅读:http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html过滤器

然而,这似乎是很多工作。

相反,您知道JFileChooser允许您动态创建过滤器吗?打开选择器,输入'q*',按回车键,选择器将只显示以'q'开头的文件。

我现在有我想要的行为。我仍然无法相信这是一场多么大的斗争,但我猜Swing社区中没有人认为JFileChooser有这种行为或有更好的钩子来实现它是合适的。谢谢你user1803551的回答,我接受你的回答,我张贴我的只是为了展示我如何调整你的得到我确切想要的行为。

public void setupListeners()
{
    JFileChooser chooser = new JFileChooser();
    JTextField fileChooserTextField = (JTextField) ((JPanel) ((JPanel) chooser.getComponent(3)).getComponent(0)).getComponent(1);
    chooser.addKeyListener(new KeyListener()
    {
       @Override
       public void keyTyped(KeyEvent e)
       {
       }
       @Override
       public void keyReleased(KeyEvent e)
       {
          filterAsYouType(fileChooserTextField, chooser);
       }
       @Override
       public void keyPressed(KeyEvent e)
       {
       }
    });
}
    private void filterAsYouType(final JTextField tf, final JFileChooser chooser)
    {
    final String text = tf.getText();
    chooser.setFileFilter(new FileFilter()
    {
       @Override
       public boolean accept(File f)
       {
          if(text.equals("")
          {
             return true;
          }
          if(f.getName().equals(text))
          {
             chooser.setSelectedFile(f);
             tf.setCaretPosition(text.length());
          }
          if(f.getName().startsWith(text))
          {
             return true;
          }
          return false;
       }
       @Override
       public String getDescription()
       {
          return null;
       }
    });
    }
}

相关内容

  • 没有找到相关文章

最新更新