Tableview可见行

时间:2014-10-02 10:47:24

标签: javafx

我想为tableview实现自定义滚动功能。因此,需要访问可见的行和单元格。

如何检测JavaFX tableview中的可见单元格和行?我还没有在tableview的API描述中找到任何相关信息。

由于

2 个答案:

答案 0 :(得分:6)

在TableView中尝试此操作以滚动到所需的行。我已尝试使用table.scrollTo(index),但它没有正确滚动,因为它将所需行设置为第一个可见行。

我已经在我的控制器上编写了下一个代码。

您还可以在此处查看如何获取可见行。

/**
 * Used to manually scroll the Table
 */
private TableViewSkin<?> tableSkin;
private VirtualFlow<?> virtualFlow;

@Override
public void initialize(URL location, ResourceBundle resources) {
    ...
    ...
    Platform.runLater( ()-> { loadVirtualFlow(); });
}

/**
 * Loads the actual VirtualFlow
 */
private void loadVirtualFlow(){
    tableSkin = (TableViewSkin<?>) tableContent.getSkin();
    virtualFlow = (VirtualFlow<?>) tableSkin.getChildren().get(1);
}

/**
 * Scrolls the table until the given index is visible
 * @param index to be shown
 */
private void scrollTo(int index){
    int first = virtualFlow.getFirstVisibleCell().getIndex();
    int last = virtualFlow.getLastVisibleCell().getIndex();
    if (index <= first){
        while (index <= first && virtualFlow.adjustPixels(-1) < 0){
            first = virtualFlow.getFirstVisibleCell().getIndex();
        }
    } else {
        while (index >= last && virtualFlow.adjustPixels(1) > 0){
            last = virtualFlow.getLastVisibleCell().getIndex();
        }
    }
}

使用此代码,您可以轻松滚动到所需的索引:

scrollTo(index);

在向列表中添加元素后,请记得在调用scrollTo之前调用 loadVirtualFlow ,这样VirtualFlow就会更新并且不会抛出异常。

答案 1 :(得分:2)

我知道这是一个老问题......无论如何,如果有人需要它:

你可以在没有VirtualFlow的情况下实现它(这是一个私人API,因为&#34;吹嘘鸽子&#34;提及)。只需使用您自己的RowFactory并在创建TableRow对象时将其存储(这里的一些断点或System.out.println()调用可以帮助您快速了解TableView的工作原理。)

在您的控制器类中,创建以下两个字段:

private ArrayList<TableRow<Person>> tblViewPersonsTableRows = new ArrayList<>();
private boolean headerTableRowCreated = false;

...在TableRowFactory中,存储引用...

final TableRow<Person> tableRow = new TableRow<Person>() {
    ...
}

if (!headerTableRowCreated) {
    headerTableRowCreated = true; //the first TableRow corresponds to TableView's header so ignore it
} else {
    int myIdx = tblViewPersonsTableRows.size();
    tblViewPersonsTableRows.add(tableRow);
}

...现在在需要的地方拨打电话......

double tblViewHeight = fxTblViewPersons.getHeight();
double headerHeight = fxTblViewPersons.lookup(".column-header-background").getBoundsInLocal().getHeight();
double viewPortHeight = tblViewHeight - headerHeight;
for (TableRow tableRow : tblViewPersonsTableRows) {
    double minY = tableRow.getBoundsInParent().getMinY();
    double maxY = tableRow.getBoundsInParent().getMaxY();

    if ((maxY < 0) || (minY > viewPortHeight)) {
        //row invisible
    } else if ((maxY <= viewPortHeight) && (minY >= 0)) {
        tableRow.getStyleClass().add("fullyVisibleRow");
    } else {
        tableRow.getStyleClass().add("partiallyVisibleRow");
    }
}

...... !!!小心 !!!如果您在某个事件处理程序中调用它,数据或排序顺序会发生变化,请检查数据更改前的旧坐标或更改后的新坐标。

如果您使用这样的CSS样式......

.fullyVisibleRow {
    -fx-control-inner-background: palegreen;
    -fx-accent: derive(-fx-control-inner-background, -40%);
    -fx-cell-hover-color: derive(-fx-control-inner-background, -20%);
}

.partiallyVisibleRow {
    -fx-control-inner-background: orange;
    -fx-accent: derive(-fx-control-inner-background, -40%);
    -fx-cell-hover-color: derive(-fx-control-inner-background, -20%);
}

...完全可见的行应为绿色,部分可见的行(在TableView的顶部和底部)应为橙色。我希望这有助于某人。