Skip to content

Commit 71ca899

Browse files
Jeanette Winzenburgaghaisas
authored andcommitted
8220722: ProgressBarSkin: adds strong listener to control's width property
Reviewed-by: aghaisas, arapte
1 parent 07af89a commit 71ca899

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public ProgressBarSkin(ProgressBar control) {
9898

9999
barWidth = ((int) (control.getWidth() - snappedLeftInset() - snappedRightInset()) * 2 * Math.min(1, Math.max(0, control.getProgress()))) / 2.0F;
100100

101-
control.widthProperty().addListener(observable -> updateProgress());
101+
registerChangeListener(control.widthProperty(), o -> updateProgress());
102102

103103
initialize();
104104
getSkinnable().requestLayout();

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

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,115 @@
2525

2626
package test.javafx.scene.control.skin;
2727

28-
import static org.junit.Assert.assertEquals;
28+
import java.lang.ref.WeakReference;
29+
30+
import org.junit.After;
31+
import org.junit.Before;
32+
import org.junit.Test;
33+
34+
import com.sun.javafx.tk.Toolkit;
35+
36+
import static org.junit.Assert.*;
2937

3038
import javafx.beans.value.ObservableValue;
39+
import javafx.scene.Scene;
3140
import javafx.scene.control.ProgressBar;
41+
import javafx.scene.control.Skin;
3242
import javafx.scene.control.skin.ProgressBarSkin;
33-
34-
import org.junit.Before;
35-
import org.junit.Test;
43+
import javafx.scene.layout.Region;
44+
import javafx.scene.layout.StackPane;
45+
import javafx.stage.Stage;
46+
import test.com.sun.javafx.pgstub.StubToolkit;
3647

3748
/**
3849
*/
3950
public class ProgressBarSkinTest {
4051
private ProgressBar progressbar;
4152
private ProgressBarSkinMock skin;
53+
private Scene scene;
54+
private Stage stage;
55+
private StackPane root;
4256

4357
@Before public void setup() {
4458
progressbar = new ProgressBar();
4559
skin = new ProgressBarSkinMock(progressbar);
4660
progressbar.setSkin(skin);
4761
}
4862

63+
/**
64+
* Helper method to init the stage only if really needed.
65+
*/
66+
private void initStage() {
67+
//This step is not needed (Just to make sure StubToolkit is loaded into VM)
68+
Toolkit tk = (StubToolkit)Toolkit.getToolkit();
69+
root = new StackPane();
70+
scene = new Scene(root);
71+
stage = new Stage();
72+
stage.setScene(scene);
73+
}
74+
75+
@After
76+
public void cleanup() {
77+
if (stage != null) {
78+
stage.hide();
79+
}
80+
}
81+
82+
/**
83+
* Test that inner bar width is in sync with its progressbar's width.
84+
*/
85+
@Test
86+
public void testWidthListener() {
87+
initStage();
88+
// set determinate
89+
double progress = .5;
90+
progressbar.setProgress(progress);
91+
// make it resizable
92+
progressbar.setMaxWidth(2000);
93+
root.getChildren().setAll(progressbar);
94+
double stageSize = 300;
95+
stage.setWidth(stageSize);
96+
stage.setHeight(stageSize);
97+
stage.show();
98+
// fire to force layout
99+
Toolkit.getToolkit().firePulse();
100+
101+
assertEquals("progressbar fills root", root.getWidth(),
102+
progressbar.getWidth(), 0.5);
103+
Region innerBar = (Region) progressbar.lookup(".bar");
104+
assertEquals("inner bar width updated",
105+
progressbar.getWidth() * progress, innerBar.getWidth(), 0.5);
106+
}
107+
108+
WeakReference<Skin<?>> weakSkinRef;
109+
110+
@Test
111+
public void testWidthListenerGC() {
112+
ProgressBar progressbar = new ProgressBar();
113+
progressbar.setSkin(new ProgressBarSkin(progressbar));
114+
weakSkinRef = new WeakReference<>(progressbar.getSkin());
115+
progressbar.setSkin(null);
116+
attemptGC(10);
117+
assertNull("skin must be gc'ed", weakSkinRef.get());
118+
}
119+
120+
private void attemptGC(int n) {
121+
// Attempt gc n times
122+
for (int i = 0; i < n; i++) {
123+
System.gc();
124+
System.runFinalization();
125+
126+
if (weakSkinRef.get() == null) {
127+
break;
128+
}
129+
try {
130+
Thread.sleep(500);
131+
} catch (InterruptedException e) {
132+
System.err.println("InterruptedException occurred during Thread.sleep()");
133+
}
134+
}
135+
}
136+
49137
@Test public void maxWidthTracksPreferred() {
50138
progressbar.setPrefWidth(500);
51139
assertEquals(500, progressbar.maxWidth(-1), 0);

0 commit comments

Comments
 (0)