JavaFX TreeTableView 标记子行为红色。

huangapple go评论69阅读模式
英文:

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 - 是treeTableView的“第一层”(TreeItem: apples, plums)。
                // 如何深入到第二层以访问apples、plums的子项 -
                // 在那里我可以检查水果的颜色并标记treeTable行为红色??
                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);
    }
}

请注意,我已经将代码中的HTML实体(如<和")更改为Java代码。

英文:

I have problem with marking color of treeTableView row. Marking "first level" row is no problem and the code functions. Under updateItem method -> item, I can access first row fruit properties.

JavaFX TreeTableView 标记子行为红色。

But I dont know how to access deeper in "second level" of treeTableView and color the rows?

JavaFX TreeTableView 标记子行为红色。

Below is my code.
Thanks in advance for any help.

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&lt;Fruit&gt; treeTableView;
ArrayList&lt;Fruit&gt; fruitsList = new ArrayList&lt;&gt;(Arrays.asList(
new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;green&quot;), new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;red&quot;),
new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;yellow&quot;), new Fruit(&quot;Plum&quot;, &quot;round&quot;, &quot;yellow&quot;),
new Fruit(&quot;Plum&quot;, &quot;round&quot;, &quot;navy blue&quot;), new Fruit(&quot;Plum&quot;, &quot;oval&quot;, &quot;red&quot;)));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
}
public void buttonMarkFruits(){
treeTableView.setRowFactory(ttv -&gt; new TreeTableRow&lt;Fruit&gt;(){
@Override
protected void updateItem(Fruit item, boolean empty) {
super.updateItem(item, empty);
//Fruit item - is here &quot;first level&quot; 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(&quot;red&quot;)){
setStyle(&quot;-fx-background-color: tomato;&quot;);
} else {
setStyle(null);
}
}
});
}
public void createTreeTable(){
TreeTableColumn&lt;Fruit, String&gt; colName = new TreeTableColumn&lt;&gt;(&quot;Fruit&quot;);
TreeTableColumn&lt;Fruit, String&gt; colShape = new TreeTableColumn&lt;&gt;(&quot;Shape&quot;);
TreeTableColumn&lt;Fruit, String&gt; colColor = new TreeTableColumn&lt;&gt;(&quot;Color&quot;);
colName.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;name&quot;));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;shape&quot;));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;color&quot;));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem root = new TreeItem(new Fruit(&quot;&quot;, &quot;&quot;, &quot;&quot;));
TreeItem apples = new TreeItem(new Fruit(&quot;Apple&quot;, &quot;&quot;, &quot;&quot;));
TreeItem plums = new TreeItem(new Fruit(&quot;Plum&quot;, &quot;&quot;, &quot;&quot;));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals(&quot;Apple&quot;)){
apples.getChildren().add(new TreeItem&lt;&gt;(new Fruit(&quot;&quot;, fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals(&quot;Plum&quot;)){
plums.getChildren().add(new TreeItem&lt;&gt;(new Fruit(&quot;&quot;, fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}

答案1

得分: 3

问题不在于行不在树的“第一级”,而是在按钮按下时未调用表格行的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);
    }
}
英文:

The problem is not that the rows are not in the "first level" of the tree; it's that the table row's updateItem() method is not called when the button is pressed.

The basic idea is to have some kind of observable property that the rows observe, so that they update the styles as needed. Use that row implementation whether or not the button is pressed (so set the row factory in the initialize() method), and just update the property when the button is pressed. A minimal implementation of this will look like:

public class ControllerWindowTest implements Initializable {
@FXML
private TreeTableView&lt;Fruit&gt; treeTableView;
private BooleanProperty redFruitsMarked = new SimpleBooleanProperty(false);
ArrayList&lt;Fruit&gt; fruitsList = new ArrayList&lt;&gt;(Arrays.asList(
new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;green&quot;), new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;red&quot;),
new Fruit(&quot;Apple&quot;, &quot;round&quot;, &quot;yellow&quot;), new Fruit(&quot;Plum&quot;, &quot;round&quot;, &quot;yellow&quot;),
new Fruit(&quot;Plum&quot;, &quot;round&quot;, &quot;navy blue&quot;), new Fruit(&quot;Plum&quot;, &quot;oval&quot;, &quot;red&quot;)));
@Override
public void initialize(URL location, ResourceBundle resources) {
createTreeTable();
fillTreeTable();
treeTableView.setRowFactory(ttv -&gt; new TreeTableRow&lt;Fruit&gt;(){
{
redFruitsMarked.addListener((obs, wereMarked, areNowMarked) -&gt; 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(&quot;red&quot;)){
setStyle(&quot;-fx-background-color: tomato;&quot;);
} else {
setStyle(null);
}
}
});
}
@FXML
private void buttonMarkWires(){
redFruitsMarked.set(true);
}
public void createTreeTable(){
TreeTableColumn&lt;Fruit, String&gt; colName = new TreeTableColumn&lt;&gt;(&quot;Fruit&quot;);
TreeTableColumn&lt;Fruit, String&gt; colShape = new TreeTableColumn&lt;&gt;(&quot;Shape&quot;);
TreeTableColumn&lt;Fruit, String&gt; colColor = new TreeTableColumn&lt;&gt;(&quot;Color&quot;);
colName.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;name&quot;));
colShape.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;shape&quot;));
colColor.setCellValueFactory(new TreeItemPropertyValueFactory&lt;&gt;(&quot;color&quot;));
treeTableView.getColumns().addAll(colName, colShape, colColor);
}
public void fillTreeTable(){
TreeItem&lt;Fruit&gt; root = new TreeItem&lt;&gt;(new Fruit(&quot;&quot;, &quot;&quot;, &quot;&quot;));
TreeItem&lt;Fruit&gt; apples = new TreeItem&lt;&gt;(new Fruit(&quot;Apple&quot;, &quot;&quot;, &quot;&quot;));
TreeItem&lt;Fruit&gt; plums = new TreeItem&lt;&gt;(new Fruit(&quot;Plum&quot;, &quot;&quot;, &quot;&quot;));
for (Fruit fruit: fruitsList){
if (fruit.getName().equals(&quot;Apple&quot;)){
apples.getChildren().add(new TreeItem&lt;&gt;(new Fruit(&quot;&quot;, fruit.getShape(), fruit.getColor())));
}
if (fruit.getName().equals(&quot;Plum&quot;)){
plums.getChildren().add(new TreeItem&lt;&gt;(new Fruit(&quot;&quot;, fruit.getShape(), fruit.getColor())));
}
}
root.getChildren().addAll(apples,plums);
root.setExpanded(true);
treeTableView.setRoot(root);
treeTableView.setShowRoot(false);
}
}

huangapple
  • 本文由 发表于 2020年8月7日 17:26:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63298947.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定