2017-07-18 122 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