*************************************************
警告:このやり方はJava9では動作しません。エラーになります。
com.sunパッケージを使っている(使わざるをえなかった)からです。
Java9でも通用するやり方は以下にあります。
https://www.gwtcenter.com/post-75
*************************************************
TableView中の特定行を可視にする
JavaFXは複雑になっているにもかかわらずこんな機能も無い。つまり、テーブル中のある行が可視領域から外れてしまったときに、テーブルをスクロールしてその行が可視領域にきてもらいたい。 scrollTo(int index)という機能もあるが、これでは常に先頭行になってしまうため不自然。
There's no functionality of making the specified row visible in TableView. The following code does it. Of course there's builtin scrollTo(int) method, but that behavior is unnatural. I don't want to use it.
import com.sun.javafx.scene.control.skin.*; import javafx.scene.control.*; public class TableRowVisible { private TableView<?> tableView; public TableRowVisible(TableView<?> tableView) { this.tableView = tableView; } @SuppressWarnings("restriction") public VisibleRange getVisibleRange() { TableViewSkin<?> skin = (TableViewSkin<?>)tableView.getSkin(); if (skin == null) { return new VisibleRange(0, 0); } VirtualFlow<?> flow = (VirtualFlow<?>)skin.getChildren().get(1); int indexFirst; int indexLast; if (flow != null && flow.getFirstVisibleCellWithinViewPort() != null && flow.getLastVisibleCellWithinViewPort() != null) { indexFirst = flow.getFirstVisibleCellWithinViewPort().getIndex(); if (indexFirst >= tableView.getItems().size()) indexFirst = tableView.getItems().size() - 1; indexLast = flow.getLastVisibleCellWithinViewPort().getIndex(); if (indexLast >= tableView.getItems().size()) indexLast = tableView.getItems().size() - 1; } else { indexFirst = 0; indexLast = 0; } return new VisibleRange(indexFirst, indexLast - 1); // indexLast may be "half" visible } /** * Make specified row visible. * @param index */ public void makeVisible(int index) { VisibleRange range = getVisibleRange(); if (range.contains(index)) return; if (index < range.start) { tableView.scrollTo(index); return; } int newStart = index - range.count(); tableView.scrollTo(newStart); } static class VisibleRange { final int start; final int end; VisibleRange(int start, int end) { this.start = start; this.end = end; } int count() { return end - start + 1; } boolean contains(int index) { return start <= index && index <= end; } @Override public String toString() { return start + "," + end + "," + count(); } } }