Skip to content

Commit 0514116

Browse files
author
Jeanette Winzenburg
committed
8246745: ListCell/Skin: misbehavior on switching skin
Reviewed-by: kcr, arapte
1 parent 7506554 commit 0514116

File tree

4 files changed

+66
-39
lines changed

4 files changed

+66
-39
lines changed

modules/javafx.controls/src/main/java/javafx/scene/control/skin/ListCellSkin.java

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@
2626
package javafx.scene.control.skin;
2727

2828
import com.sun.javafx.scene.control.behavior.BehaviorBase;
29-
import javafx.beans.InvalidationListener;
30-
import javafx.beans.Observable;
29+
import com.sun.javafx.scene.control.behavior.ListCellBehavior;
30+
3131
import javafx.geometry.Orientation;
32-
import javafx.scene.Node;
33-
import javafx.scene.control.Accordion;
34-
import javafx.scene.control.Button;
3532
import javafx.scene.control.Control;
3633
import javafx.scene.control.ListCell;
3734
import javafx.scene.control.ListView;
38-
39-
import com.sun.javafx.scene.control.behavior.ListCellBehavior;
35+
import javafx.scene.layout.Region;
4036

4137
/**
4238
* Default skin implementation for the {@link ListCell} control.
@@ -52,12 +48,8 @@ public class ListCellSkin<T> extends CellSkinBase<ListCell<T>> {
5248
* *
5349
**************************************************************************/
5450

55-
private double fixedCellSize;
56-
private boolean fixedCellSizeEnabled;
5751
private final BehaviorBase<ListCell<T>> behavior;
5852

59-
60-
6153
/***************************************************************************
6254
* *
6355
* Constructors *
@@ -77,31 +69,8 @@ public ListCellSkin(ListCell<T> control) {
7769
// install default input map for the ListCell control
7870
behavior = new ListCellBehavior<>(control);
7971
// control.setInputMap(behavior.getInputMap());
80-
81-
setupListeners();
8272
}
8373

84-
private void setupListeners() {
85-
ListView listView = getSkinnable().getListView();
86-
if (listView == null) {
87-
getSkinnable().listViewProperty().addListener(new InvalidationListener() {
88-
@Override public void invalidated(Observable observable) {
89-
getSkinnable().listViewProperty().removeListener(this);
90-
setupListeners();
91-
}
92-
});
93-
} else {
94-
this.fixedCellSize = listView.getFixedCellSize();
95-
this.fixedCellSizeEnabled = fixedCellSize > 0;
96-
registerChangeListener(listView.fixedCellSizeProperty(), e -> {
97-
this.fixedCellSize = getSkinnable().getListView().getFixedCellSize();
98-
this.fixedCellSizeEnabled = fixedCellSize > 0;
99-
});
100-
}
101-
}
102-
103-
104-
10574
/***************************************************************************
10675
* *
10776
* Public API *
@@ -127,7 +96,8 @@ private void setupListeners() {
12796

12897
/** {@inheritDoc} */
12998
@Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
130-
if (fixedCellSizeEnabled) {
99+
double fixedCellSize = getFixedCellSize();
100+
if (fixedCellSize > 0) {
131101
return fixedCellSize;
132102
}
133103

@@ -140,7 +110,8 @@ private void setupListeners() {
140110

141111
/** {@inheritDoc} */
142112
@Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
143-
if (fixedCellSizeEnabled) {
113+
double fixedCellSize = getFixedCellSize();
114+
if (fixedCellSize > 0) {
144115
return fixedCellSize;
145116
}
146117

@@ -149,10 +120,15 @@ private void setupListeners() {
149120

150121
/** {@inheritDoc} */
151122
@Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
152-
if (fixedCellSizeEnabled) {
123+
double fixedCellSize = getFixedCellSize();
124+
if (fixedCellSize > 0) {
153125
return fixedCellSize;
154126
}
155-
156127
return super.computeMaxHeight(width, topInset, rightInset, bottomInset, leftInset);
157128
}
129+
130+
private double getFixedCellSize() {
131+
ListView<?> listView = getSkinnable().getListView();
132+
return listView != null ? listView.getFixedCellSize() : Region.USE_COMPUTED_SIZE;
133+
}
158134
}

modules/javafx.controls/src/test/java/test/javafx/scene/control/ListCellTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.junit.Ignore;
4343
import org.junit.Test;
4444

45+
import static javafx.scene.control.ControlShim.*;
4546
import static test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils.*;
4647
import static org.junit.Assert.*;
4748

@@ -810,4 +811,28 @@ private final class FocusModelMock extends FocusModel {
810811
ListCell cell = new ListCell();
811812
cell.setSkin(new ListCellSkin(cell));
812813
}
814+
815+
/**
816+
* Test that min/max/pref height respect fixedCellSize.
817+
* Sanity test when fixing JDK-8246745.
818+
*/
819+
@Test
820+
public void testListCellHeights() {
821+
ListCell<Object> cell = new ListCell<>();
822+
ListView<Object> listView = new ListView<>();
823+
cell.updateListView(listView);
824+
installDefaultSkin(cell);
825+
listView.setFixedCellSize(100);
826+
assertEquals("pref height must be fixedCellSize",
827+
listView.getFixedCellSize(),
828+
cell.prefHeight(-1), 1);
829+
assertEquals("min height must be fixedCellSize",
830+
listView.getFixedCellSize(),
831+
cell.minHeight(-1), 1);
832+
assertEquals("max height must be fixedCellSize",
833+
listView.getFixedCellSize(),
834+
cell.maxHeight(-1), 1);
835+
}
836+
837+
813838
}

modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/SkinCleanupTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import javafx.scene.control.Button;
4040
import javafx.scene.control.ChoiceBox;
4141
import javafx.scene.control.Control;
42+
import javafx.scene.control.ListCell;
4243
import javafx.scene.control.ListView;
4344
import javafx.scene.control.ToolBar;
4445
import javafx.scene.layout.Pane;
@@ -55,6 +56,32 @@ public class SkinCleanupTest {
5556
private Stage stage;
5657
private Pane root;
5758

59+
// ------------------ ListCell
60+
61+
@Test
62+
public void testListCellReplaceListViewWithNull() {
63+
ListCell<Object> cell = new ListCell<>();
64+
ListView<Object> listView = new ListView<>();
65+
cell.updateListView(listView);
66+
installDefaultSkin(cell);
67+
cell.updateListView(null);
68+
// 8246745: updating the old listView must not throw NPE in skin
69+
listView.setFixedCellSize(100);
70+
}
71+
72+
@Test
73+
public void testListCellPrefHeightOnReplaceListView() {
74+
ListCell<Object> cell = new ListCell<>();
75+
cell.updateListView(new ListView<>());
76+
installDefaultSkin(cell);
77+
ListView<Object> listView = new ListView<>();
78+
listView.setFixedCellSize(100);
79+
cell.updateListView(listView);
80+
assertEquals("fixed cell set to value of new listView",
81+
cell.getListView().getFixedCellSize(),
82+
cell.prefHeight(-1), 1);
83+
}
84+
5885
//-------------- listView
5986

6087
@Test

modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/SkinMemoryLeakTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ public static Collection<Object[]> data() {
110110
ColorPicker.class,
111111
ComboBox.class,
112112
DatePicker.class,
113-
ListCell.class,
114113
MenuBar.class,
115114
MenuButton.class,
116115
Pagination.class,

0 commit comments

Comments
 (0)