javafx treeTableView 将子行标记为红色
javafx treeTableView mark children rows red
我在标记 treeTableView 行的颜色时遇到问题。标记“第一级”行没问题,代码功能正常。在 updateItem 方法 -> 项目下,我可以访问第一行水果属性。
但我不知道如何更深入地访问 treeTableView 的“第二级”并为行着色?
下面是我的代码。
在此先感谢您的帮助。
import javafx.fxml.Initializable;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ResourceBundle;
public class ControllerWindowTest implements Initializable {
public TreeTableView<Fruit> treeTableView;
ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
}
public void buttonMarkFruits(){
treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
@Override
protected void updateItem(Fruit item, boolean empty) {
super.updateItem(item, empty);
//Fruit item - is here "first level" of treeTableView(TreeItem: apples, plums).
// How to go deeper to second level to access children of apples, plums -
// where I can check color of fruit and mark treeTable row red??
if (item == null) {
setStyle(null);
} else if (item.getColor().equals("red")){
setStyle("-fx-background-color: tomato;");
} else {
setStyle(null);
}
}
});
}
public void createTreeTable(){
TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");
colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem root = new TreeItem(new Fruit("", "", ""));
TreeItem apples = new TreeItem(new Fruit("Apple", "", ""));
TreeItem plums = new TreeItem(new Fruit("Plum", "", ""));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals("Apple")){
apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals("Plum")){
plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}
问题不在于行不在树的“第一层”;这是 table 行的 updateItem()
方法在按下按钮时没有被调用。
基本思想是让行观察到某种可观察的 属性,以便它们根据需要更新样式。无论是否按下按钮,都使用该行实现(因此在 initialize()
方法中设置行工厂),并在按下按钮时更新 属性。一个最小的实现如下所示:
public class ControllerWindowTest implements Initializable {
@FXML
private TreeTableView<Fruit> treeTableView;
private BooleanProperty redFruitsMarked = new SimpleBooleanProperty(false);
ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
{
redFruitsMarked.addListener((obs, wereMarked, areNowMarked) -> updateStyles());
}
@Override
protected void updateItem(Fruit item, boolean empty) {
super.updateItem(item, empty);
updateStyles();
}
private void updateStyles() {
if (getItem() == null || (! redFruitsMarked.get())) {
setStyle(null);
} else if (getItem().getColor().equals("red")){
setStyle("-fx-background-color: tomato;");
} else {
setStyle(null);
}
}
});
}
@FXML
private void buttonMarkWires(){
redFruitsMarked.set(true);
}
public void createTreeTable(){
TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");
colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem<Fruit> root = new TreeItem<>(new Fruit("", "", ""));
TreeItem<Fruit> apples = new TreeItem<>(new Fruit("Apple", "", ""));
TreeItem<Fruit> plums = new TreeItem<>(new Fruit("Plum", "", ""));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals("Apple")){
apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals("Plum")){
plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}
我在标记 treeTableView 行的颜色时遇到问题。标记“第一级”行没问题,代码功能正常。在 updateItem 方法 -> 项目下,我可以访问第一行水果属性。
但我不知道如何更深入地访问 treeTableView 的“第二级”并为行着色?
下面是我的代码。 在此先感谢您的帮助。
import javafx.fxml.Initializable;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ResourceBundle;
public class ControllerWindowTest implements Initializable {
public TreeTableView<Fruit> treeTableView;
ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
}
public void buttonMarkFruits(){
treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
@Override
protected void updateItem(Fruit item, boolean empty) {
super.updateItem(item, empty);
//Fruit item - is here "first level" of treeTableView(TreeItem: apples, plums).
// How to go deeper to second level to access children of apples, plums -
// where I can check color of fruit and mark treeTable row red??
if (item == null) {
setStyle(null);
} else if (item.getColor().equals("red")){
setStyle("-fx-background-color: tomato;");
} else {
setStyle(null);
}
}
});
}
public void createTreeTable(){
TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");
colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem root = new TreeItem(new Fruit("", "", ""));
TreeItem apples = new TreeItem(new Fruit("Apple", "", ""));
TreeItem plums = new TreeItem(new Fruit("Plum", "", ""));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals("Apple")){
apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals("Plum")){
plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}
问题不在于行不在树的“第一层”;这是 table 行的 updateItem()
方法在按下按钮时没有被调用。
基本思想是让行观察到某种可观察的 属性,以便它们根据需要更新样式。无论是否按下按钮,都使用该行实现(因此在 initialize()
方法中设置行工厂),并在按下按钮时更新 属性。一个最小的实现如下所示:
public class ControllerWindowTest implements Initializable {
@FXML
private TreeTableView<Fruit> treeTableView;
private BooleanProperty redFruitsMarked = new SimpleBooleanProperty(false);
ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
{
redFruitsMarked.addListener((obs, wereMarked, areNowMarked) -> updateStyles());
}
@Override
protected void updateItem(Fruit item, boolean empty) {
super.updateItem(item, empty);
updateStyles();
}
private void updateStyles() {
if (getItem() == null || (! redFruitsMarked.get())) {
setStyle(null);
} else if (getItem().getColor().equals("red")){
setStyle("-fx-background-color: tomato;");
} else {
setStyle(null);
}
}
});
}
@FXML
private void buttonMarkWires(){
redFruitsMarked.set(true);
}
public void createTreeTable(){
TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");
colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem<Fruit> root = new TreeItem<>(new Fruit("", "", ""));
TreeItem<Fruit> apples = new TreeItem<>(new Fruit("Apple", "", ""));
TreeItem<Fruit> plums = new TreeItem<>(new Fruit("Plum", "", ""));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals("Apple")){
apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals("Plum")){
plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}