JavaFx:再次在TreeView中添加TreeItem

时间:2017-06-19 09:31:33

标签: javafx

我在[1]之前问了这个问题:JavaFx: Adding treeItem in Treeview但没有得到任何回应。

我需要帮助解决这个问题。

用户需要添加树项的树视图。

这是我的代码

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Callback;

public class Main extends Application
{

    private BorderPane border;
    @SuppressWarnings("unchecked")
    @Override
    public void start(Stage primaryStage)
    {   
        border = new BorderPane();    
        Scene scene = new Scene(border,600,300); 
        primaryStage.setTitle("BorderPane");
        primaryStage.setScene(scene);
        primaryStage.show();

        TreeItem<String> tree = new TreeItem<String>("Main System"); 
        TreeItem<String> item2 = new TreeItem<String>("Roots");
        TreeItem<String> item2Child1 = new TreeItem<String>("UX");
        TreeItem<String> item2Child2 = new TreeItem<String>("UY");
        item2.getChildren().addAll(item2Child1,item2Child2);        
        item2.setExpanded(true);    

        tree.setExpanded(true);
        tree.getChildren().add(item2);
        TreeView<String> treeView  = new TreeView<String>(tree);       

        treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
            @Override
            public TreeCell<String> call(TreeView<String> p) {
                return new AddMenuTreeCell();
            }
        });


        VBox box3 = new VBox();
        treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem>() {

            @Override
            public void changed(ObservableValue<? extends TreeItem> observable, TreeItem oldValue, TreeItem newValue) {
                if (newValue.getValue().equals(item2Child1.getValue())) {
                    box3.getChildren().add(getrightPane1());
                } else {
                    int i = box3.getChildren().size();
                    if (i > 0) {
                        box3.getChildren().remove(0);
                    }
                }
            }
        });

        VBox box4 = new VBox();
        treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem>() {

            @Override
            public void changed(ObservableValue<? extends TreeItem> observable, TreeItem oldValue, TreeItem newValue) {
                if (newValue.getValue().equals(item2Child2.getValue())) {
                    box4.getChildren().add(getrightPane2());
                } else {
                    int i = box4.getChildren().size();
                    if (i > 0) {
                        box4.getChildren().remove(0);
                    }
                }
            }
        });

        VBox box2 = new VBox();
        treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem>() {

            @Override
            public void changed(ObservableValue<? extends TreeItem> observable, TreeItem oldValue, TreeItem newValue) {
                if (newValue.getValue().equals(item2.getValue())) {
                    box2.getChildren().add(getrightPane3());
                } else {
                    int i = box2.getChildren().size();
                    if (i > 0) {
                        box2.getChildren().remove(0);
                    }
                }
            }
        });

        HBox hb = new HBox(); 
        hb.getChildren().addAll(treeView,box2,box3,box4);        
        border.setCenter(hb);
    }

    private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
        private ContextMenu menu = new ContextMenu();     
        private TextField textField;

        public AddMenuTreeCell() {
            MenuItem newitem1 = new MenuItem("Insert leaf");
            menu.getItems().add(newitem1);

            newitem1.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent arg0) {

                    TreeItem<String> newLeaf =  new TreeItem<String>("UY" );
                                getTreeItem().getChildren().add(newLeaf);
                }
            });
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(getTreeItem().getGraphic());
                    if (!(getTreeItem().isLeaf() && getTreeItem().getParent() == null)){
                        setContextMenu(menu);
                    }
                }           
            }
        }        
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    }

    TextField textf1 = new TextField();
    TextField textf2 = new TextField();
    BorderPane root1 = new BorderPane();    
    private BorderPane getrightPane1() {            
        VBox vbox = new VBox(20);
        vbox.setPadding(new Insets(10));        
        HBox h1 = new HBox(7);
        HBox h2 = new HBox(7); 
        textf1.setPrefWidth(100);
        textf1.setPromptText("Enter Height");   
        textf1.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {  
                if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf1.getText()));
                    rect.setWidth(Double.parseDouble(textf2.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.RED);
                    root1.setBottom(rect);
                }
            }
        });
        textf2.setPrefWidth(100);
        textf2.setPromptText("Enter Width");
        textf2.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {
                if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf1.getText()));
                    rect.setWidth(Double.parseDouble(textf2.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.RED);
                    root1.setBottom(rect);
                }
            }
        });
        h1.getChildren().addAll(new Label("Y1:"), textf1);
        h2.getChildren().addAll(new Label("X1:"), textf2);
        vbox.getChildren().addAll(h1, h2);
        root1.setLeft(vbox);
        return root1;
    }

    TextField textf3 = new TextField();
    TextField textf4 = new TextField();
    BorderPane root2 = new BorderPane();    
    private BorderPane getrightPane2() {        
        VBox vbox = new VBox(20);
        vbox.setPadding(new Insets(10));

        HBox h1 = new HBox(7);
        HBox h2 = new HBox(7);
        textf3.setPrefWidth(100);
        textf3.setPromptText("Enter Height");
        textf3.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {  
                if(textf3.getText().length() > 0 && textf4.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf3.getText()));
                    rect.setWidth(Double.parseDouble(textf4.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.BLUE);
                    root2.setBottom(rect);
                }
            }
        });

        textf4.setPrefWidth(100);
        textf4.setPromptText("Enter Width");
        textf4.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {
                if(textf3.getText().length() > 0 && textf4.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf3.getText()));
                    rect.setWidth(Double.parseDouble(textf4.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.BLUE);
                    root2.setBottom(rect);
                }
            }
        });

        h1.getChildren().addAll(new Label("Y2:"), textf3);
        h2.getChildren().addAll(new Label("X2:"), textf4);
        vbox.getChildren().addAll(h1, h2);
        root2.setLeft(vbox);
        return root2;
    }

    private HBox getrightPane3() {

        HBox hbox = new HBox(20);
        hbox.setAlignment(Pos.BOTTOM_CENTER);
        hbox.setPadding(new Insets(50));

        HBox hbox1 = new HBox();
        Rectangle rect1 = new Rectangle();

        if (!textf1.getText().equals("") && !textf2.getText().equals("")) {            
            rect1.setHeight(Double.parseDouble(textf1.getText()));
            rect1.setWidth(Double.parseDouble(textf2.getText()));
            rect1.setFill(null);
            rect1.setStroke(Color.RED);
            hbox1.getChildren().addAll(rect1);
        } 

        HBox hbox2 = new HBox();
         Rectangle rect2 = new Rectangle();

        if (!textf3.getText().equals("") && !textf4.getText().equals("")) {
            rect2.setHeight(Double.parseDouble(textf3.getText()));
            rect2.setWidth(Double.parseDouble(textf4.getText()));
            rect2.setFill(null);
            rect2.setStroke(Color.BLUE);
            hbox2.getChildren().addAll(rect2);
        } 

        hbox.getChildren().addAll(hbox1,hbox2); 
        return hbox;
    } 

}

