JavaFX, не могу поставить иконку в TreeView

462
21 июля 2017, 02:11

Изображения видимы, но не ставятся на TreeItem:

Код

  package Application;
import java.io.File;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.TreeItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class FileSeeker extends TreeItem<File> {
     Image icon = new Image(FileSeeker.class.getResourceAsStream("ImagesAndCss/foldclose16.png"));
     Image image = new Image(FileSeeker.class.getResourceAsStream("ImagesAndCss/foldopen16.png"));
    public FileSeeker(File file) {
        super(file);
    }
    public FileSeeker(File file, ImageView imageview){
        super(file,imageview);
    }
    @Override
    public ObservableList<TreeItem<File>> getChildren() {
        if (isFirstChildren) {
            isFirstChildren = false;
            super.getChildren().setAll(buildFoldersAndFiles(this));
        }
        return super.getChildren();
    }
    @Override
    public boolean isLeaf() {
        if (isFirstLeaf) {
            isFirstLeaf = false;
            File f = (File) getValue();
            isLeaf = f.isFile();
        }
        return isLeaf;
    }
    private ObservableList<TreeItem<File>> buildFoldersAndFiles(TreeItem<File> treeItem) {
        File f = treeItem.getValue();
        f.getName();
        if(treeItem.getValue().isDirectory()){
        treeItem.setGraphic(new ImageView(icon));
        }else{
            treeItem.setGraphic(new ImageView(image));
        }
        if (f != null) {            
            File[] files = f.listFiles();
                ObservableList<TreeItem<File>> children = FXCollections
                        .observableArrayList();
                for (File childFile : files) {
                    if(childFile.isDirectory()){
                    FileSeeker fs = new FileSeeker(childFile);
                    fs.setGraphic(new ImageView(icon));
                    children.add(fs);
                    } else {
                        FileSeeker fs = new FileSeeker(childFile);
                        System.out.println(image.equals(null));
                        fs.setGraphic(new ImageView(image));
                        children.add(fs);
                    }
            }
                return children;
        }
        return FXCollections.emptyObservableList();
    }
    private boolean isFirstChildren = true;
    private boolean isFirstLeaf = true;
    private boolean isLeaf;
}

Приложение

package Application;
import java.io.File;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeView;
import javafx.scene.effect.InnerShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
//Основное окно
public class FileManager extends Application {
    Image ico = new Image(getClass().getResourceAsStream("ImagesAndCss/gnome_text_x_generic.png"));
    FileSeeker fseek = new FileSeeker(new File("C:\\"));
    TreeView<File> treeview = new TreeView<File>(fseek);
    @Override
    public void start(final Stage primaryStage) throws Exception {
        String css = FileManager.class.getResource("ImagesAndCss/Main.css").toExternalForm();
        String icon = FileManager.class.getResource("ImagesAndCss/folder-documents-icon.png").toExternalForm();
        final Label warn = new Label("Выберите Каталог");
        Button addDirectory = new Button("Создать каталог (F7)");
        addDirectory.setId("AddDir");
        fseek.setExpanded(true);
        fseek.setGraphic(new ImageView(ico));
        BorderPane spane = new BorderPane();
        spane.setStyle("-fx-text-fill: white;-fx-background-color: #24011F;");
        HBox But = new HBox();
        Scene scene = new Scene(spane, 600, 600);
        scene.getStylesheets().add(css);
        Label root = new Label("C:\\");
        root.setStyle("-fx-text-fill: white;");
        warn.setStyle("-fx-text-fill: yellow;");
        reduceNames(treeview);
        addDirectory.setOnAction(new EventHandler<ActionEvent>() {  
            public void handle(ActionEvent event) {     
                try{
                File f = treeview.getSelectionModel().getSelectedItem().getValue();
                if(f == null || !f.isDirectory()){
                    warn.setText("Ошибка.Вы выбрали файл, а не Директорию");
                } else {
                    warn.setText("");
                final Stage addDirStage = new AddDirectory(primaryStage,f.getAbsolutePath() + "\\Новый Каталог");
                addDirStage.show();
                }
                }catch(NullPointerException e) {
                    warn.setText("Директория не выбрана!");
                }
            }
        });
        But.getChildren().addAll(addDirectory,warn);
        spane.setTop(root);
        spane.setCenter(treeview);
        spane.setBottom(But);
        madeShadow(treeview,50);
        madeShadow(But,2);
        primaryStage.setTitle("Файловый менеджер");
        primaryStage.setScene(scene);
        primaryStage.getIcons().add(new Image(icon));
        primaryStage.show();
    }

