путь к файлу элемента дерева javafx

у меня есть вопрос для этого примера кода.

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class CopyOfTreeViewSample extends Application {
    public static Image folderCollapseImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/folder.png"));
    public static Image folderExpandImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/folder-open.png"));
    public static Image fileImage=new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/text-x-generic.png"));
    public static Image rootImage = new Image(ClassLoader.getSystemResourceAsStream("treeviewsample/computer.png"));
    private TreeView treeView;
      public static void main(String[] args) {
            launch(args);
      }
  @Override
  public void start(Stage stage) {
    Scene scene = new Scene(new Group());
    stage.setTitle("Sample");
    stage.setWidth(300);
    stage.setHeight(500);

    VBox vbox = new VBox();
    vbox.setLayoutX(20);
    vbox.setLayoutY(20);

    TreeItem<String> root = new SimpleFileTreeItem(Paths.get("C:\\Users\\Jake"), true);
    treeView = new TreeView<String>(root);

    Button b = new Button("Change");
    b.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent arg0) {
            // TODO Auto-generated method stub
                     ////// How do i this section write code?//////            
     }

    });
    vbox.getChildren().addAll(treeView,b);
    vbox.setSpacing(10);
    ((Group) scene.getRoot()).getChildren().add(vbox);

    stage.setScene(scene);
    stage.show();
  }

  public class SimpleFileTreeItem extends TreeItem<String> {

    private boolean isRoot = false;
    private boolean isFirstTimeChildren = true;
    private boolean isFirstTimeLeaf = true;
    private boolean isLeaf;
    private boolean isDirectory;
    public boolean isDirectory(){return(this.isDirectory);}
    private String fullPath;
    public String getFullPath(){return(this.fullPath);}
    public SimpleFileTreeItem(Path f, Boolean flag) {
        super(f.toString());
        fullPath = f.toString();
        isRoot = flag;
        if(!isRoot)
        {
            if(Files.isDirectory(f))
            {
                isDirectory = true;
                this.setGraphic(new ImageView(folderCollapseImage));
            }
            else
            {
                isDirectory = false;
                this.setGraphic(new ImageView(fileImage));
            }
            //set the value
            if(!fullPath.endsWith(File.separator)){
                String value=f.toString();
                int indexOf=value.lastIndexOf(File.separator);
                if(indexOf>0){
                    this.setValue(value.substring(indexOf+1));
                }else{
                    this.setValue(value);
                }
            }
            this.addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler(){
                @Override
                public void handle(Event e){
                    SimpleFileTreeItem source=(SimpleFileTreeItem)e.getSource();
                    if(source.isDirectory()&&source.isExpanded()){
                        ImageView iv=(ImageView)source.getGraphic();
                        iv.setImage(folderExpandImage);

                    }
                }   
            });

            this.addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler(){
                @Override
                public void handle(Event e){
                    SimpleFileTreeItem source=(SimpleFileTreeItem)e.getSource();
                    if(source.isDirectory()&&!source.isExpanded()){
                        ImageView iv=(ImageView)source.getGraphic();
                        iv.setImage(folderCollapseImage);
                    }
                }
            });
        }
        else
        {
            this.setExpanded(true);
            if(Files.isDirectory(f))
            {
                isDirectory = true;
                this.setGraphic(new ImageView(rootImage));
            }
            else
            {
                isDirectory = false;
                this.setGraphic(new ImageView(fileImage));
            }
        }   
    }

    @Override
    public ObservableList<TreeItem<String>> getChildren() {
        if (isFirstTimeChildren) {
            isFirstTimeChildren = false;

            /*
             * First getChildren() call, so we actually go off and determine the
             * children of the File contained in this TreeItem.
             */
            super.getChildren().setAll(buildChildren(this));
        }
        return super.getChildren();
    }

    @Override
    public boolean isLeaf() {
        if (isFirstTimeLeaf) {
            isFirstTimeLeaf = false;
            File f = new File(fullPath);
            isLeaf = f.isFile();
        }
        return isLeaf;
    }

    /**
     * Returning a collection of type ObservableList containing TreeItems, which
     * represent all children available in handed TreeItem.
     * 
     * @param TreeItem
     *            the root node from which children a collection of TreeItem
     *            should be created.
     * @return an ObservableList<TreeItem<File>> containing TreeItems, which
     *         represent all children available in handed TreeItem. If the
     *         handed TreeItem is a leaf, an empty list is returned.
     */
    private ObservableList<TreeItem<String>> buildChildren(TreeItem<String> TreeItem) {
        File f = new File(fullPath);
        if (f != null && f.isDirectory()) {
            File[] files = f.listFiles();
            if (files != null) {
                ObservableList<TreeItem<String>> children = FXCollections
                        .observableArrayList();

                for (File childFile : files) {
                    children.add(new SimpleFileTreeItem(childFile.toPath(), false));
                }
                return children;
            }
        }

        return FXCollections.emptyObservableList();
    }   
}

