Skip to content

Commit 18b2366

Browse files
Robert Lichtenbergeraghaisas
Robert Lichtenberger
authored andcommittedMay 20, 2022
8285197: TableColumnHeader: calc of cell width must respect row styling (TreeTableView)
Reviewed-by: mhanl, aghaisas
1 parent 81e1cc3 commit 18b2366

File tree

2 files changed

+179
-4
lines changed

2 files changed

+179
-4
lines changed
 

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

+18-4
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,9 @@ private <T,S> void resizeColumnToFitContent(TreeTableView<T> ttv, TreeTableColum
737737
padding = r.snappedLeftInset() + r.snappedRightInset();
738738
}
739739

740-
TreeTableRow<T> treeTableRow = new TreeTableRow<>();
741-
treeTableRow.updateTreeTableView(ttv);
740+
Callback<TreeTableView<T>, TreeTableRow<T>> rowFactory = ttv.getRowFactory();
741+
TreeTableRow<T> treeTableRow = createMeasureRow(ttv, tableSkin, rowFactory);
742+
((SkinBase<?>) treeTableRow.getSkin()).getChildren().add(cell);
742743

743744
int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
744745
double maxWidth = 0;
@@ -752,8 +753,7 @@ private <T,S> void resizeColumnToFitContent(TreeTableView<T> ttv, TreeTableColum
752753
cell.updateIndex(row);
753754

754755
if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
755-
tableSkin.getChildren().add(cell);
756-
cell.applyCss();
756+
treeTableRow.applyCss();
757757

758758
double w = cell.prefWidth(-1);
759759

@@ -797,6 +797,20 @@ private <T,S> void resizeColumnToFitContent(TreeTableView<T> ttv, TreeTableColum
797797
}
798798
}
799799

