我刚刚在我正在写的一个小型桌面应用程序中添加了一个标准的"打开文件"对话框,基于Swing教程的JFileChooser
入口。它生成的窗口看起来像这样:
但我更喜欢有一个看起来像这样的窗口:
换句话说,我想要我的文件选择器具有Windows Vista / Windows 7的样式,而不是Windows XP的样式。 在Swing中是否可以实现?如果可以,如何做到?(为了这个问题,假设代码将仅在Windows 7计算机上运行。)
我刚刚在我正在写的一个小型桌面应用程序中添加了一个标准的"打开文件"对话框,基于Swing教程的JFileChooser
入口。它生成的窗口看起来像这样:
但我更喜欢有一个看起来像这样的窗口:
换句话说,我想要我的文件选择器具有Windows Vista / Windows 7的样式,而不是Windows XP的样式。 在Swing中是否可以实现?如果可以,如何做到?(为了这个问题,假设代码将仅在Windows 7计算机上运行。)
在Java 6的Swing中似乎不支持此功能。
目前,我能找到的最简单的打开此对话框的方法是通过SWT而不是Swing。 SWT的FileDialog(javadoc)可以打开此对话框。以下是SWT的FileDialog代码示例FileDialog snippet的修改版本,以使用打开而不是保存对话框。我知道这不完全是您要寻找的,但您可以将其隔离到一个实用程序类中,并将swt.jar添加到您的类路径中以获取此功能。
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 ();
}
}
OPENFILENAME
结构中的标志以及其大小在调用WinAPI函数GetOpenFileName
时进行控制。Swing(Java)使用钩子来获取打开文件对话框中的事件;这些事件在Windows XP和Windows 7版本之间传递方式不同。Java 8可能终于为此提供了解决方案,但不幸的是(对于Swing应用程序而言),它只作为JavaFX类FileChooser提供:
我已经从这里测试过这段代码,它确实弹出了一个现代对话框(在此处为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()
中)。
总之,在Swing应用程序中准备好运行的解决方案将如下所示:
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);
});
showOpenDialog(null)
没有指定父/所有者窗口,因此弹出窗口不是模态的。它期望一个javafx.stage.Window
,但我正在使用Swing的java.awt.Window
。我该如何实现模态FileChooser
? - MasterHD虽然不如Swing版本功能强大,但如果你考虑使用java.awt.FileDialog
,也是一个小技巧。它不仅应该看起来像Windows文件选择器,而且实际上就是一个。
<rant>
Java 7 在这个古老的类上进行了微小的增强。我可以理解焦点正在从 Swing 转移,但我仍然无法相信他们不能为这个基本重要的对话框做更多的事情!</rant>
- Luke Usherwood我不认为Swing会覆盖那个,尽管可能会有,如果没有,你可能需要看一下像SWT这样的东西,它将使用实际的本地组件,或者做一个自定义的UI元素,就像“Filthy Rich Clients”书中的一些内容。
好问题+1,看起来似乎他们在Java6中没有为Win7(defaultLookAndFeel)实现某些功能,但对于WinXP,它可以正常工作,我也希望存在某些方法/属性
无论如何,您可以尝试使用以下代码:
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将我们带回到树状目录选择器,它与问题中列出的选择器相同。问题是它不允许我选择/打开隐藏的文件夹。也不允许浏览到像AppData、ProgramData等文件夹。
Windows 7风格的文件对话框(swt)允许浏览这些文件夹,但是又不允许选择文件夹:(
更新
要查看隐藏文件夹,请使用JFileChooser并设置setFileHidingEnabled(false)
。唯一的要求是用户需要在Windows资源管理器的
文件夹选项 -> 查看
中选择“显示隐藏的文件、文件夹和驱动器”
您将无法获得地址栏的灵活性,但是如果您正在寻找一种非树形文件选择器来浏览/查看隐藏的文件/文件夹,则应该足够了
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.Image;
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");
String absolutePath = dialog.open();
由于Swing模拟了各种外观和感觉,我猜你最好的选择是升级你的JRE到最新版本,并希望JFileChooser UI已经得到更新。