2017-07-18 138 views
0

我有一个TreeView它看起来像这样 enter image description hereJavaFX的:我的根节点不能正常工作[再次]

让假设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个矩形。但我的第一个节点什么也没有显示那就是问题所在。

[注:以前我问过这个问题,但没有得到任何答复。以前我多次编辑这个问题,我没有太多的声誉把奖金(因为我是新的堆栈溢出)]

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

谢谢

+0

你的问题是不是5分钟,我会玩它,让你知道... –

回答

1

穆斯塔法,为您的问题我有这种变体的解决方案。

首先,而不是字符串作为树项目的主要值类型让我们处理特定的值对象。基于这些对象,您将能够从任意节点向下走树,并递归地收集所有矩形。

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

这是我创建了一些根和儿童和选定的顶端根看所有子矩形的例子: enter image description here

欢迎您了解我的版本以了解发生了什么变化。请注意,这是草稿版本,可根据您的需求进行改进。 欢迎您提出任何问题。

+0

非常感谢你。我很沮丧,没有得到任何结果。我被困在这一点上。大家指出明显的错误,但没有解决办法。非常感谢。你在这里救了我 – Mustafa

+0

是的,我有2个问题。首先为什么将'String'定义为'Label',它用在MyNode类中的'MyRootNode'和'MyCoordinateNode'中。第二什么是'curTreeItem'?它是'treeItem'吗? – Mustafa

+1

1)Label as String用作每个树节点的标签。它仅在updateItem()方法中用于正确渲染树节点。2)curTreeItem,treeItem只是一个名字来显示它是当前的树节点。 –

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())); 
     } 
+0

首先非常感谢你的回应。是的,我知道,但问题是如何得到4,5,6,7作为第一的孩子,他们也应该保持为2或3的孩子 – Mustafa

+0

代码应该像上面的图片一样工作,用户可以添加尽可能多的根和坐标,他想要和所有的矩形应该显示在主根和子根上。 – Mustafa