在一個非常廣泛使用TreeTableViews的應用程式中,我遇到了每次將子項添加到這棵樹時都需要觸發代碼的情況。
我的第一種方法是“封裝”myTree.getChildren().add(...)方法內部,例如:
public boolean addToChildren(TreeItemPlaylist tritPlaylist) {
boolean resAdd = false;
resAdd = getChildren().add(tritPlaylist);
[... personalized code which might affect the resAdd ...]
return resAdd;
}
這仍然getChildren().add(...)可以訪問,因此可以繞過我的個性化代碼。
我正在尋找更清潔的東西,并且試圖覆寫該TreeTableView 中的add(newNode)方法getChildren()。
我做了很多研究,最后試圖做:
- 一個平行的兒童串列。然后可以訪問
- 有它的 'add(...) 覆寫
- 而該名單由回傳
getChildren()的TreeItem
的 Overriden 部分的getChildren()靈感來自

取消評論同一部分。然后運行。然后按下按鈕 -->

表現形式1:樹
所以在這兩種情況下,我的第一個孩子串列都存在......它們在根樹專案下,但是:當通過自定義的 ObservableList 時,它們沒有顯示在樹中,在根下。
據我所知,TreeTableView 的機制依賴于對 TreeItem 串列的特定呼叫:子項,可能我在那里遺漏了一些東西......因為我做了一個并行的 LIST,因此它不被稱為......有點。 ..做了一些研究和實驗,但到目前為止沒有運氣:-(。
是不是因為:
- There is something missing on the TreeTableView : CellValueFactory / CellFactory / TreeItems / ...
- There is something wrong about my ObservableList : Another override I should implement / Wrong ascendant used / Should 'implement' and 'extend' rather than 'extend' ?
Manifestation 2 : Children / Parent
I have broken the children/parent ! This also has to do with the fact that I tried to build a parallel LIST and made a customized getChildren(). Should be a customization of super.getChildren() I suppose, but then again, tried many ways without success. And if so, I don't get my customnized LIST but the original (correct) one.
Help would be greatly appreciated.
MCE :
package overrides;
import javafx.application.Application;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CustomedTypedTreeTableSample extends Application {
public final class ObservableListOfTreeItemPlaylist<T> extends SimpleListProperty<T> {
ObservableListOfTreeItemPlaylist() {
super(FXCollections.observableArrayList());
}
@Override
public boolean add(T element) {
System.out.println("Adding an element");
return super.add(element);
}
}
public class TreeItemPlaylist extends TreeItem<TreeTableRowPlaylist> {
private ObservableListOfTreeItemPlaylist<TreeItem<TreeTableRowPlaylist>> playlistItems = new ObservableListOfTreeItemPlaylist<>();
public TreeItemPlaylist(TreeTableRowPlaylist treeTableRow) {
super(treeTableRow);
}
////////////////////////
// COMMENT / UNCOMMENT the next overridden method to see my problem
//
// When commenting : - GUI tree is filled with the correct children. All is fine... but, of course, no customized 'add(...'
// - When printing to console the children of root : All branches and children are there !
//
// When NOT commenting : - The overridden 'add(T element)' of class ObservableListOfTreeItemPlaylist is fired...
// - GUI tree is left with only the ROOT element
// - When printing to console only the first children of root are there ! But hey... they are there on the console, but not in the GUI !
@Override
public ObservableListOfTreeItemPlaylist<TreeItem<TreeTableRowPlaylist>> getChildren() {
return playlistItems;
}
////////////////////////
}
public class TreeTableRowPlaylist extends TreeTableRow<TreeTableRowPlaylist> {
// Initialized during constructor
private SimpleStringProperty name;
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public SimpleStringProperty nameProperty() {
return name;
}
public TreeTableRowPlaylist(String name) {
super();
this.name = new SimpleStringProperty(name);
}
}
@SuppressWarnings ("unchecked")
@Override
public void start(Stage primaryStage) {
///// TreeTableView basics
// Tree table view
TreeTableView<TreeTableRowPlaylist> tableView = new TreeTableView<>();
// Column for the name
TreeTableColumn<TreeTableRowPlaylist, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(param -> param.getValue().getValue().nameProperty());
// Add column
tableView.getColumns().addAll(nameColumn);
///// Dummy tree building
tableView.setRoot(new TreeItemPlaylist(new TreeTableRowPlaylist("ROOT")));
tableView.getRoot().getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf 1")));
tableView.getRoot().getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf 2")));
TreeItemPlaylist aTreeBranchA = new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Branch A"));
aTreeBranchA.getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf A.1")));
aTreeBranchA.getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf A.2")));
tableView.getRoot().getChildren().add(aTreeBranchA);
///// Testing if overriding is working
// button to get the list of children
Button display = new Button("Print out children list to console");
display.setOnAction(event -> tableView.getRoot().getChildren().forEach(playlist -> printChildrenToConsole(playlist)));
///// Setting the GUI
VBox vbox = new VBox(0, tableView, display);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}
private void printChildrenToConsole(TreeItem<TreeTableRowPlaylist> playlist) {
System.out.println(playlist.getValue().getName());
if (!playlist.isLeaf()) {
playlist.getChildren().forEach(childPlaylist -> printChildrenToConsole(childPlaylist));
}
}
public static void main(String[] args) {
launch(args);
}
}
uj5u.com熱心網友回復:
有時,最好只用鷹眼從頭開始重新啟動整個架構。在我的情況下,這導致了最好的答案之一......我希望......而且效果很好!
在這種情況下,覆寫的方法getChildren.add(...)是錯誤的方法。
正確的方向是關于事件,在這種情況下addEventHandler:
這是實施了解決方案的 MCE:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CustomedTypedTreeTableSample2 extends Application {
public class TreeTableRowPlaylist extends TreeTableRow<TreeTableRowPlaylist> {
// Initialized during constructor
private SimpleStringProperty name;
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public SimpleStringProperty nameProperty() {
return name;
}
public TreeTableRowPlaylist(String name) {
super();
this.name = new SimpleStringProperty(name);
}
}
private final class TreeItemPlaylist extends TreeItem<TreeTableRowPlaylist> {
// private boolean isFirstTimeChildren = true;
private TreeItemPlaylist(TreeTableRowPlaylist treeTableRowPlaylist) {
super(treeTableRowPlaylist);
addEventHandler(TreeItem.childrenModificationEvent(), this::childrenModification);
// Same code in a 'anonymous' implementation :
// addEventHandler(TreeItem.childrenModificationEvent(), new EventHandler<TreeModificationEvent<TreeTableRowPlaylist>>() {
// @Override
// public void handle(TreeModificationEvent<TreeTableRowPlaylist> event) {
// childrenModification(event);
// }
// });
}
private void childrenModification(TreeModificationEvent<TreeTableRowPlaylist> event) {
if (event.wasAdded()) {
for (TreeItem<TreeTableRowPlaylist> item : event.getAddedChildren()) {
System.out.println("Node " item.getValue().getName() " has been added.");
}
}
}
}
private void printChildrenToConsole(TreeItem<TreeTableRowPlaylist> playlist) {
System.out.println(playlist.getValue().getName());
if (!playlist.isLeaf()) {
playlist.getChildren().forEach(childPlaylist -> printChildrenToConsole(childPlaylist));
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
///// TreeTableView basics
// Tree table view
TreeTableView<TreeTableRowPlaylist> tableView = new TreeTableView<>();
// Column for the name
TreeTableColumn<TreeTableRowPlaylist, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(param -> param.getValue().getValue().nameProperty());
// Add column
tableView.getColumns().addAll(nameColumn);
///// Dummy tree building
tableView.setRoot(new TreeItemPlaylist(new TreeTableRowPlaylist("ROOT")));
tableView.getRoot().getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf 1")));
tableView.getRoot().getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf 2")));
TreeItemPlaylist aTreeBranchA = new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Branch A"));
aTreeBranchA.getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf A.1")));
aTreeBranchA.getChildren().add(new TreeItemPlaylist(new TreeTableRowPlaylist("Playlist Leaf A.2")));
tableView.getRoot().getChildren().add(aTreeBranchA);
///// Testing if overriding is working
// button to get the list of children
Button display = new Button("Print out children tree to console");
display.setOnAction(event -> tableView.getRoot().getChildren().forEach(playlist -> printChildrenToConsole(playlist)));
///// Setting the GUI
VBox vbox = new VBox(0, tableView, display);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/346223.html
標籤:inheritance javafx treeview overriding treetable
