我刚刚根据JFileChooser
entry of the Swing Tutorial向我正在编写的小型桌面应用添加了一个标准的“打开文件”对话框。它正在生成一个如下所示的窗口:
但我希望有一个看起来像这样的窗口:
换句话说,我希望我的文件选择器具有Windows Vista / Windows 7的风格,而不是Windows XP的风格。这可能在Swing吗?如果是这样,它是如何完成的? (出于此问题的目的,假设代码将仅在Windows 7计算机上运行。)
答案 0 :(得分:21)
Java 6中的Swing似乎不支持此功能。
目前,我可以找到打开此对话框的最简单方法是通过SWT,而不是Swing。 SWT的FileDialog(javadoc)显示此对话框。以下是对SWT的FileDialog snippet的修改,以使用open而不是save对话框。我知道这不是您正在寻找的,但您可以将其与实用程序类隔离,并将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 ();
}
}
答案 1 :(得分:11)
即使是本机Windows应用程序也可以在Windows 7上显示此类对话框。这通常由OPENFILENAME
结构中的标志控制,其大小在调用WinAPI函数GetOpenFileName
时传递。 Swing(Java)使用钩子从“打开文件”对话框中获取事件;这些事件在Windows XP和Windows 7版本之间以不同方式传递。
所以答案是你无法从Swing控制FileChooser的外观。但是,当Java获得对这种新外观的支持时,您将自动获得新样式。
另一种选择是使用SWT,如this answer中所述。或者,您可以使用JNA调用Windows API或编写本机方法来执行此操作。
答案 2 :(得分:7)
有点像黑客,而且比Swing版本的权力稍微弱一些,但你考虑过使用java.awt.FileDialog
吗?它不应该只是看起来像Windows文件选择器,但实际上是一个。
答案 3 :(得分:7)
我不相信Swing会覆盖它,虽然它可能,如果它不是你可能需要看一些像SWT,这将使用实际的本机组件,或做一个自定义UI元素,如某事出自“肮脏的富客户”一书。
答案 4 :(得分:7)
Java 8可能最终会为此提供解决方案,但不幸的是(对于Swing应用程序)它只是作为JavaFX类FileChooser:
我已经从here测试了这段代码,它确实弹出了一个现代对话框(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主题中运行它(如here所示)。
请注意,这将需要您初始化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);
});
答案 5 :(得分:2)
好问题+1,看起来就像他们“忘记”为Win7(defaultLookAndFeel)实现了一些东西到Java6中,但是对于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() {
}
}
答案 6 :(得分:1)
虽然不能让这个目录工作!! DirectoryDialog将我们返回到树样式目录选择器,该选择器与问题中列出的选择器相同。问题是它不允许我选择/选择/打开隐藏文件夹。它也不允许导航到AppData,ProgramData等文件夹。
Windows 7样式的filedialog(swt)允许导航到这些文件夹,但是再次,不允许选择文件夹:(
<强>更新强>
要查看隐藏文件夹,请使用JFileChooser并使用setFileHidingEnabled(false)
。唯一的要求是用户需要在
Windows资源管理器的文件夹选项 - &gt;图
您将无法获得地址栏的灵活性,但如果您正在寻找Java中的非树类文件选择器,这也允许您浏览/查看隐藏文件/文件夹 - 那么这应该足够了
答案 7 :(得分:1)
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.Image;
在左上角添加图片。使用&#34; getResourceAsStream&#34;非常重要,您在导出后会注意到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");
获取绝对路径名而不是依赖于过滤器的路径名,这在其他驱动器上是错误的。
String absolutePath = dialog.open();
答案 8 :(得分:0)
由于Swing模拟各种L&amp; F,我猜你最好的选择是将你的JRE升级到最新版本,并希望JFileChooser UI已经更新。
答案 9 :(得分:0)
JFileChooser一直看起来有点奇怪,也有点慢。
尝试使用SWT的文件追踪器,或者你可以在JNA中包装C调用。