Swing是否支持Windows 7风格的文件select器?
我刚刚根据Swing教程的JFileChooser
条目向我写的一个小型桌面应用程序添加了一个标准的“ 打开文件 ”对话框。 它生成一个如下所示的窗口:
但我宁愿有一个如下所示的窗口:
换句话说,我希望我的文件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调用。