Javafx:我如何引用setRowFactory中一行中的特定单元格? [英] Javafx: how do I reference a particular cell within a row in setRowFactory?

查看:150
本文介绍了Javafx:我如何引用setRowFactory中一行中的特定单元格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个tableView,其中每个表行代表一个对象,每列代表该对象的属性。在tableView中,我定义了一个 setRowFactory

I have a tableView, where each table row represents an object and each column represents the attributes of the object. Within the tableView, I am defining a setRowFactory.

setRowFactory 中,我希望能够访问该行中的特定单元格并突出显示它通过这样做: ThisCellofThisRow.pseudoClassStateChanged(...)

Within the setRowFactory, I want to be able to have access to a particular cell within the row and highlight it by doing this: ThisCellofThisRow.pseudoClassStateChanged(...)

问题是:我不知道如何引用这个 ThisCellofThisRow

Problem is: I have no idea how to reference this ThisCellofThisRow.

推荐答案

不确定你想要做什么,但你可以改变行的伪类状态,然后使用CSS来选择特定列。这样行工厂根本不必访问单元。

Not sure exactly what you want to do, but you could change the pseudoclass state of the row, and then use CSS to select the particular column. That way the row factory doesn't have to access the cell at all.

示例:

highlight-cell-in-row.css:

highlight-cell-in-row.css:

/*
** Gives a yellow background to a table cell with style class "value-cell"
** that is inside a row with the "high" psuedoclass set 
*/

.table-row-cell:high .value-cell {
    -fx-background-color: transparent, yellow ;
}

TableViewHighlightItem.java:

TableViewHighlightItem.java:

import java.util.Random;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;


public class TableViewHighlightItem extends Application {

    @Override
    public void start(Stage primaryStage) {

        // create table and columns:
        TableView<Item> table = new TableView<>();
        TableColumn<Item, String> nameCol = column("Name", Item::nameProperty);
        TableColumn<Item, Number> valueCol = column("Value", Item::valueProperty);
        table.getColumns().add(nameCol);
        table.getColumns().add(valueCol);

        // basic default cell, but with "value-cell" always added as a CSS class:
        valueCol.setCellFactory(col -> {
            TableCell<Item, Number> cell = new TableCell<Item, Number>(){
                @Override
                public void updateItem(Number value, boolean empty) {
                    super.updateItem(value, empty);
                    if (empty) {
                        setText(null);
                    } else {
                        setText(value.toString());
                    }
                }
            };
            cell.getStyleClass().add("value-cell");
            return cell ;
        });

        PseudoClass high = PseudoClass.getPseudoClass("high");

        // Table row toggles "high" pseudoclass according to state of current item in row:
        table.setRowFactory(tv -> {
            TableRow<Item> row = new TableRow<>();

            ChangeListener<Boolean> highListener = (obs, wasHigh, isNowHigh) -> 
                row.pseudoClassStateChanged(high, isNowHigh);

            row.itemProperty().addListener((obs, oldItem, newItem) -> {
                if (oldItem != null) {
                    oldItem.highProperty().removeListener(highListener);
                }
                if (newItem == null) {
                    row.pseudoClassStateChanged(high, false);
                } else {
                    row.pseudoClassStateChanged(high, newItem.isHigh());
                    newItem.highProperty().addListener(highListener);
                }
            });

            return row ;
        });

        Random rng = new Random();

        // Button to test changing data to random values:
        Button changeButton = new Button("Change Data");
        changeButton.setOnAction(e -> 
                table.getItems().forEach(item -> item.setValue(rng.nextInt(20))));

        // add data to table:
        for (int i = 1 ; i <= 40 ; i++) {
            table.getItems().add(new Item("Item "+i, rng.nextInt(20)));
        }

        // layout:
        BorderPane root = new BorderPane(table, null, null, changeButton, null);
        BorderPane.setAlignment(changeButton, Pos.CENTER);
        BorderPane.setMargin(changeButton, new Insets(10));
        Scene scene = new Scene(root, 600, 600);
        scene.getStylesheets().add("highlight-cell-in-row.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // utility method for creating columns:
    private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> column = new TableColumn<>(title);
        column.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return column ;
    }

    // model class:
    public static class Item {
        private final StringProperty name = new SimpleStringProperty();
        private final IntegerProperty value = new SimpleIntegerProperty();
        private final ReadOnlyBooleanWrapper high = new ReadOnlyBooleanWrapper();

        public Item(String name, int value) {
            setName(name);
            setValue(value);
            high.bind(this.value.greaterThanOrEqualTo(10));
        }

        public final StringProperty nameProperty() {
            return this.name;
        }

        public final String getName() {
            return this.nameProperty().get();
        }

        public final void setName(final String name) {
            this.nameProperty().set(name);
        }

        public final IntegerProperty valueProperty() {
            return this.value;
        }

        public final int getValue() {
            return this.valueProperty().get();
        }

        public final void setValue(final int value) {
            this.valueProperty().set(value);
        }

        public final ReadOnlyBooleanProperty highProperty() {
            return this.high.getReadOnlyProperty();
        }

        public final boolean isHigh() {
            return this.highProperty().get();
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}

这篇关于Javafx:我如何引用setRowFactory中一行中的特定单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