JavaFX TreeView选择(TreeItem<;Object>;)未按预期工作
过去我在这个论坛上读到了很多提示和技巧。 现在我试着问我的第一个问题:——) 我对JavaFX有点陌生,但对Java并不陌生。我正在尝试将一个应用程序从Swing移植到JavaFX,这样它将更加新奇和可定制 这个程序的主要任务是显示两棵树并比较它们。 为了更方便,我在旧的应用程序中实现了一个侦听器和celleditor来可视化差异,当您在一个树中选择一个项目时,它会尝试在另一个树中找到相应的项目。如果它不可见,它将可见 显示当前应用程序的一个屏幕截图: 开始后,它看起来像这样 在左侧选择时,在右侧自动选择,反之亦然: 现在,我尝试在JavaFX中实现相同的功能: 但使用此代码:JavaFX TreeView选择(TreeItem<;Object>;)未按预期工作,java,javafx,treeview,Java,Javafx,Treeview,过去我在这个论坛上读到了很多提示和技巧。 现在我试着问我的第一个问题:——) 我对JavaFX有点陌生,但对Java并不陌生。我正在尝试将一个应用程序从Swing移植到JavaFX,这样它将更加新奇和可定制 这个程序的主要任务是显示两棵树并比较它们。 为了更方便,我在旧的应用程序中实现了一个侦听器和celleditor来可视化差异,当您在一个树中选择一个项目时,它会尝试在另一个树中找到相应的项目。如果它不可见,它将可见 显示当前应用程序的一个屏幕截图: 开始后,它看起来像这样 在左侧选择时,在右
public void setOtherTree(TreeView<CompareNode> otherTree) {
if (log.isTraceEnabled()) {
log.trace("setOtherTree("+otherTree+")");
}
this.otherTree = otherTree;
tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
tree.getSelectionModel().selectedItemProperty().addListener((observable,oldValue,newValue) -> selectInOtherTree(newValue));
}
public void selectInOtherTree(TreeItem<CompareNode> newValue) {
if (log.isDebugEnabled()) {
log.debug(logPrefix + " " + String.format("selectInOtherTree:newValue".replaceAll(", ", "=%s, ") + "=%s", newValue));
}
otherTree.getSelectionModel().clearSelection();
otherTree.getSelectionModel().select(newValue);
}
public void setOtherTree(TreeView otherTree){
if(log.isTraceEnabled()){
trace(“setOtherTree(“+otherTree+”);
}
this.otherTree=otherTree;
tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
tree.getSelectionModel().SelectEditeProperty().addListener((可观察、旧值、新值)->selectInOtherTree(新值));
}
public void选择其他树(TreeItem newValue){
if(log.isDebugEnabled()){
log.debug(logPrefix+“”+String.format(“selectInOtherTree:newValue.replaceAll”(“,”,“=%s,”)+“=%s”,newValue));
}
otherTree.getSelectionModel().clearSelection();
otherTree.getSelectionModel().select(newValue);
}
它总是在索引基础上选择项目:
我是遗漏了什么还是JDK1.8u45(我目前正在使用)中的一个bug
类CompareNode覆盖toString、equals和hash
正如我所看到的,我需要10个声誉来发布图片:-(,所以我希望我的话能足够详细地解释它,或者你可以点击链接。对此感到抱歉。
非常感谢您的帮助
问候
安德烈亚斯
2015-07-10更新:
显示旧应用程序的两个屏幕截图:
以及新应用程序的屏幕截图:
感谢您的好评:-)
2015-09-22更新
同时,我创建了一个小的演示应用程序来演示它
TreeItemString.java
package application;
import javafx.scene.control.TreeItem;
public class TreeItemString extends TreeItem<String> {
public TreeItemString(String value) {
this.setValue(value);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
return this.getValue().equals(((TreeItemString) obj).getValu());
}
@Override
public String toString() {
return this.getValue();
}
@Override
public int hashCode() {
return this.getValue().hashCode();
}
}
包应用;
导入javafx.scene.control.TreeItem;
公共类TreeItemString扩展TreeItem{
public TreeItemString(字符串值){
这个.setValue(值);
}
@凌驾
公共布尔等于(对象obj){
if(obj==null){
返回false;
}
返回此.getValue().equals(((TreeItemString)obj.getValu());
}
@凌驾
公共字符串toString(){
返回这个.getValue();
}
@凌驾
public int hashCode(){
返回此.getValue().hashCode();
}
}
MainApp.java
package application;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
public void selectInOtherTree(TreeItem<String> toSelect, TreeView otherTree, TreeView thisTree) {
System.out.println("Othertree : " + toSelect);
System.out.println("Me : " + thisTree.getRow(toSelect));
System.out.println("Other: " + otherTree.getRow(toSelect));
otherTree.getSelectionModel().select(toSelect);
}
public TreeItemString newRoot(TreeView<String> tree, Label label, String labelPrefix) {
//Create TreeItems for the Hierarchy of the TreeView
TreeItemString royalRoot = new TreeItemString("Queen Elizabeth - Prince Philip");
TreeItemString Charlie = new TreeItemString("Prince Charles - Princess Diana");
TreeItemString Annie = new TreeItemString("Princess Anne - Mark Phillips");
TreeItemString Andy = new TreeItemString("Prince Andrew - Sarah Ferguson");
TreeItemString Eddie = new TreeItemString("Prince Edward - Sophie");
//Populate the TreeItem to be used as the root with the other TreeItems
royalRoot.getChildren().addAll(Charlie, Annie, Andy, Eddie);
//Populate the other TreeItems with more TreeItems
//to build the family tree
Charlie.getChildren().addAll(
new TreeItemString("Prince William"),
new TreeItemString("Prince Henry"));
Annie.getChildren().addAll(
new TreeItemString("Peter Phillips"),
new TreeItemString("Zara Phillips"));
Andy.getChildren().addAll(
new TreeItemString("Princess Beatrice"),
new TreeItemString("Princess Eugenie"));
Eddie.getChildren().addAll(
new TreeItemString("Lady Louise"),
new TreeItemString("Viscount Severn"));
return royalRoot;
}
@Override
public void start(Stage primaryStage) {
final String leftTreeLabelPrefix= "Selected Tree Item From left Tree: \n";
final String rightTreeLabelPrefix = "Selected Tree Item From right Tree: \n";
//Use HBOX and VBOX layout panes to space out the controls
//in a single row
HBox treeBox = new HBox();
VBox labelBox = new VBox(30);
HBox controlBox = new HBox(10);
//Create labels to highlight the selected items from the TreeViews
final Label leftTreeLabel = new Label(leftTreeLabelPrefix);
final Label rightTreeLabel = new Label(rightTreeLabelPrefix);
//Create and empty TreeView
TreeView<String> leftTree = new TreeView<String>();
//Use the setRoot method to set the root TreeItem
// duckTree.setRoot(duckRoot);
leftTree.setRoot(newRoot(leftTree,leftTreeLabel, "Selected Tree Item From left Tree: \n"));
//Create a TreeView using the root TreeItem
TreeView<String> rightTree = new TreeView<String>();
rightTree.setRoot(newRoot(rightTree,rightTreeLabel, "Selected Tree Item From right Tree: \n"));
rightTree.getSelectionModel().selectedItemProperty().addListener((observable,oldValue,newValue) -> selectInOtherTree(newValue, leftTree, rightTree));
leftTree.getSelectionModel().selectedItemProperty().addListener((observable,oldValue,newValue) -> selectInOtherTree(newValue, rightTree,leftTree));
//Add the TreeViews to the HBox
treeBox.getChildren().add(leftTree);
treeBox.getChildren().add(rightTree);
//Add the labels to the VBox
labelBox.getChildren().add(leftTreeLabel);
labelBox.getChildren().add(rightTreeLabel);
//Add the HBox and VBox to another HBox to
//position the layout panes
controlBox.getChildren().add(treeBox);
controlBox.getChildren().add(labelBox);
//Add the main HBOX layout pane to the scene
Scene scene = new Scene(controlBox, 800, 250);
Platform.setImplicitExit(false);
Thread backGroundThread = new Thread(() -> {
try {
Thread.sleep(5000);
System.out.println("Select left Viscount Severn");
leftTree.getRoot().setExpanded(true);
leftTree.getRoot().getChildren().get(1).setExpanded(true);
leftTree.getRoot().getChildren().get(2).setExpanded(true);
leftTree.getRoot().getChildren().get(3).setExpanded(true);
TreeItemString toSearch = new TreeItemString("Prince Edward - Sophie");
System.out.println("true:false for : " + toSearch);
System.out.println("true:false : " + leftTree.getRoot().getChildren().contains(toSearch));
System.out.println("indexOf: " + leftTree.getRoot().getChildren().indexOf(toSearch));
System.out.println("get: " + leftTree.getRoot().getChildren().get(leftTree.getRoot().getChildren().indexOf(toSearch)));
System.out.println("getRow: " + leftTree.getRow(leftTree.getRoot().getChildren().get(leftTree.getRoot().getChildren().indexOf(toSearch))));
leftTree.getSelectionModel().select(new TreeItemString("Princess Anne - Mark Phillips"));
Thread.sleep(5000);
System.out.println("Select right Princess Beatrice");
rightTree.getSelectionModel().select(new TreeItemString("Princess Beatrice"));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
backGroundThread.setDaemon(true);
backGroundThread.start();
//Show the form
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
包应用;
导入javafx.application.application;
导入javafx.application.Platform;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类主扩展应用程序{
public void选择其他树(TreeItem to select,TreeView otherTree,TreeView this tree){
System.out.println(“其他树:+toSelect”);
System.out.println(“Me:+thisTree.getRow(toSelect));
System.out.println(“其他:+otherTree.getRow(toSelect));
otherTree.getSelectionModel().select(toSelect);
}
public TreeItemString newRoot(树视图树、标签标签、字符串标签前缀){
//为树视图的层次结构创建树项
TreeItemString royalRoot=新的TreeItemString(“伊丽莎白女王-菲利普亲王”);
TreeItemString查理=新的TreeItemString(“查尔斯王子-戴安娜王妃”);
TreeItemString Annie=新的TreeItemString(“安妮公主-马克·菲利普斯”);
TreeItemString Andy=新的TreeItemString(“安德鲁王子-莎拉·弗格森”);
TreeItemString Eddie=新的TreeItemString(“爱德华王子-索菲”);
//将要用作根的TreeItem与其他TreeItem一起填充
royalRoot.getChildren().addAll(查理、安妮、安迪、埃迪);
//用更多树项填充其他树项
//建立家谱
Charlie.getChildren().addAll(
新的TreeItemString(“威廉王子”),
新的TreeItemString(“亨利王子”);
Annie.getChildren().addAll(
新的TreeItemString(“Peter Phillips”),
新的TreeItemString(“Zara Phillips”);
Andy.getChildren().addAll(
新的TreeItemString(“比阿特丽斯公主”),
新的TreeItemString(“尤金妮公主”);
Eddie.getChildren().addAll(
新的TreeItemString(“Louise女士”),
新的TreeItemString(“塞文子爵”);
返回根;
}
@凌驾
公共无效开始(阶段初始阶段){
最后一个字符串leftTreeLabelPrefix=“从左树中选择的树项:\n”;
最后一个字符串rightTreeLabelPrefix=“从右树中选择的树项:\n”;
//使用HBOX和VBOX布局窗格隔开控件
//一排
HBox treeBox=新的HBox();
VBox labelBox=新的VBox(30);
HBox控制盒=新的HBox(10);
//创建标签以高亮显示树视图中的选定项目
最终标签leftTreeLabel=新标签(leftTreeLabel前缀);
最终标签rightTreeLabel=新标签(rightTreeLabel前缀);
//创建并清空TreeView
TreeView leftTree=new TreeView();
//使用setRoot m