【问题标题】:JavaFx: Adding TreeItem in TreeView againJavaFx:再次在 TreeView 中添加 TreeItem
【发布时间】:2017-06-19 09:31:33
【问题描述】:

TreeView 必须添加 TreeItems。这是我的代码:

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;
    } 

}

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

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

如何将项目添加到树中?

【问题讨论】:

    标签: javafx


    【解决方案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());
                    hbox.getChildren().add(newRectangle);
                }
            }
                   
            root1.setLeft(hbox);
            return root1;
        } 
    }
    

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

    【讨论】:

    • 如您所知,在我的代码中,我使用Ux and Uy 矩形在根分支中水平显示,并且新添加的Uy's 矩形也应该添加到那里。
    • @kleopatra,这是在 2017 年完成的。我想我是在 2016 年才开始使用JavaFX。我真的需要回去重构很多我的旧代码。其他地方可能有更多这种类型的垃圾。谢谢你指出这一点。
    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多