Skip to content

Commit 18b9e94

Browse files
Robert Lichtenbergeraghaisas
Robert Lichtenberger
authored andcommittedApr 5, 2022
8251480: TableColumnHeader: calc of cell width must respect row styling
Reviewed-by: mhanl, aghaisas
1 parent b0f2521 commit 18b9e94

File tree

2 files changed

+97
-5
lines changed

2 files changed

+97
-5
lines changed
 

‎modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableColumnHeader.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import javafx.scene.Node;
5454
import javafx.scene.control.ContextMenu;
5555
import javafx.scene.control.Label;
56+
import javafx.scene.control.SkinBase;
5657
import javafx.scene.control.TableCell;
5758
import javafx.scene.control.TableColumn;
5859
import javafx.scene.control.TableColumnBase;
@@ -645,9 +646,9 @@ private <T,S> void resizeColumnToFitContent(TableView<T> tv, TableColumn<T, S> t
645646
Region r = (Region) n;
646647
padding = r.snappedLeftInset() + r.snappedRightInset();
647648
}
648-
649-
TableRow<T> tableRow = new TableRow<>();
650-
tableRow.updateTableView(tv);
649+
Callback<TableView<T>, TableRow<T>> rowFactory = tv.getRowFactory();
650+
TableRow<T> tableRow = createMeasureRow(tv, tableSkin, rowFactory);
651+
((SkinBase<?>) tableRow.getSkin()).getChildren().add(cell);
651652

652653
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
653654
double maxWidth = 0;
@@ -660,8 +661,7 @@ private <T,S> void resizeColumnToFitContent(TableView<T> tv, TableColumn<T, S> t
660661
cell.updateIndex(row);
661662

662663
if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
663-
tableSkin.getChildren().add(cell);
664-
cell.applyCss();
664+
tableRow.applyCss();
665665
maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
666666
tableSkin.getChildren().remove(cell);
667667
}
@@ -701,6 +701,20 @@ private <T,S> void resizeColumnToFitContent(TableView<T> tv, TableColumn<T, S> t
701701
}
702702
}
703703

704+
private <T> TableRow<T> createMeasureRow(TableView<T> tv, TableViewSkinBase tableSkin,
705+
Callback<TableView<T>, TableRow<T>> rowFactory) {
706+
TableRow<T> tableRow = rowFactory != null ? rowFactory.call(tv) : new TableRow<>();
707+
tableSkin.getChildren().add(tableRow);
708+
tableRow.applyCss();
709+
if (!(tableRow.getSkin() instanceof SkinBase<?>)) {
710+
tableSkin.getChildren().remove(tableRow);
711+
// recreate with null rowFactory will result in a standard TableRow that will
712+
// have a SkinBase-derived skin
713+
tableRow = createMeasureRow(tv, tableSkin, null);
714+
}
715+
return tableRow;
716+
}
717+
704718
private <T,S> void resizeColumnToFitContent(TreeTableView<T> ttv, TreeTableColumn<T, S> tc, TableViewSkinBase tableSkin, int maxRows) {
705719
List<?> items = new TreeTableViewBackingList(ttv);
706720
if (items == null || items.isEmpty()) return;

‎modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/TableColumnHeaderTest.java

+78
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@
2929
import javafx.collections.FXCollections;
3030
import javafx.collections.ObservableList;
3131
import javafx.event.Event;
32+
import javafx.scene.Node;
33+
import javafx.scene.control.Skin;
34+
import javafx.scene.control.Skinnable;
3235
import javafx.scene.control.TableColumn;
36+
import javafx.scene.control.TableRow;
3337
import javafx.scene.control.TableView;
3438
import javafx.scene.control.cell.PropertyValueFactory;
3539
import javafx.scene.control.skin.TableColumnHeader;
3640
import javafx.scene.input.MouseButton;
3741
import javafx.scene.input.MouseEvent;
42+
import javafx.scene.layout.HBox;
43+
3844
import org.junit.Before;
3945
import org.junit.After;
4046
import org.junit.Test;
@@ -252,4 +258,76 @@ public void test_resizeColumnToFitContentMaxRow() {
252258
assertEquals("Width must be equal to initial value",
253259
width, column.getWidth(), 0.001);
254260
}
261+
262+
/** Row style must affect the required column width */
263+
@Test
264+
public void test_resizeColumnToFitContentRowStyle() {
265+
TableColumn column = tableView.getColumns().get(0);
266+
267+
tableView.setRowFactory(this::createSmallRow);
268+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
269+
double width = column.getWidth();
270+
271+
tableView.setRowFactory(this::createLargeRow);
272+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
273+
assertTrue("Column width must be greater", width < column.getWidth());
274+
}
275+
276+
/** Test resizeColumnToFitContent in the presence of a non-standard row skin */
277+
@Test
278+
public void test_resizeColumnToFitContentCustomRowSkin() {
279+
TableColumn column = tableView.getColumns().get(0);
280+
281+
tableView.setRowFactory(this::createCustomRow);
282+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
283+
double width = column.getWidth();
284+
assertTrue(width > 0);
285+
}
286+
287+
private TableRow<Person> createCustomRow(TableView<Person> tableView) {
288+
TableRow<Person> row = new TableRow<>() {
289+
protected Skin<?> createDefaultSkin() {
290+
return new CustomSkin(this);
291+
};
292+
};
293+
return row;
294+
}
295+
296+
private static class CustomSkin implements Skin<TableRow<?>> {
297+
298+
private TableRow<?> row;
299+
private Node node = new HBox();
300+
301+
CustomSkin(TableRow<?> row) {
302+
this.row = row;
303+
}
304+
305+
@Override
306+
public TableRow<?> getSkinnable() {
307+
return row;
308+
}
309+
310+
@Override
311+
public Node getNode() {
312+
return node;
313+
}
314+
315+
@Override
316+
public void dispose() {
317+
node = null;
318+
}
319+
}
320+
321+
private TableRow<Person> createSmallRow(TableView<Person> tableView) {
322+
TableRow<Person> row = new TableRow<>();
323+
row.setStyle("-fx-font: 24 Amble");
324+
return row;
325+
}
326+
327+
private TableRow<Person> createLargeRow(TableView<Person> param) {
328+
TableRow<Person> row = new TableRow<>();
329+
row.setStyle("-fx-font: 48 Amble");
330+
return row;
331+
}
332+
255333
}

0 commit comments

Comments
 (0)
Please sign in to comment.