800+
private <T> TreeTableRow<T> createMeasureRow(TreeTableView<T> ttv, TableViewSkinBase tableSkin,
801+
Callback<TreeTableView<T>, TreeTableRow<T>> rowFactory) {
802+
TreeTableRow<T> treeTableRow = rowFactory != null ? rowFactory.call(ttv) : new TreeTableRow<>();
803+
tableSkin.getChildren().add(treeTableRow);
804+
treeTableRow.applyCss();
805+
if (!(treeTableRow.getSkin() instanceof SkinBase<?>)) {
806+
tableSkin.getChildren().remove(treeTableRow);
807+
// recreate with null rowFactory will result in a standard TableRow that will
808+
// have a SkinBase-derived skin
809+
treeTableRow = createMeasureRow(ttv, tableSkin, null);
810+
}
811+
return treeTableRow;
812+
}
813+
800814
private void updateSortPosition() {
801815
this.sortPos = ! getTableColumn().isSortable() ? -1 : getSortPosition();
802816
updateSortGrid();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package test.javafx.scene.control.skin;
27+
28+
import com.sun.javafx.tk.Toolkit;
29+
import javafx.scene.Node;
30+
import javafx.scene.control.Skin;
31+
import javafx.scene.control.TreeItem;
32+
import javafx.scene.control.TreeTableColumn;
33+
import javafx.scene.control.TreeTableRow;
34+
import javafx.scene.control.TreeTableView;
35+
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
36+
import javafx.scene.control.skin.TableColumnHeader;
37+
import javafx.scene.control.skin.TableColumnHeaderShim;
38+
import javafx.scene.layout.HBox;
39+
import org.junit.After;
40+
import org.junit.Before;
41+
import org.junit.Test;
42+
import test.com.sun.javafx.scene.control.infrastructure.StageLoader;
43+
import test.com.sun.javafx.scene.control.infrastructure.VirtualFlowTestUtils;
44+
import test.com.sun.javafx.scene.control.test.Person;
45+
46+
import java.util.List;
47+
48+
import static org.junit.Assert.assertTrue;
49+
50+
public class TreeTableColumnHeaderTest {
51+
52+
private TableColumnHeader firstColumnHeader;
53+
private TreeTableView<Person> treeTableView;
54+
private StageLoader sl;
55+
private static String NAME0 = "Humphrey McPhee";
56+
private static String NAME1 = "Justice Caldwell";
57+
private static String NAME2 = "Orrin Davies";
58+
private static String NAME3 = "Emma Wilson";
59+
60+
@Before
61+
public void before() {
62+
TreeItem<Person> root = new TreeItem<>(new Person("Witty quotes", "", ""));
63+
root.getChildren().addAll(List.of(
64+
new TreeItem<Person>(new Person(NAME0, 76)),
65+
new TreeItem<Person>(new Person(NAME1, 30)),
66+
new TreeItem<Person>(new Person(NAME2, 30)),
67+
new TreeItem<Person>(new Person(NAME3, 8))
68+
));
69+
70+
TreeTableColumn<Person, String> column = new TreeTableColumn<>("Col ");
71+
column.setCellValueFactory(new TreeItemPropertyValueFactory<Person, String>("firstName"));
72+
73+
treeTableView = new TreeTableView<>(root);
74+
75+
treeTableView.getColumns().add(column);
76+
77+
sl = new StageLoader(treeTableView);
78+
Toolkit tk = Toolkit.getToolkit();
79+
80+
tk.firePulse();
81+
//Force the column to have default font, otherwise font Amble is applied and mess with header width size
82+
column.setStyle("-fx-font: System;");
83+
firstColumnHeader = VirtualFlowTestUtils.getTableColumnHeader(treeTableView, column);
84+
}
85+
86+
@After
87+
public void after() {
88+
sl.dispose();
89+
}
90+
91+
/** Row style must affect the required column width */
92+
@Test
93+
public void test_resizeColumnToFitContentRowStyle() {
94+
TreeTableColumn column = treeTableView.getColumns().get(0);
95+
96+
treeTableView.setRowFactory(this::createSmallRow);
97+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
98+
double width = column.getWidth();
99+
100+
treeTableView.setRowFactory(this::createLargeRow);
101+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
102+
assertTrue("Column width must be greater", width < column.getWidth());
103+
}
104+
105+
/** Test resizeColumnToFitContent in the presence of a non-standard row skin */
106+
@Test
107+
public void test_resizeColumnToFitContentCustomRowSkin() {
108+
TreeTableColumn column = treeTableView.getColumns().get(0);
109+
110+
treeTableView.setRowFactory(this::createCustomRow);
111+
TableColumnHeaderShim.resizeColumnToFitContent(firstColumnHeader, -1);
112+
double width = column.getWidth();
113+
assertTrue(width > 0);
114+
}
115+
116+
private TreeTableRow<Person> createCustomRow(TreeTableView<Person> treeTableView) {
117+
TreeTableRow<Person> row = new TreeTableRow<>() {
118+
protected Skin<?> createDefaultSkin() {
119+
return new CustomSkin(this);
120+
};
121+
};
122+
return row;
123+
}
124+
125+
private static class CustomSkin implements Skin<TreeTableRow<?>> {
126+
127+
private TreeTableRow<?> row;
128+
private Node node = new HBox();
129+
130+
CustomSkin(TreeTableRow<?> row) {
131+
this.row = row;
132+
}
133+
134+
@Override
135+
public TreeTableRow<?> getSkinnable() {
136+
return row;
137+
}
138+
139+
@Override
140+
public Node getNode() {
141+
return node;
142+
}
143+
144+
@Override
145+
public void dispose() {
146+
node = null;
147+
}
148+
}
149+
150+
private TreeTableRow<Person> createSmallRow(TreeTableView<Person> treeTableView) {
151+
TreeTableRow<Person> row = new TreeTableRow<>();
152+
row.setStyle("-fx-font: 24 Amble");
153+
return row;
154+
}
155+
156+
private TreeTableRow<Person> createLargeRow(TreeTableView<Person> param) {
157+
TreeTableRow<Person> row = new TreeTableRow<>();
158+
row.setStyle("-fx-font: 48 Amble");
159+
return row;
160+
}
161+
}

0 commit comments

Comments
 (0)
Please sign in to comment.