Я хочу выбрать файл, соответствующий пути при нажатии кнопки.

мой путь к проекту eclipse - c:\java\samplecode.

Я пытался решить, используя Absolutepath, результат c:\java\samplecode\samplefile.txt

я хочу этот путь (c:\Users\jake\samplefile.txt)

Спасибо за советы и подсказки.


person jake    schedule 13.02.2015    source источник


Ответы (1)


Используя имеющиеся у вас настройки, вы сможете сделать

b.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        SimpleFileTreeItem<String> selectedItem = (SimpleFileTreeItem)treeView.getSelectionModel().getSelectedItem();
        if (selectedItem != null) {
            String pathString = selectedItem.getFullPath();

        }
    }
});

(Если вы также делаете

b.disableProperty().bind(
    Bindings.isNull(treeView.getSelectionModel().selectedItemProperty()));

то можно смело пропускать проверку на null в обработчике.)

Я думаю, что лучше было бы сделать SimpleFileTreeItem TreeItem<Path>. Затем вы просто сохраняете Path в качестве значения элемента дерева и можете использовать фабрику ячеек, чтобы просто отобразить имя файла.

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

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class CopyOfTreeViewSample extends Application {

    private TreeView<Path> treeView;

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

    @Override
    public void start(Stage stage) {
        stage.setTitle("Sample");
        stage.setWidth(300);
        stage.setHeight(500);

        VBox vbox = new VBox();
        vbox.setPadding(new Insets(20));

        TreeItem<Path> root = new SimpleFileTreeItem(
                Paths.get(System.getProperty("user.home")));
        root.setExpanded(true);
        treeView = new TreeView<Path>(root);

        treeView.setCellFactory(treeView -> new TreeCell<Path>() {
            @Override
            public void updateItem(Path path, boolean empty) {
                super.updateItem(path, empty);
                if (empty) {
                    setText(null);
                } else {
                    setText(path.getFileName().toString());
                }
            }
        });

        Button b = new Button("Change");
        b.disableProperty().bind(Bindings.isNull(treeView.getSelectionModel().selectedItemProperty()));

        b.setOnAction(event ->  {
            Path selectedPath = treeView.getSelectionModel().getSelectedItem().getValue() ;
            // do something with selectedPath...
            System.out.println(selectedPath);
        });

        vbox.getChildren().addAll(treeView, b);
        vbox.setSpacing(10);

        Scene scene = new Scene(vbox);

        stage.setScene(scene);
        stage.show();
    }

    public class SimpleFileTreeItem extends TreeItem<Path> {

        private boolean isFirstTimeChildren = true;
        private boolean isFirstTimeLeaf = true;
        private boolean isLeaf;

        public boolean isDirectory() {
            return Files.isDirectory(getValue());
        }


        public SimpleFileTreeItem(Path f) {
            super(f);
        }

        @Override
        public ObservableList<TreeItem<Path>> getChildren() {
            if (isFirstTimeChildren) {
                isFirstTimeChildren = false;

                /*
                 * First getChildren() call, so we actually go off and determine
                 * the children of the File contained in this TreeItem.
                 */
                super.getChildren().setAll(buildChildren());
            }
            return super.getChildren();
        }

        @Override
        public boolean isLeaf() {
            if (isFirstTimeLeaf) {
                isFirstTimeLeaf = false;
                isLeaf = Files.exists(getValue()) && ! Files.isDirectory(getValue());
            }
            return isLeaf;
        }

        /**
         * Returning a collection of type ObservableList containing TreeItems,
         * which represent all children of this TreeITem.
         * 
         * 
         * @return an ObservableList<TreeItem<File>> containing TreeItems, which
         *         represent all children available in this TreeItem. If the
         *         handed TreeItem is a leaf, an empty list is returned.
         */
        private ObservableList<TreeItem<Path>> buildChildren() {
            if (Files.isDirectory(getValue())) {
                try {

                    return Files.list(getValue())
                            .map(SimpleFileTreeItem::new)
                            .collect(Collectors.toCollection(() -> FXCollections.observableArrayList()));

                } catch (IOException e) {
                    e.printStackTrace();
                    return FXCollections.emptyObservableList();
                } 
            }

            return FXCollections.emptyObservableList();
        }
    }
}
person James_D    schedule 13.02.2015
comment
спасибо ... Я видел этот источник в документации Oracle, в Интернете, и я изучил treeviewitem. Я знаю, что файл выбран, мне нужен полный путь к выбранному файлу. - person jake; 13.02.2015
comment
Ах хорошо. Вы просто сохраняете имя файла в качестве значения и помещаете полный путь в другую переменную. Вы можете просто получить доступ к методу getFullPath. Смотрите обновленный ответ. Я, вероятно, не рекомендовал бы этот подход, гораздо лучше сохранить правильный тип (Path или, в худшем случае, File) в модели. - person James_D; 13.02.2015