How to Save/Load editable Fall tree in javafx?

 ̄綄美尐妖づ 提交于 2021-01-28 05:03:15

问题


i have a editable fall tree which i want to save and load here is my code

public class Muddassir extends Application 
    {

        private BorderPane root;
        TreeView<String> tree;
        TreeItem<String> module,unite,translateA ,translateB,rotate;
        @Override
        public void start(Stage primaryStage) throws Exception
        {    
            root = new BorderPane();        
            root.setLeft(getLeftHBox());
            root.setTop(getTop());

            Scene scene = new Scene(root, 900, 500);        
            primaryStage.setTitle("BorderPane");
            primaryStage.setScene(scene);
            primaryStage.show();    
        }

        private VBox getLeftHBox()
        {
            TreeItem<String> rootnode = new TreeItem<String>("Library");
            rootnode.setExpanded(true);
            module = makeBranch("module",rootnode);
            makeBranch("Parameter X",module);
            unite = makeBranch("unite",module);
            makeBranch("Parameter uX",unite);
            translateA = makeBranch("translateA",unite);
            makeBranch("Parameter taX",translateA);
            translateB = makeBranch("translateB",unite);
            makeBranch("Parameter tbX",translateB);
            rotate = makeBranch("rotate",translateB);
            makeBranch("Parameter RX",rotate);
            tree= new TreeView<>(rootnode);
            tree.setEditable(true);
            tree.setCellFactory(TextFieldTreeCell.forTreeView());



            VBox vbox =new VBox(10);
            vbox.setPadding(new Insets(5));
            Text text= new Text("Fall tree");
            text.setFont(Font.font("I", FontWeight.BOLD,16)); 
            vbox.getChildren().addAll(text,tree);
            return vbox;
        }

        private TreeItem<String> makeBranch(String title, TreeItem<String> parent) {
            TreeItem<String>item = new TreeItem<>(title);
            item.setExpanded(true);
            parent.getChildren().add(item);
            return item;

        }       

         private Parent getTop() {
             TextField fieldName = new TextField();
              Button btSave = new Button("Save");
               btSave.setOnAction(event -> {
                   SaveData data = new SaveData();
                  // data.name = ((TreeView<String>) tree).getText();
                   data.name = fieldName.getText();
                   try {
                     Function.save(data, "Javafx.save");
                    }
                    catch (Exception e) {
                      e.printStackTrace();
                   }
                });


               Button btLoad = new Button("Load");
                btLoad.setOnAction(event -> {
                   try {
                      SaveData data = (SaveData) Function.load("Javafx.save");      
                     //((TreeItems<String>)tree).setText(data.name);
                     fieldName.setText(data.name);
                    }
                    catch (Exception e) {
                     e.printStackTrace();
                  }
              });

                HBox hb= new HBox(5,fieldName,btSave,btLoad);
                hb.setPadding(new Insets(5));
            return hb;
        }

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

And Function class is

import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.nio.file.Files;
    import java.nio.file.Paths;

    public class Function {
           public static void save(Serializable data, String fileName) throws Exception {
                try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(Paths.get(fileName)))) {
                    oos.writeObject(data);
                }
            }
            public static Object load(String fileName) throws Exception {
                try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Paths.get(fileName)))) {
                    return ois.readObject();
                }
            }
        } 

And SaveData Class is

import javafx.scene.control.TreeView;

    public class SaveData implements java.io.Serializable{
        private static final long serialVersionUID = 1L;

        public String name;

    }

I wanted to edit the Tree and make changes, save that changes and after next execution, i should have that changed result. Since i don't know much about database so i came up with this method to save changes in a file and load that file.

Problem is that i can save and load text in textfield but i cannot save and load changes in tree.

I want to save changes in tree and load these changes on my next execution. I tried but failed. Any hint will be fine Please.

Thank you.


回答1:


You can play with this app I just created. It can hopefully help you come up with a better solution. This app only handles two deep(see below) or less trees. You can make it recursive to make it handle any depth. The recursive algorithm that is used to save the tree can save a tree of any depth. The non-recursive loadTree method can only handle a depth of two.

