Reputation: 51
JavaFx-14 put this method in the TableColumnHeader, rather than in the Skin. How does one find a TableColumnHeader from a TableColumn and a TableView?
Upvotes: 3
Views: 749
Reputation: 3518
Don't know if you still need this, but if anyone else is interested, this is how I surpassed the problem in java, based on David Goodenough's scala code above.
The class for the TableSkin
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TableView;
import javafx.scene.control.skin.NestedTableColumnHeader;
import javafx.scene.control.skin.TableColumnHeader;
import javafx.scene.control.skin.TableHeaderRow;
import javafx.scene.control.skin.TableViewSkin;
import java.util.ArrayList;
import java.util.List;
public class CustomTableViewSkin extends TableViewSkin<Track> {
private List<CustomTableColumnHeader> columnHeadersList = new ArrayList<>();
private class CustomTableColumnHeader extends TableColumnHeader {
/**
* Creates a new TableColumnHeader instance to visually represent the given
* {@link TableColumnBase} instance.
*
* @param tc The table column to be visually represented by this instance.
*/
public CustomTableColumnHeader(TableColumnBase tc) {
super(tc);
}
public void resizeColumnToFitContent() {
super.resizeColumnToFitContent(-1);
}
}
public CustomTableViewSkin(TableView<Track> tableView) {
super(tableView);
}
@Override
protected TableHeaderRow createTableHeaderRow() {
return new TableHeaderRow(this) {
@Override
protected NestedTableColumnHeader createRootHeader() {
return new NestedTableColumnHeader(null) {
@Override
protected TableColumnHeader createTableColumnHeader(TableColumnBase col) {
CustomTableColumnHeader columnHeader = new CustomTableColumnHeader(col);
if (columnHeadersList == null) {
columnHeadersList = new ArrayList<>();
}
columnHeadersList.add(columnHeader);
return columnHeader;
}
};
}
};
}
public void resizeColumnToFit() {
if (!columnHeadersList.isEmpty()) {
for (CustomTableColumnHeader columnHeader : columnHeadersList) {
columnHeader.resizeColumnToFitContent();
}
}
}
}
And the class for the TableView
import javafx.scene.control.TableView;
public class CustomTableView extends TableView<Foo> {
private final CustomTableViewSkin thisSkin;
public CustomTableView() {
super();
setSkin(thisSkin = new CustomTableViewSkin(this));
}
public void resizeColumnsToFitContent() {
if (thisSkin != null && getSkin() == thisSkin) {
thisSkin.resizeColumnToFit();
}
}
}
Upvotes: 3
Reputation: 51
Well this code is Scala not Java, but for the record the code below works:-
skin = new TableViewSkin(this) {
override protected def createTableHeaderRow:TableHeaderRow = {
new TableHeaderRow(this) {
override protected def createRootHeader:NestedTableColumnHeader = {
new NestedTableColumnHeader(null) {
override protected def createTableColumnHeader(col:TableColumnBase[_,_]) = {
val tableColumnHeader = new MyTableColumnHeader(col)
if(col == null || col.getColumns.isEmpty || col == getTableColumn) tableColumnHeader else new NestedTableColumnHeader(col)
}
}
}
}
}
}
private class MyTableColumnHeader(tc:TableColumnBase[_,_]) extends TableColumnHeader(tc) {
def resizeCol():Double = {
resizeColumnToFitContent(-1)
width.value
}
}
and then when I want to use it I use kleopatra's suggestion and:-
val w = columns.map { col =>
// To find the TableColumnHeader we can use column.getStyleableNode as suggested by kleopatra on StackOverflow:-
// you get the header from coumn.getStyleableNode (took a moment, had to check if it's really implemented) – kleopatra Jul 1 at 20:46
col.getStyleableNode() match {
case mtch:MyTableColumnHeader => mtch.resizeCol
case _ => col.width.get
}
}.sum
Upvotes: 1
Reputation: 2703
This is a hack'ish way of getting the TableColumnHeader
:
public TableColumnHeader getTableColumnHeader(TableView<?> table, int index) {
return (TableColumnHeader) table.queryAccessibleAttribute(AccessibleAttribute.COLUMN_AT_INDEX, index);
}
Or, as @kleopatra suggested, for a non-hack'ish approach you can do:
public TableColumnHeader getTableColumnHeader(TableView<?> table, int index) {
return (TableColumnHeader) table.getColumns().get(index).getStyleableNode();
}
Make sure that the TableView
is part of the scene graph.
However, the resizeColumnToFitContent
method is protected and you won't be able to access it.
Upvotes: 0