且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

带有图标和文件名的JavaFX文件列表视图

更新时间:2023-02-23 18:37:26

我提出了这个代码,它似乎可以将 getSystemIcon 返回的图标转换为JavaFX可以理解的格式。它通过使用 SwingUtilities.invokeLater Platform.runLater 的组合来尝试减轻任何潜在的线程问题。这两个项目。 javax.swing.Icon 被绘制为 java.awt.BufferedImage ,由转换SwingFXUtils 到JavaFX图像。

I came up with this code, which seems to work for converting the icon returned by getSystemIcon to a format which JavaFX can understand. It does this by using a combo of SwingUtilities.invokeLater with Platform.runLater to try to mitigate any potential threading issues between the two projects. The javax.swing.Icon is painted to java.awt.BufferedImage which is converted by SwingFXUtils to a JavaFX Image.

因此,您询问的代码的Swing Icon => JavaFX图像部分似乎有效。唯一的事情是,当我在运行Oracle Java8u20的OS X 10.7上测试应用程序时,我尝试的每个文件扩展名类型都给出了完全相同的图标。因此,在OS X上实际上不支持通过swing FileSystemView 从系统获取图标的方法(据我所知)。我想你可以在另一个操作系统上试一试,看看它是否适合你(假设你的任务不需要在OS X上支持这个图标查找功能)。

So the Swing Icon => JavaFX image portion of the code you were asking about seems to work. The only thing is, when I tested the application on OS X 10.7 running Oracle Java8u20, every file extension type I tried gave the exact same icon. So it would seem that your method for getting an icon from the system via the swing FileSystemView isn't really supported on OS X (as far as I can tell). I guess you could try it on another OS and see if it works for you there (presuming that supporting this icon lookup feature on OS X is not necessary for your task).

所以谷歌搜索带来了以下问题:

So googling around brought up the following question:

  • Access file type icons Mac OSX

在那里,Sam Barnum建议 FileView FileSystemView 更好 - 所以它对我有用。我切换你的代码使用 FileView 然后开始在OS X上获得不同文件类型的不同图标。图标仍然是非常小的16x16图标(我不知道例如,如何检索高分辨率视网膜图标),但至少检索到的图标看起来是正确的,文件类型是特定的。

And in that, Sam Barnum recommends a FileView works much better than a FileSystemView - and so it did for me. I switched your code to use a FileView and after that started getting different icons for different file types on OS X. The icons were still really small 16x16 icons (I wouldn't know how to retrieve the hi-res retina icons for instance), but at least the icons which were retrieved appeared correct and file type specific.

import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class FileIconViewer extends Application {

    @Override
    public void start(Stage stage) throws IOException {
        Runnable fetchIcon = () -> {
            File file = null;
            try {
                file = File.createTempFile("icon", ".png");

                // commented code always returns the same icon on OS X...
                // FileSystemView view = FileSystemView.getFileSystemView();
                // javax.swing.Icon icon = view.getSystemIcon(file);

                // following code returns different icons for different types on OS X...
                final javax.swing.JFileChooser fc = new javax.swing.JFileChooser();
                javax.swing.Icon icon = fc.getUI().getFileView(fc).getIcon(file);

                BufferedImage bufferedImage = new BufferedImage(
                    icon.getIconWidth(), 
                    icon.getIconHeight(), 
                    BufferedImage.TYPE_INT_ARGB
                );
                icon.paintIcon(null, bufferedImage.getGraphics(), 0, 0);

                Platform.runLater(() -> {
                    Image fxImage = SwingFXUtils.toFXImage(
                        bufferedImage, null
                    );
                    ImageView imageView = new ImageView(fxImage);
                    stage.setScene(
                        new Scene(
                            new StackPane(imageView), 
                            200, 200
                        )
                    );
                    stage.show();
                });
            } catch (IOException e) {
                e.printStackTrace();
                Platform.exit();
            } finally {
                if (file != null) {
                    file.delete();
                }
            }
        };

        javax.swing.SwingUtilities.invokeLater(fetchIcon);
    }

    public static void main(String[] args) { launch(args); }
}

注意:JavaFX问题跟踪器中有一条现有请求要添加此项JavaFX的功能(目前尚未安排实施,但您可以登录问题跟踪器并对问题进行投票,对其进行评论,将其链接回此***问题等):

Note: there is an existing request in the JavaFX issue tracker to add this functionality to JavaFX (it is currently not scheduled for implementation, though you could log into the issue tracker and vote for the issue, comment on it, link it back to this *** question, etc):

  • RT-19583 Possibility to get native icons, on different sizes.