-root depth-0
    -child 1 depth-1
           -child 1a depth-2
    -child 2 depth-1
    -child 3 depth-1
           -child 3a depth-2


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication94 extends Application
{


    @Override
    public void start(Stage primaryStage)
    {
        TreeItem<String> treeRoot = new TreeItem("Node 0");
        TreeItem<String> item1 = new TreeItem("Node 1");
        TreeItem<String> item1Child = new TreeItem("Node 1a");
        item1.getChildren().add(item1Child);
        TreeItem<String> item2 = new TreeItem("Node 2");
        TreeItem<String> item2Child = new TreeItem("Node 2a");
        item2.getChildren().add(item2Child);
        TreeItem<String> item3 = new TreeItem("Node 3");



        treeRoot.setExpanded(true);
        treeRoot.getChildren().addAll(item1, item2, item3);
        TreeView<String> treeView = new TreeView(treeRoot);
        treeView.setEditable(true);
        treeView.setCellFactory(TextFieldTreeCell.forTreeView());

        Button btn = new Button("Save TreeView");
        btn.setOnAction(new EventHandler<ActionEvent>()
        {            
            @Override
            public void handle(ActionEvent event)
            {
                //If the file exist delete it and save new info
                File file = new File("tree_structure.txt");
                if(file.exists()) {
                   file.delete();     
                }
                saveParentAndChildren(treeRoot, "root");
            }
        });

        Button btn2 = new Button("Load TreeView");
        btn2.setOnAction(new EventHandler<ActionEvent>()
        {            
            @Override
            public void handle(ActionEvent event)
            {        
               //Load the tree structure into the old treeView
               treeView.setRoot(loadTree());
            }
        });

        StackPane root = new StackPane();
        VBox vbox = new VBox();
        vbox.getChildren().add(treeView);
        vbox.getChildren().add(btn);
        vbox.getChildren().add(btn2);
        root.getChildren().add(vbox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

    static private void saveParentAndChildren(TreeItem<String> root, String parent){
        System.out.println("Current Parent :" + root.getValue());
        try(PrintWriter writer = new PrintWriter(new FileOutputStream(new File("tree_structure.txt"),true /* append = true */))){
            writer.println(root.getValue() + "=" + parent);

            for(TreeItem<String> child: root.getChildren()){
                if(child.getChildren().isEmpty()){
                    writer.println(child.getValue() + "=" + root.getValue());
                } else {
                    saveParentAndChildren(child, root.getValue());
                }
            }
        }
        catch (FileNotFoundException ex) {
            Logger.getLogger(JavaFXApplication94.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    static private TreeItem loadTree(){
        TreeItem root = null;
        HashMap<String, String> treeStructure = new HashMap();

        File file = new File("tree_structure.txt");
        try(BufferedReader br = new BufferedReader(new FileReader(file)))
        {
            String st;
            while((st=br.readLine()) != null){
                String[] splitLine = st.split("=");
                treeStructure.put(splitLine[0], splitLine[1]);
            }

            root = getChildrenNodes(treeStructure, "root").get(0);//This gets the root node
            List<TreeItem> parentItems = getChildrenNodes(treeStructure, root.getValue().toString());//get the root's children
            //if the root has children get every child's children if they have some.
            if(parentItems.size() > 0)
            {                
                root.getChildren().addAll(parentItems);
                for(TreeItem item : parentItems)
                {
                    item.getChildren().addAll(getChildrenNodes(treeStructure, item.getValue().toString()));
                }
            }            
        }
        catch (IOException ex) {
            Logger.getLogger(JavaFXApplication94.class.getName()).log(Level.SEVERE, null, ex);
        }

        return root;
    }   

    static private List<TreeItem> getChildrenNodes(HashMap<String, String> hMap, String parent)
    {
        List<TreeItem> children = new ArrayList();

        for (Map.Entry<String, String> entry : hMap.entrySet())
        {

            if(entry.getValue().equals(parent))
            {
                System.out.println(entry.getKey() + "/" + entry.getValue());
                children.add(new TreeItem(entry.getKey()));
            }
        }

        return children;
    }


}


来源:https://stackoverflow.com/questions/43679701/how-to-save-load-editable-fall-tree-in-javafx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!