    //Обрезает имена файлов и каталогов
    public void reduceNames(TreeView<File> treeview) {
        treeview.setCellFactory(new Callback<TreeView<File>, TreeCell<File>>() {
            public TreeCell<File> call(TreeView<File> tv) {
                return new TreeCell<File>() {
                    @Override
                    protected void updateItem(File item, boolean empty) {
                        super.updateItem(item, empty);
                        setText((empty || item == null) ? "" : item.getName());
                    }
                };
            }
        });
    }
    //Дополнительное окно с добавлением каталога
    public class AddDirectory extends Stage {
        public AddDirectory(Stage parent,final String path) {
            initOwner(parent);
            initModality(Modality.WINDOW_MODAL);
            String iconAdd = FileManager.class.getResource("ImagesAndCss/kde_add_folder_to_archive.png").toExternalForm();
            BorderPane bpane = new BorderPane();
            bpane.setStyle("-fx-text-fill: white; -fx-background-color: #24011F; ");
            HBox buts = new HBox(5); 
            HBox addField = new HBox();
            Button add = new Button("Создать");
            Button cancel = new Button("Отмена");
            add.setStyle("-fx-color: green;");
            cancel.setStyle("-fx-color: red;");

            Label pathl = new Label("Путь Каталога: ");
            pathl.setStyle("-fx-text-fill: white");
            final TextField enterpath = new TextField(path);
            enterpath.setMinWidth(400);
            enterpath.setMaxWidth(600);
            buts.getChildren().addAll(add,cancel);
            addField.getChildren().addAll(pathl,enterpath);
            bpane.setBottom(buts);
            bpane.setCenter(addField);

            add.setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent event) {
                    File f = new File(enterpath.getText());
                    System.out.println(enterpath.getText());
                    if(!f.exists()){
                        f.mkdir();
                        close();
                    }
                }
            });
            cancel.setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent event) {
                    close();    
                }
            });
            Scene scene = new Scene(bpane, 500, 100);
            setResizable(false);
            setScene(scene);
            getIcons().add(new Image(iconAdd));
            setTitle("Добавить каталог");
        }
    }
    //Эффект внутренней тени
    public void madeShadow(Node node, double res){
        InnerShadow insh = new InnerShadow(res, Color.BLACK);   
        node.setEffect(insh);
    }
    public static void main(String [] args){
        launch(args);
    }
}

Css

.tree-cell:hover .highlight-on-hover {
    -fx-text-fill: red ;
}
.tree-cell  {
    -fx-background-color: "#24011F";
     -fx-text-fill: white ;
}
#AddDir {
    -fx-color: green;
}
#Warning {
    -fx-color: red;
}

.MainTheme {
    -fx-background-color: "#24011F";
     -fx-text-fill: white ;
}

Было

public void reduceNames(TreeView<File> treeview) {
        treeview.setCellFactory(new Callback<TreeView<File>, TreeCell<File>>() {

            public TreeCell<File> call(TreeView<File> tv) {
                return new TreeCell<File>() {
                    @Override
                    protected void updateItem(File item, boolean empty) {
                        super.updateItem(item, empty);
                        setText((empty || item == null) ? "" : item.getName());
                    }
                };
            }
        });
    }

Стало

      public void reduceNames(TreeView<File> treeview) {
                treeview.setCellFactory(new Callback<TreeView<File>, TreeCell<File>>() {

                    public TreeCell<File> call(TreeView<File> tv) {
                        return new TreeCell<File>() {
                            @Override
                            protected void updateItem(File item, boolean empty) {
                                super.updateItem(item, empty);
                                setText((empty || item == null) ? "" : item.getName());
                           this.setGraphic(this.getTreeItem().getGraphic());
                            }
                        };
                    }
                });
            }
Answer 1

Ваша проблема заключается в том, что при отрисовке ( т.е. когда у вас идет вызов setCellFactory) вы проставляете только текст setText() и поэтому иконки у вас не рисуются.

Возможные варианты решения проблемы.

  1. Не проставляйте свою фактори. ( просто удалите вызов метода reduceNames(treeView))
  2. В фактори вызывать еще метод this.setGraphic(this.getTreeItem().getGraphic()), в которую вы будете передавать иконку.

    @Override
    protected void updateItem(File item, boolean empty) {
        super.updateItem(item, empty);
        // этой строки не было
        setGraphic((empty || item == null) ? null : this.getTreeItem().getGraphic());
        setText((empty || item == null) ? "" : item.getName());
    }
    
READ ALSO
checkout всех веток через интерфейс Idea

checkout всех веток через интерфейс Idea

Добрый день, коллегиВопрос следующего характера: имеется многомодульный Java-проект

262
Отображение полей в связе многие ко многим в Hibernate

Отображение полей в связе многие ко многим в Hibernate

У меня есть сущности "событие" и "участник"Связь многие-ко-многим

246
Подскажите что поправить в коде задачи про массивы

Подскажите что поправить в коде задачи про массивы

Дана задача - Cоздать двумерный массив из 7 строк по 4 столбца в каждой из случайных целых чисел из отрезка [-5;5]Вывести массив на экран

173
проблемы с кодировкой в swing

проблемы с кодировкой в swing

есть JTextPane и JEditorPaneв первом установлен контекст text/html, во втором - просто текст для написания html кода

222