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

带有图标和文件名的JavaFX文件列表视图,javafx,Javafx,在JavaFX对话框中,我想显示一个带有图标和文件名的文件列表 很容易找到如何获取文件扩展名的图标: File file = File.createTempFile("icon", ".doc"); FileSystemView view = FileSystemView.getFileSystemView(); java.swing.Icon icon = view.getSystemIcon(file); file.delete(); 但是,如何在JavaFXL

在JavaFX对话框中,我想显示一个带有图标和文件名的文件列表

很容易找到如何获取文件扩展名的图标:

File file = File.createTempFile("icon", ".doc");  
FileSystemView view = FileSystemView.getFileSystemView();      
java.swing.Icon icon = view.getSystemIcon(file);      
file.delete();
但是,如何在JavaFX
ListView
中绘制
Swing图标呢

private static class AttachmentListCell extends ListCell<String> {
    @Override
    public void updateItem(String fileName, boolean empty) {
        if (item != null) {

            // Get file Icon for fileName as shown above.
            java.swing.Icon icon = 

            // Transform Icon to something that can be 
            // added to the box, maybe an ImageView.
            javafx.scene.image.ImageView image = ???

            // Label for file name
            Label label = new Label(item);

            HBox box = new HBox();
            box.getChildren().addAll(image, label);
            setGraphic(box);
        }
    }
}
私有静态类AttachmentListCell扩展ListCell{
@凌驾
public void updateItem(字符串文件名,布尔值为空){
如果(项!=null){
//获取文件名的文件图标,如上所示。
java.swing.Icon图标=
//将图标转换为可以
//添加到框中,可能是一个ImageView。
javafx.scene.image.ImageView图像=???
//文件名标签
标签=新标签(项目);
HBox box=新的HBox();
box.getChildren().addAll(图像、标签);
设置图形(框);
}
}
}

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

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

因此,谷歌搜索带来了以下问题:

在这方面,Sam Barnum建议使用
文件视图
文件系统视图
工作得好得多,这对我来说也是如此。我将您的代码切换为使用
文件视图
,然后开始在OS X上为不同的文件类型获取不同的图标。这些图标仍然非常小,只有16x16个图标(例如,我不知道如何检索高分辨率视网膜图标),但至少检索到的图标是正确的,并且是特定于文件类型的

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的请求(目前未计划实施此功能,但您可以登录问题跟踪器并对问题进行投票、评论、将其链接回此StackOverflow问题等):


下面是一个带有文件图标的列表视图示例:

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

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

import javax.swing.filechooser.FileSystemView;

public class ListViewCellFactory2 extends Application {

    ListView<String> list = new ListView<String>();
    ObservableList<String> data = FXCollections.observableArrayList(
            "a.msg", "a1.msg", "b.txt", "c.pdf", 
            "d.html", "e.png", "f.zip",
            "g.docx", "h.xlsx", "i.pptx");

