-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux odic021 2.6.32-220.el6.i686 #1 SMP Wed Nov 9 08:02:18 EST 2011 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
We did find that Control "boundsInLocalProperty" invalidation listeners may receive several times events containing extacly the same bounds. But note that change listeners do receive only the fist event (i.e. when bounds changed).
We expect InvalidationListener to receive the same events as ChangeListener as for any property.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Please use test code provided in this issue
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Invalidation listener should not receive the same event over and over again.
ACTUAL -
Change listener is ok but invalidation listener receives events containing the same bounds although they are both listening the same property!
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public final class Test2 extends Application {
private static final class MyWidget extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new MySkin(this);
}
}
private static final class MySkin extends SkinBase<MyWidget> {
public final Line line = new Line();
protected MySkin(final MyWidget control) {
super(control);
init();
}
private void init() {
final Thread t = new Thread(() -> {
try {
for (;;) {
setLine(0, 0, 100, 100 * Math.random());
Thread.sleep(1000);
}
} catch (final InterruptedException e) {
// End of work
}
});
t.setDaemon(true);
t.start();
line.setManaged(false);
line.setStyle("-fx-stroke: #FF0000;");
getChildren().add(line);
}
private void setLine(final double startX, final double startY, final double endX, final double endY) {
line.setStartX(startX);
line.setStartY(startY);
line.setEndX(endX);
line.setEndY(endY);
}
@Override
protected void layoutChildren(final double x, final double y, final double width, final double height) {
System.out.println("layoutChildren: x=" + x + ", y=" + y + ", w=" + width + ", h=" + height);
}
}
public static void main(final String... a) {
launch(a);
}
@Override
public void start(final Stage stage) throws Exception {
final MyWidget w = new MyWidget();
w.boundsInLocalProperty().addListener(observed -> System.out.println("invalidation - ko, even when no change: " + observed));
w.boundsInLocalProperty().addListener((observed, previous, next) -> System.out.println("change - ok, only when change: " + next));
stage.setScene(new Scene(new StackPane(w)));
stage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Not really as the invalidation events are fired BEFORE change events. We have to store and compare the event with the previous one which is really not nice!
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux odic021 2.6.32-220.el6.i686 #1 SMP Wed Nov 9 08:02:18 EST 2011 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
We did find that Control "boundsInLocalProperty" invalidation listeners may receive several times events containing extacly the same bounds. But note that change listeners do receive only the fist event (i.e. when bounds changed).
We expect InvalidationListener to receive the same events as ChangeListener as for any property.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Please use test code provided in this issue
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Invalidation listener should not receive the same event over and over again.
ACTUAL -
Change listener is ok but invalidation listener receives events containing the same bounds although they are both listening the same property!
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public final class Test2 extends Application {
private static final class MyWidget extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new MySkin(this);
}
}
private static final class MySkin extends SkinBase<MyWidget> {
public final Line line = new Line();
protected MySkin(final MyWidget control) {
super(control);
init();
}
private void init() {
final Thread t = new Thread(() -> {
try {
for (;;) {
setLine(0, 0, 100, 100 * Math.random());
Thread.sleep(1000);
}
} catch (final InterruptedException e) {
// End of work
}
});
t.setDaemon(true);
t.start();
line.setManaged(false);
line.setStyle("-fx-stroke: #FF0000;");
getChildren().add(line);
}
private void setLine(final double startX, final double startY, final double endX, final double endY) {
line.setStartX(startX);
line.setStartY(startY);
line.setEndX(endX);
line.setEndY(endY);
}
@Override
protected void layoutChildren(final double x, final double y, final double width, final double height) {
System.out.println("layoutChildren: x=" + x + ", y=" + y + ", w=" + width + ", h=" + height);
}
}
public static void main(final String... a) {
launch(a);
}
@Override
public void start(final Stage stage) throws Exception {
final MyWidget w = new MyWidget();
w.boundsInLocalProperty().addListener(observed -> System.out.println("invalidation - ko, even when no change: " + observed));
w.boundsInLocalProperty().addListener((observed, previous, next) -> System.out.println("change - ok, only when change: " + next));
stage.setScene(new Scene(new StackPane(w)));
stage.show();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Not really as the invalidation events are fired BEFORE change events. We have to store and compare the event with the previous one which is really not nice!