Swing是否支持Windows 7风格的文件select器?

我刚刚根据Swing教程的JFileChooser条目向我写的一个小型桌面应用程序添加了一个标准的“ 打开文件 ”对话框。 它生成一个如下所示的窗口:

不需要的/ XP风格的窗口截图

但我宁愿有一个如下所示的窗口:

所需/ 7风格窗口的屏幕截图

换句话说,我希望我的文件select器具有Windows Vista / Windows 7的风格,而不是Windows XP的风格。 这在Swing中可能吗? 如果是这样,那怎么办? (就这个问题而言,假定代码将在Windows 7计算机上独占运行。)

它没有出现在Java 6中的Swing中支持。

目前,我能find打开这个对话框最简单的方法是通过SWT,而不是Swing。 SWT的FileDialog( javadoc )调出这个对话框。 以下是对SWT的FileDialog片段的修改,使用打开而不是保存对话框。 我知道这不是你正在寻找的东西,但你可以将它隔离到一个实用工具类,并添加swt.jar到你的类path这个function。

 import org.eclipse.swt.*; import org.eclipse.swt.widgets.*; public class SWTFileOpenSnippet { public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); // Don't show the shell. //shell.open (); FileDialog dialog = new FileDialog (shell, SWT.OPEN | SWT.MULTI); String [] filterNames = new String [] {"All Files (*)"}; String [] filterExtensions = new String [] {"*"}; String filterPath = "c:\\"; dialog.setFilterNames (filterNames); dialog.setFilterExtensions (filterExtensions); dialog.setFilterPath (filterPath); dialog.open(); System.out.println ("Selected files: "); String[] selectedFileNames = dialog.getFileNames(); for(String fileName : selectedFileNames) { System.out.println(" " + fileName); } shell.close(); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } } 

即使是本地Windows应用程序也可以在Windows 7上显示这种types的对话框。这通常由OPENFILENAME结构中的标志控制,其大小通过调用WinAPI函数GetOpenFileName来传递。 Swing(Java)使用钩子从打开文件对话框中获取事件; 这些事件在Windows XP和Windows 7版本之间传递不同。

所以答案是你无法控制Swing中FileChooser的外观。 但是,当Java获得这种新外观的支持时,您将自动获得新的样式。

另一个select是使用SWT,正如在这个答案中所build议的。 或者,您可以使用JNA调用Windows API或编写本机方法来执行此操作。

有点破解,并且比Swing版本的权力稍差,但你有没有考虑使用java.awt.FileDialog ? 它不应该只是看起来像Windows文件select器,但实际上一个。

我不相信Swing会覆盖,尽pipe它可能,如果它不,你可能需要看看像SWT,这将使用实际的本地组件,或做一个自定义UI元素, “肮脏的客户”书。

Java 8可能最终会带来一个解决scheme,但不幸的是(对于Swing应用程序),它只能作为JavaFX类FileChooser来使用 :

我从这里testing了这个代码,它确实popup了一个现代的对话框(Windows 7在这里):

 FileChooser fileChooser = new FileChooser(); //Set extension filter FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG"); FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG"); fileChooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG); //Show open file dialog File file = fileChooser.showOpenDialog(null); 

为了将其集成到Swing应用程序中,您必须通过Platform.runLater (如下所示)在javafx线程中运行它。

请注意,这将需要你初始化javafx线程(在这个例子中,这是在现场初始化,在new JFXPanel() )完成的。

总而言之,在摇摆应用程序中准备运行的解决scheme如下所示:

 new JFXPanel(); // used for initializing javafx thread (ideally called once) Platform.runLater(() -> { FileChooser fileChooser = new FileChooser(); //Set extension filter FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG"); FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG"); fileChooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG); //Show open file dialog File file = fileChooser.showOpenDialog(null); }); 

好的问题+1,看起来像他们“忘了”为Win7(defaultLookAndFeel)实现东西到Java6中,但是对于WinXP工作correclty,我也希望也必须存在一些方法/属性

无论如何,你可以试试这个代码,

 import java.io.File; import javax.swing.*; import javax.swing.filechooser.FileFilter; class ChooserFilterTest { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { String[] properties = {"os.name", "java.version", "java.vm.version", "java.vendor"}; for (String property : properties) { System.out.println(property + ": " + System.getProperty(property)); } JFileChooser jfc = new JFileChooser(); jfc.showOpenDialog(null); jfc.addChoosableFileFilter(new FileFilter() { @Override public boolean accept(File f) { return f.isDirectory() || f.getName().toLowerCase().endsWith(".obj"); } @Override public String getDescription() { return "Wavefront OBJ (*.obj)"; } @Override public String toString() { return getDescription(); } }); int result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?"); System.out.println("Displayed description (Metal): " + (result == JOptionPane.YES_OPTION)); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); SwingUtilities.updateComponentTreeUI(jfc); } catch (Exception e) { e.printStackTrace(); } jfc.showOpenDialog(null); result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?"); System.out.println("Displayed description (System): " + (result == JOptionPane.YES_OPTION)); } }; SwingUtilities.invokeLater(r); } private ChooserFilterTest() { } } 

不能使这个工作的目录虽然! DirectoryDialog把我们抛回到与问题中列出的树样式目录select器相同。 问题是,它不允许我select/select/打开隐藏的文件夹。 也不允许导航到像AppData,ProgramData等文件夹。

Windows 7风格filedialog(swt)确实允许导航到这些文件夹,但是,然后再次,不允许文件夹select:(

更新要查看隐藏的文件夹使用JFileChooser和setFileHidingEnabled(false) 。 与此唯一的任务是用户需要“显示隐藏文件,文件夹和驱动器”中select

文件夹选项 – >查看

的Windows资源pipe理器

你不会得到一个地址栏的灵活性,但是如果你正在四处寻找像Java中的文件select器,它也可以浏览/查看隐藏的文件/文件夹 – 那么这应该足够

约翰·麦卡锡的答案似乎是最好的。 这里有一些build议。

 import org.eclipse.swt.*; import org.eclipse.swt.widgets.*; import org.eclipse.swt.graphics.Image; 

在左上angular添加图片。 使用“getResourceAsStream”很重要,在导出为Runnable jar之后您会注意到:

 Display display = new Display(); Shell shell = new Shell(display); InputStream inputImage = getClass().getResourceAsStream("/app/launcher.png"); if (inputImage != null) { shell.setImage(new Image(display, inputImage)); } 

用户的主目录:

 String filterPath = System.getProperty("user.home"); 

获取绝对path名而不是依赖于filter的path名,这在其他驱动器上是错误的。

 String absolutePath = dialog.open(); 

由于Swing模拟各种L&F的,我想你最好的select是将JRE升级到最新版本,并希望JFileChooser UI已经更新。

JFileChooser与Swing一起看起来有点奇怪,也有点慢。

尝试使用SWT的filechooser,或者可以在JNA中包装C调用。