    @Override
    public void start(Stage stage) {
        VBox box = new VBox();
        Scene scene = new Scene(box, 200, 200);
        stage.setScene(scene);
        stage.setTitle("ListViewSample");
        box.getChildren().addAll(list);
        VBox.setVgrow(list, Priority.ALWAYS);

        list.setItems(data);

        list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
            @Override
            public ListCell<String> call(ListView<String> list) {
                return new AttachmentListCell();
            }
        });

        stage.show();
    }

    private static class AttachmentListCell extends ListCell<String> {
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setGraphic(null);
                setText(null);
            } else {
                Image fxImage = getFileIcon(item);
                ImageView imageView = new ImageView(fxImage);
                setGraphic(imageView);
                setText(item);
            }
        }
    }

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


    static HashMap<String, Image> mapOfFileExtToSmallIcon = new HashMap<String, Image>();

    private static String getFileExt(String fname) {
        String ext = ".";
        int p = fname.lastIndexOf('.');
        if (p >= 0) {
            ext = fname.substring(p);
        }
        return ext.toLowerCase();
    }

    private static javax.swing.Icon getJSwingIconFromFileSystem(File file) {

        // Windows {
        FileSystemView view = FileSystemView.getFileSystemView();
        javax.swing.Icon icon = view.getSystemIcon(file);
        // }

        // OS X {
        //final javax.swing.JFileChooser fc = new javax.swing.JFileChooser();
        //javax.swing.Icon icon = fc.getUI().getFileView(fc).getIcon(file);
        // }

        return icon;
    }

    private static Image getFileIcon(String fname) {
        final String ext = getFileExt(fname);

        Image fileIcon = mapOfFileExtToSmallIcon.get(ext);
        if (fileIcon == null) {

            javax.swing.Icon jswingIcon = null; 

            File file = new File(fname);
            if (file.exists()) {
                jswingIcon = getJSwingIconFromFileSystem(file);
            }
            else {
                File tempFile = null;
                try {
                    tempFile = File.createTempFile("icon", ext);
                    jswingIcon = getJSwingIconFromFileSystem(tempFile);
                }
                catch (IOException ignored) {
                    // Cannot create temporary file. 
                }
                finally {
                    if (tempFile != null) tempFile.delete();
                }
            }

            if (jswingIcon != null) {
                fileIcon = jswingIconToImage(jswingIcon);
                mapOfFileExtToSmallIcon.put(ext, fileIcon);
            }
        }

        return fileIcon;
    }

    private static Image jswingIconToImage(javax.swing.Icon jswingIcon) {
        BufferedImage bufferedImage = new BufferedImage(jswingIcon.getIconWidth(), jswingIcon.getIconHeight(),
                BufferedImage.TYPE_INT_ARGB);
        jswingIcon.paintIcon(null, bufferedImage.getGraphics(), 0, 0);
        return SwingFXUtils.toFXImage(bufferedImage, null);
    }

}

导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.HashMap;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.scene;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.util.Callback;
导入javax.swing.filechooser.FileSystemView;
公共类ListViewCellFactory2扩展了应用程序{
ListView列表=新建ListView();
ObservableList data=FXCollections.observableArrayList(
“a.msg”、“a1.msg”、“b.txt”、“c.pdf”,
“d.html”、“e.png”、“f.zip”,
“g.docx”、“h.xlsx”、“i.pptx”);
@凌驾
公众假期开始(阶段){
VBox box=新的VBox();
场景=新场景(框,200200);
舞台场景;
stage.setTitle(“ListViewSample”);
box.getChildren().addAll(列表);
setVgrow(列表、优先级、始终);
列表.设置项(数据);
list.setCellFactory(新回调(){
@凌驾
公共ListCell调用(ListView列表){
返回新的AttachmentListCell();
}
});
stage.show();
}
私有静态类AttachmentListCell扩展ListCell{
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
if(空){
设置图形(空);
setText(空);
}否则{
图像fxImage=getFileIcon(项目);
ImageView ImageView=新ImageView(fxImage);
设置图形(图像视图);
setText(项目);
}
}
}
公共静态void main(字符串[]args){
发射(args);
}
静态HashMap mapOfFileExtToSmallIcon=新HashMap();
私有静态字符串getFileExt(字符串fname){
字符串ext=“.”;
int p=fname.lastIndexOf('.');
如果(p>=0){
ext=fname.substring(p);
}
返回ext.toLowerCase();
}
私有静态javax.swing.Icon getJSwingIconFromFileSystem(文件文件){
//窗户{
FileSystemView视图=FileSystemView.getFileSystemView();
javax.swing.Icon-Icon=view.getSystemIcon(文件);
// }
//OSX{
//final javax.swing.JFileChooser fc=new javax.swing.JFileChooser();
//javax.swing.Icon Icon=fc.getUI().getFileView(fc).getIcon(文件);
// }
返回图标;
}
私有静态图像getFileIcon(字符串fname){
最终字符串ext=getFileExt(fname);
Image fileIcon=mapOfFileExtToSmallIcon.get(ext);
如果(fileIcon==null){
javax.swing.Icon jswingIcon=null;
File=new