48

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

不需要的/XP 样式窗口的屏幕截图

但我希望有一个看起来像这样的窗口:

所需/7 样式窗口的屏幕截图

换句话说,我希望我的文件选择器具有 Windows Vista/Windows 7 的风格,而不是 Windows XP 的风格。这在 Swing 中可能吗?如果是这样,它是如何完成的?(就本问题而言,假设代码将仅在 Windows 7 计算机上运行。)

4

10 回答 10

20

Java 6 中的 Swing 似乎不支持这一点。

目前,我能找到打开此对话框的最简单方法是通过 SWT,而不是 Swing。SWT 的 FileDialog ( javadoc ) 会弹出这个对话框。以下是对 SWT 的FileDialog 片段的修改,以使用打开而不是保存对话框。我知道这不是您正在寻找的,但是您可以将其隔离到一个实用程序类中,并将 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 ();
    }
} 
于 2011-05-28T05:22:12.530 回答
10

甚至本机 Windows 应用程序也可以在 Windows 7 上显示这种类型的对话框。这通常由OPENFILENAME结构中的标志及其大小控制在对 WinAPI 函数的调用中GetOpenFileName。Swing (Java) 使用钩子从 Open File 对话框中获取事件;这些事件在 Windows XP 和 Windows 7 版本之间的传递方式不同。

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

另一种选择是使用 SWT,如this answer中所建议的那样。或者,您可以使用 JNA 调用 Windows API 或编写本机方法来执行此操作。

于 2011-05-31T06:20:30.397 回答
8

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 应用程序中,您必须在 javafx 线程中运行它Platform.runLater(如此处所示

请注意,这将需要您初始化 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);
});
于 2014-08-22T07:28:52.583 回答
7

有点 hack,并且比 Swing 版本稍微弱一点,但是你考虑过使用java.awt.FileDialog? 它不应该只是看起来像 Windows 文件选择器,而实际上应该是其中之一。

于 2011-04-18T14:01:28.307 回答
7

我不相信 Swing 会涵盖这一点,尽管它可能会涵盖,如果不是,您可能需要查看类似 SWT 之类的东西,它会利用实际的本机组件,或者做一个自定义 UI 元素,比如在《肮脏的富客户》一书。

于 2011-04-18T15:28:58.937 回答
2

好问题+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() {
    }
}
于 2011-05-25T11:21:11.603 回答
1

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

Windows 7 风格的文件对话框 (swt) 确实允许导航到这些文件夹,但话又说回来,不允许选择文件夹:(

更新 要查看隐藏文件夹,请使用 JFileChooser 并拥有setFileHidingEnabled(false). 唯一的要求是用户需要在

文件夹选项 -> 查看

Windows 资源管理器

您不会获得地址栏的灵活性,但如果您正在寻找 Java 中的非树状文件选择器,它还可以让您浏览/查看隐藏文件/文件夹 - 那么这就足够了

于 2013-06-08T06:58:14.817 回答
1

约翰麦卡锡的回答似乎是最好的。这里有一些建议。

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

在左上角添加图像。使用“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");

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

String absolutePath = dialog.open();
于 2015-07-28T12:15:47.847 回答
0

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

于 2011-04-18T14:58:26.063 回答
0

JFileChooser 在 Swing 上看起来总是有点奇怪,也有点慢。

尝试使用 SWT 的文件选择器,或者您可以将 C 调用包装在 JNA 中。

于 2011-05-24T21:46:59.530 回答