Есть ли способ привязать поле объекта к TreeItem, чтобы при изменении поля TreeItem автоматически обновлялось в TreeView?У меня есть объекты с несколькими полями, которые установлены в TreeItems в TreeView.Поля объектов обновляются иногда с 5 до 10 раз в секунду через их установщики, и я хотел бы, чтобы TreeItems обновлялись на лету при изменении полей.Любая помощь по этому вопросу будет принята с благодарностью.Кажется, я не могу найти способ сделать это, кроме как перезагрузить весь TreeView.
Редактировать: вот существующий код ... Прослушиватель списка устанавливает древовидное представление для списка проигрывателя.Если количество объектов в списке изменяется, дерево перерисовывается.Это все хорошо.Я хочу, чтобы, если бы вы поместили код в метод нажатия кнопки дескриптора, который непрерывно изменяет атрибуты игрока (в цикле, может быть, 2-10 раз в секунду), это должно отражаться в древовидном представлении при изменении этих атрибутов (простосимуляция, я не могу понять, как эти атрибуты действительно меняются с такой скоростью).Пример того, как это сделать, был бы великолепен.
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import viewcontroller.PlayerViewController;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
private Stage mainStage;
@FXML
private AnchorPane mainView;
@Override
public void start(Stage mainStage) {
this.mainStage = mainStage;
PlayerList.playerListListener();
this.showMainLayout();
}
/**
* shows the main screen
*/
public void showMainLayout() {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("/viewcontroller/playerView.fxml"));
try {
mainView = (AnchorPane) loader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Scene scene = new Scene(mainView);
mainStage.sizeToScene();
mainStage.setScene(scene);
mainStage.show();
PlayerViewController controller = loader.getController();
controller.setMainApp(this);
}
public static void main(String[] args) {
launch(args);
}
}
package model;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Player {
private StringProperty str1 = new SimpleStringProperty();
private StringProperty str2 = new SimpleStringProperty();
private StringProperty str3 = new SimpleStringProperty();
public Player() {
}
public Player(String str1, String str2, String str3) {
super();
this.str1 = new SimpleStringProperty(str1);
this.str2 = new SimpleStringProperty(str2);
this.str3 = new SimpleStringProperty(str3);
}
public StringProperty str1() {
return str1;
}
public String getStr1() {
return str1.get();
}
public void setStr1(String str1) {
this.str1.set(str1);
}
public StringProperty str2() {
return str2;
}
public String getStr2() {
return str2.get();
}
public void setStr2(String str2) {
this.str2.set(str2);
}
public StringProperty str3() {
return str3;
}
public String getStr3() {
return str3.get();
}
public void setStr3(String str3) {
this.str3.set(str3);
}
}
package application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import model.Player;
public class PlayerList {
private final ObservableList<Player> playerList = FXCollections.observableArrayList();
private static PlayerList instance = new PlayerList();
public static TreeItem<String> rootNode = new TreeItem<String>("Root");
private PlayerList() {}
public ObservableList<Player> getPlayerList() {
return playerList;
}
public static PlayerList getInstance() {
return instance;
}
public static void playerListListener() {
//adds a list listener which reloads tree if objects are added or removed
PlayerList.getInstance().getPlayerList().addListener((ListChangeListener<? super Player>) new ListChangeListener<Player>() {
@SuppressWarnings("unchecked")
public void onChanged(Change<? extends Player> change) {
//re-sort list
//System.out.println("List changed");
rootNode.getChildren().clear();//clear tree before reloading on list change
for(Player p: PlayerList.getInstance().getPlayerList()) {
//Parent Node
TreeItem<String> playerName = new TreeItem<String>(p.getStr1());
//Items
TreeItem<String> attr1 = new TreeItem<String>(p.getStr2());
TreeItem<String> attr2 = new TreeItem<String>(p.getStr3());
playerName.getChildren().addAll(attr1, attr2);
playerName.setExpanded(true);
rootNode.getChildren().add(playerName);
rootNode.setExpanded(true);
}
}
});
}
}
package viewcontroller;
import java.net.URL;
import java.util.ResourceBundle;
import application.Main;
import application.PlayerList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import model.Player;
public class PlayerViewController implements Initializable {
@FXML
private VBox vbox;
private TreeView<String> treeView;
public void setMainApp(Main main) {
// TODO Auto-generated method stub
}
@Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
Player p1 = new Player("Name1", "Attr1", "Attr2");
Player p2 = new Player("Name2", "Attr1", "Attr2");
Player p3 = new Player("Name3", "Attr1", "Attr2");
PlayerList.getInstance().getPlayerList().addAll(p1, p2, p3);//add players to list
treeView = new TreeView<String>(PlayerList.rootNode);
treeView.setShowRoot(false);
vbox.getChildren().add(treeView);//add tree view to GUI
}
@FXML
private void handleButtonClick() {
/*this method can hold code that would run in a loop, continuously setting new values
on p1, p2, and p3 attributes and would show the tree items updating automatically*/
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="mainView" prefHeight="400.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="viewcontroller.PlayerViewController">
<children>
<VBox fx:id="vbox" layoutX="14.0" layoutY="14.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button mnemonicParsing="false" onAction="#handleButtonClick" text="Button" />
</children>
</VBox>
</children>
</AnchorPane>