Javafx:我的Root节点没有正常工作[再次]

时间:2017-07-18 10:34:21

标签: javafx treeview

我有一个看起来像这样的树视图 enter image description here

假设1,2,3被称为根,4,5,6,7被称为坐标。每个坐标生成2个矩形,在根上水平显示。这是代码

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
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 java.util.HashMap;
import java.util.Map;

public class Main extends Application {

    private static int rootNr = 0;
    private static int coordinateNr = 0;

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

    static final Map<TreeItem<String>, BorderPane> map = new HashMap<>();

    @Override
    public void start(Stage primaryStage) {
        BorderPane root = new BorderPane();
        TreeItem<String> tree = new TreeItem<>("Main System");
        TreeItem<String> item1 = new TreeItem<>("Roots");
        TreeView<String> treeView = new TreeView<>(tree);
        treeView.setOnMouseClicked((event) -> {
            TreeItem<String> treeItem = treeView.getSelectionModel().getSelectedItem();
            if (treeItem.getChildren().stream().anyMatch(child -> child.getValue().startsWith("C"))) {
                    root.setCenter(getRootsPanel(treeItem.getValue()));
            }else {
                    root.setCenter(map.get(treeItem));
            }
        });

        treeView.setCellFactory(p -> new AddMenuTreeCell());
        tree.setExpanded(true);
        root.setLeft(treeView);
        tree.getChildren().add(item1);

        Scene scene = new Scene(root, 700, 500);
        primaryStage.setTitle("Tree View");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class AddMenuTreeCell extends TextFieldTreeCell<String> {
        private ContextMenu menu = new ContextMenu();
        private TextField textField;
        public AddMenuTreeCell() {
            MenuItem newitem1 = new MenuItem("Insert Roots");
            MenuItem newitem2 = new MenuItem("Insert Coordinates");
            menu.getItems().addAll(newitem1, newitem2);
            newitem1.setOnAction(arg0 -> {
                TreeItem<String> item3 = new TreeItem<>("Root" + rootNr++);
                getTreeItem().getChildren().add(item3);
            });
            newitem2.setOnAction(arg0 -> {
                TreeItem<String> newLeaf = new TreeItem<>("Coordinates" + coordinateNr++);
                TreeItem<String> uxItem1 = new TreeItem<>("X");
                map.put(uxItem1, getrightPane1());
                TreeItem<String> uyItem1 = new TreeItem<>("y");
                map.put(uyItem1, getrightPane1());
                newLeaf.getChildren().add(uxItem1);
                newLeaf.getChildren().add(uyItem1);
                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()) {
                    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(event -> {
            if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
               Rectangle rect1 = new Rectangle();
                rect1.setHeight(Double.parseDouble(textf1.getText()));
                rect1.setWidth(Double.parseDouble(textf2.getText()));
                rect1.setFill(null);
                rect1.setStroke(Color.BLUE);
                root1.setCenter(rect1);
            }
        });
        textf2.setPrefWidth(100);
        textf2.setPromptText("Enter Width");
        textf2.setOnKeyReleased(event -> {
            if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
                Rectangle rect2 = new Rectangle();
                rect2.setHeight(Double.parseDouble(textf1.getText()));
                rect2.setWidth(Double.parseDouble(textf2.getText()));
                rect2.setFill(null);
                rect2.setStroke(Color.RED);
                root1.setCenter(rect2);
            }
        });

        if (textf1.getText().length() > 0 && textf2.getText().length() > 0 && root1.getCenter() == 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.setCenter(rect);
        }

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

    private static BorderPane getRootsPanel(String root) {
        BorderPane root2 = new BorderPane();
        HBox hbox = new HBox(10);
        hbox.setPadding(new Insets(40));
        hbox.setAlignment(Pos.TOP_CENTER);

        for (Map.Entry<TreeItem<String>, BorderPane> entry : map.entrySet()) {
            if (entry.getKey().getParent().getParent().getValue().equals(root)) {
                Rectangle rect1 = (Rectangle) entry.getValue().getCenter();
                if (rect1 != null) {
                    Rectangle rect2 = new Rectangle();
                    rect2.setWidth(rect1.getWidth());
                    rect2.setHeight(rect1.getHeight());
                    rect2.setFill(rect1.getFill());
                    rect2.setStroke(rect1.getStroke());
                    Platform.runLater(() -> hbox.getChildren().addAll(rect2));
                }
            }
        }

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

使用此代码,用户可以使图中显示的树。 2和3(称为根节点)将显示4个矩形,因为每个内部有2个坐标,第1个节点应该水平显示8个矩形。但我的第一个节点什么都没显示这就是问题。

[注意:我之前问过这个问题,但没有得到任何回复。以前我多次编辑这个问题而且我没有多少声誉可以放置赏金(因为我是堆叠溢出的新手)]

我在这个问题上需要帮助。

谢谢

2 个答案:

答案 0 :(得分:2)

我检查了你的代码,我发现了一些东西。

在我看来,当您选择第一个节点时,treeItem.getChildren()方法只有2个子节点。 这意味着4,5,6和7不是第一个节点的子节点。他们是2或3岁的孩子。

因此,当您选择第一个节点时,代码中的下方不起作用。

if (treeItem.getChildren().stream().anyMatch(child -> child.getValue().startsWith("C"))) {
                root.setCenter(getRootsPanel(treeItem.getValue()));
        }

答案 1 :(得分:1)

穆斯塔法,对于你的问题,我有这种解决方案。

首先,而不是String作为树项的主要值类型,让我们使用特定的值对象。基于这些对象,您将能够从任何节点向下遍历树并以递归方式收集所有矩形。

import javafx.scene.Node;

abstract class MyNode {
    private final String label;
    private Node rectangle;

    MyNode(String label) {
        this.label = label;
    }

    String getLabel() {
        return label;
    }

    Node getRectangle() {
        return rectangle;
    }

    void setRectangle(Node rectangle) {
        this.rectangle = rectangle;
    }
}

class MyRootNode extends MyNode {
    MyRootNode(String label) {
        super(label);
    }
}

class MyCoordinateNode extends MyNode {
    MyCoordinateNode(String label) {
        super(label);
    }
}

主要课程相应地重做了

public class MyMain extends Application {
    private static int rootNr = 0;
    private static int coordinateNr = 0;

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

    private static final Map<TreeItem<MyNode>, BorderPane> map = new HashMap<>();

    @Override
    public void start(Stage primaryStage) {
        BorderPane root = new BorderPane();

        TreeItem<MyNode> mainTree = new TreeItem<>(new MyRootNode("Main System"));
        mainTree.setExpanded(true);

        TreeView<MyNode> treeView = new TreeView<>(mainTree);
        treeView.setCellFactory(p -> new AddMenuTreeCell());
        treeView.setOnMouseClicked((event) -> {
            final TreeItem<MyNode> treeItem = treeView.getSelectionModel().getSelectedItem();
            if (treeItem.getValue() instanceof MyRootNode) {
                root.setCenter(getRootsPanel(treeItem));
            } else {
                root.setCenter(map.get(treeItem));
            }
        });

        root.setLeft(treeView);

        Scene scene = new Scene(root, 700, 700);
        primaryStage.setTitle("Tree View");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

        AddMenuTreeCell() {
            MenuItem newitem1 = new MenuItem("Insert Root");
            MenuItem newitem2 = new MenuItem("Insert Coordinates");
            menu.getItems().addAll(newitem1, newitem2);
            newitem1.setOnAction(arg0 -> {
                TreeItem<MyNode> item = new TreeItem<>(new MyRootNode("Root" + rootNr++));
                getTreeItem().getChildren().add(item);
            });
            newitem2.setOnAction(arg0 -> {
                TreeItem<MyNode> uxItem1 = new TreeItem<>(new MyCoordinateNode("X"));
                map.put(uxItem1, getRightPane(uxItem1));

                TreeItem<MyNode> uyItem1 = new TreeItem<>(new MyCoordinateNode("Y"));
                map.put(uyItem1, getRightPane(uyItem1));

                TreeItem<MyNode> newLeaf = new TreeItem<>(new MyRootNode("Coordinates" + coordinateNr++));
                newLeaf.getChildren().add(uxItem1);
                newLeaf.getChildren().add(uyItem1);
                getTreeItem().getChildren().add(newLeaf);
            });
        }

        @Override
        public void updateItem(MyNode item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (!isEditing()) {
                    setText(item.getLabel());
                    setGraphic(getTreeItem().getGraphic());
                    if (item instanceof MyRootNode) {
                        setContextMenu(menu);
                    }
                }
            }
        }
    }

    private static BorderPane getRightPane(final TreeItem<MyNode> curTreeItem) {
        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(event -> {
            if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
                Rectangle rect = getRectangle(textf1, textf2, Color.BLUE);
                root1.setCenter(rect);
                curTreeItem.getValue().setRectangle(rect);
            }
        });
        textf2.setPrefWidth(100);
        textf2.setPromptText("Enter Width");
        textf2.setOnKeyReleased(event -> {
            if (textf1.getText().length() > 0 && textf2.getText().length() > 0) {
                Rectangle rect = getRectangle(textf1, textf2, Color.RED);
                root1.setCenter(rect);
                curTreeItem.getValue().setRectangle(rect);
            }
        });

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

    private static Rectangle getRectangle(TextField textf1, TextField textf2, final Color blue) {
        Rectangle rect = new Rectangle();
        rect.setHeight(Double.parseDouble(textf1.getText()));
        rect.setWidth(Double.parseDouble(textf2.getText()));
        rect.setFill(null);
        rect.setStroke(blue);

        return rect;
    }

    private static BorderPane getRootsPanel(final TreeItem<MyNode> treeItem) {
        BorderPane root = new BorderPane();
        HBox hbox = new HBox(10);
        hbox.setPadding(new Insets(40));
        hbox.setAlignment(Pos.TOP_CENTER);

        final List<MyNode> coordinateNodes = getCoordinateNodes(treeItem);
        for (final MyNode coordinateNode : coordinateNodes) {
            if (coordinateNode.getRectangle() != null) {
                Platform.runLater(() -> hbox.getChildren().addAll(coordinateNode.getRectangle()));
            }
        }

        Platform.runLater(() -> root.setLeft(hbox));

        return root;
    }

    private static List<MyNode> getCoordinateNodes(final TreeItem<MyNode> treeItem) {
        final List<MyNode> result = new ArrayList<>();

        if (treeItem.getValue() instanceof MyRootNode) {
            for (final TreeItem<MyNode> child : treeItem.getChildren()) {
                result.addAll(getCoordinateNodes(child));
            }
        } else {
            result.add(treeItem.getValue());
        }

        return result;
    }
}

这是我创建一些根和子项并选择顶部根以查看所有子矩形的示例: https://codepen.io/nolaandy/pen/awgoQM

欢迎您了解我的版本以了解更改内容。请注意,这是草稿变体,可根据您的需要进行改进。 如有任何问题,欢迎您。