Root有2个叶子Ux, Uy,两者都包含构建矩形的逻辑,并且矩形在根中水平显示。现在问题是用户需要添加另一个叶子名称Uy并且应该具有相同的Rectangle构建逻辑,并且这些新构建的矩形应该自动显示在root中。

我尝试添加另一个Uy,但这不起作用。

我该怎么办?

请知道吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

我稍微更改了你的代码。问题是您尝试多次向场景添加节点。在这个例子中,我创建了一个与TreeView和与之关联的BorderPane保持同步的地图。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication124 extends Application
{
    //List<BorderPane> rightPanels = new ArrayList();
   static final Map<TreeItem<String>, BorderPane> MAP = new HashMap();
   static BorderPane root;

    @Override
    public void start(Stage primaryStage)
    {        


        TreeItem<String> treeRoot = new TreeItem("Main System");  
        root = new BorderPane();

        TreeView treeView = new TreeView(treeRoot); 
        treeView.setOnMouseClicked((event)->{
            TreeItem tempTreeItem = (TreeItem)treeView.getSelectionModel().getSelectedItem(); 
                if(tempTreeItem.getValue().equals("Main System"))
                {
                    root.setCenter(getRootsPanel());
                    //System.out.println(getRootsPanel());
                }
                else
                {
                    root.setCenter(MAP.get(tempTreeItem));
                    System.out.println(MAP.get(tempTreeItem));
                }


        });

        treeView.setCellFactory(new Callback<TreeView<String>,TreeCell<String>>(){
            @Override
            public TreeCell<String> call(TreeView<String> p) {
                return new AddMenuTreeCell();
            }
        });        
        treeRoot.setExpanded(true);

        root.setLeft(treeView);

        TreeItem<String> uxItem1 = new TreeItem("UX");
        MAP.put(uxItem1, getrightPane1());
        TreeItem<String> uyItem1 = new TreeItem("UY");
        MAP.put(uyItem1, getrightPane1());
        treeRoot.getChildren().addAll(uxItem1, uyItem1);

        Scene scene = new Scene(root, 500, 500);



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

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


    TreeItem<String> addNewTreeItem(String name)
    {
        TreeItem tempTreeItem = new TreeItem(name);

        return tempTreeItem;
    }


    private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
        private final ContextMenu menu = new ContextMenu();     
        private TextField textField;

        public AddMenuTreeCell() {
            MenuItem newitem1 = new MenuItem("Insert leaf");
            menu.getItems().add(newitem1);

            newitem1.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent arg0) {
                    TreeItem<String> newLeaf =  new TreeItem("UY");                    
                    getTreeItem().getChildren().add(newLeaf);
                    MAP.put(newLeaf, getrightPane1());
                }
            });
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(item);
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(item);
                    setGraphic(getTreeItem().getGraphic());
                    if (!(getTreeItem().isLeaf() && getTreeItem().getParent() == null)){
                        setContextMenu(menu);
                    }
                }           
            }
        }  
    }

    private static BorderPane getrightPane1() {              
        TextField textf1 = new TextField();
        TextField textf2 = new TextField();
        BorderPane root1 = new BorderPane(); 

        VBox vbox = new VBox(20);
        vbox.setPadding(new Insets(10));        
        HBox h1 = new HBox(7);
        HBox h2 = new HBox(7); 

        textf1.setPrefWidth(100);
        textf1.setPromptText("Enter Height");   
        textf1.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {  
                if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf1.getText()));
                    rect.setWidth(Double.parseDouble(textf2.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.RED);
                    root1.setBottom(rect);
                }
            }
        });
        textf2.setPrefWidth(100);
        textf2.setPromptText("Enter Width");
        textf2.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event)
            {
                if(textf1.getText().length() > 0 && textf2.getText().length() > 0)
                {
                    Rectangle rect = new Rectangle();
                    rect.setHeight(Double.parseDouble(textf1.getText()));
                    rect.setWidth(Double.parseDouble(textf2.getText()));
                    rect.setFill(null);
                    rect.setStroke(Color.RED);
                    root1.setBottom(rect);
                }
            }
        });

        if(textf1.getText().length() > 0 && textf2.getText().length() > 0 && root1.getBottom() == null)
        {
            Rectangle rect = new Rectangle();
            rect.setHeight(Double.parseDouble(textf1.getText()));
            rect.setWidth(Double.parseDouble(textf2.getText()));
            rect.setFill(null);
            rect.setStroke(Color.RED);
            root1.setBottom(rect);
        }

        h1.getChildren().addAll(new Label("Y1:"), textf1);
        h2.getChildren().addAll(new Label("X1:"), textf2);
        vbox.getChildren().addAll(h1, h2);
        root1.setLeft(vbox);
        return root1;
    } 

    private static BorderPane getRootsPanel() { 
        BorderPane root1 = new BorderPane(); 
        HBox hbox = new HBox();

        List<BorderPane> listBordePane = new ArrayList(MAP.values());
        for(BorderPane element : listBordePane)
        {          
            Node node = element.getBottom();
            if(node instanceof Rectangle)
            {
                Rectangle tempRectangle = ((Rectangle)node);
                Rectangle newRectangle = new Rectangle();
                newRectangle.setWidth(tempRectangle.getWidth());
                newRectangle.setHeight(tempRectangle.getHeight());
                newRectangle.setFill(tempRectangle.getFill());
                newRectangle.setStroke(tempRectangle.getStroke());
                Platform.runLater(()->{hbox.getChildren().add(newRectangle);});
            }
        }

        Platform.runLater(()->{root1.setLeft(hbox);});
        return root1;
    } 
}
  

代码已更新!您需要捕获TextField java.lang.NumberFormatException!