JavaFX仿windows文件管理器目录树

时间:2024-04-14 11:19:31

一、windows文件管理器目录树

JavaFX仿windows文件管理器目录树

 

二、代码

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.util;

import imagemanagesystem.FileTreeItem;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javax.swing.filechooser.FileSystemView;

/**
 *
 * @author MK
 */
public class Test extends Application {
    public static File ROOT_FILE = FileSystemView.getFileSystemView().getRoots()[0];
    @Override
    public void start(Stage stage) {
        HBox hBox = new HBox();
        TreeView<String> treeView = new TreeView<>();
       
        FileTreeItem fileTreeItem = new FileTreeItem(ROOT_FILE, f -> {
            File[] allFiles = f.listFiles();
            File[] directorFiles = f.listFiles(File::isDirectory);
            List<File> list = new ArrayList<>(Arrays.asList(allFiles));
            list.removeAll(Arrays.asList(directorFiles));
            return list.toArray(new File[list.size()]);
        });
        treeView.setRoot(fileTreeItem);
        treeView.setShowRoot(false);
        treeView.setMinWidth(250);
        hBox.getChildren().add(treeView);
        StackPane stackPane = new StackPane();
        stackPane.getChildren().add(hBox);

        Scene scene = new Scene(stackPane, 900, 700);
        stage.setScene(scene);

        stage.show();
        stage.setOnCloseRequest(e -> {
            System.exit(0);
        });

    }

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

    }

}

 

package imagemanagesystem;

import cn.util.U;
import static cn.util.Test.ROOT_FILE;
import java.io.File;
import java.util.function.Function;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;

/**
 *
 * @author MK
 */
public class FileTreeItem extends TreeItem<String> {

    //判断树节点是否被初始化,没有初始化为真
    private boolean notInitialized = true;

    private final File file;
    private final Function<File,File[]> supplier;

    public FileTreeItem(File file) {
        super(U.getFileName(file), U.getFileIconToNode(file));
        this.file = file;
        supplier = (File f) -> {
            if (((FileTreeItem) this.getParent()).getFile() == ROOT_FILE) {
                String name = U.getFileName(f);
                if (name.equals("网络") || name.equals("家庭组")) {
                    return new File[0];
                }
            }
            return f.listFiles();
        };
    }
    public FileTreeItem(File file, Function<File,File[]> supplier) {
        super(U.getFileName(file),U.getFileIconToNode(file));
        this.file=file;
        this.supplier=supplier;
    }

 
    //重写getchildren方法,让节点被展开时加载子目录
    @Override
    public ObservableList<TreeItem<String>> getChildren() {

        ObservableList<TreeItem<String>> children = super.getChildren();
        //没有加载子目录时,则加载子目录作为树节点的孩子
        if (this.notInitialized && this.isExpanded()) {
            
            this.notInitialized = false;    //设置没有初始化为假

            /*判断树节点的文件是否是目录,
             *如果是目录,着把目录里面的所有的文件目录添加入树节点的孩子中。
             */
         
            if (this.getFile().isDirectory()) {
                for (File f : supplier.apply(this.getFile())) {
                    //如果文件是目录,则把它加到树节点上
                    if (f.isDirectory()) {
                        children.add(new FileTreeItem(f));
                    }
                }

            }
        }
        return children;
    }

    //重写叶子方法,如果该文件不是目录,则返回真
    @Override
    public boolean isLeaf() {

        return !file.isDirectory();
    }

    /**
     * @return the file
     */
    public File getFile() {
        return file;
    }

    
}
package cn.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.IntBuffer;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritablePixelFormat;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;

/**
 *
 * @author MK
 */
public class U {

    //设置图标
    public static Canvas getFileIconToNode(File file) {

        //获取系统文件的图标
        Image image = (Image) ((ImageIcon) FileSystemView.getFileSystemView()
                .getSystemIcon(file)).getImage();
        //构建图片缓冲区,设定图片缓冲区的大小和背景,背景为透明
        BufferedImage bi = new BufferedImage(image.getWidth(null),
                image.getHeight(null), BufferedImage.BITMASK);
        bi.getGraphics().drawImage(image, 0, 0, null);          //把图片画到图片缓冲区
        //将图片缓冲区的数据转换成int型数组
        int[] data = ((DataBufferInt) bi.getData().getDataBuffer()).getData();
        //获得写像素的格式模版
        WritablePixelFormat<IntBuffer> pixelFormat
                = PixelFormat.getIntArgbInstance();
        Canvas canvas = new Canvas(bi.getWidth() + 2, bi.getHeight() + 2);    //新建javafx的画布
        //获取像素的写入器
        PixelWriter pixelWriter = canvas.getGraphicsContext2D().getPixelWriter();
        //根据写像素的格式模版把int型数组写到画布
        pixelWriter.setPixels(1, 1, bi.getWidth(), bi.getHeight(),
                pixelFormat, data, 0, bi.getWidth());
        //设置树节点的图标
        return canvas;

    }

    public static String getFileName(File file) {
        return FileSystemView.getFileSystemView().getSystemDisplayName(file);
    }


}