-
Bug
-
Resolution: Unresolved
-
P4
-
jfx11, jfx15, jfx16
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
Nodes used as clip or shape return null when calling getParent() which leads to incorrect calculation in sceneToLocal/localToScene.
Nodes used as clip or shape return null when calling getParent() is the good behaviour as they are in some kind of detached graph.
Nodes used as clip or shape need to know their owner to correctly calculate their position
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Add a Rectangle to the scene and move it to 100,100
Add a Circle clip to the previous Rectangle with a radius of 50 then move center X,Y to 50,50
print the value of circle.localToScene(0, 0, true)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Point2D [x = 100.0, y = 100.0]
ACTUAL -
Point2D [x = 0.0, y = 0.0]
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Test extends Application {
@Override
public void start(Stage primaryStage) {
Rectangle clipedRectangle = new Rectangle(100, 100);
clipedRectangle.setFill(Color.BLUE);
Circle circle = new Circle(50);
// set circle to share the same bounding box and position than clipedRectangle
circle.setCenterX(50);
circle.setCenterY(50);
clipedRectangle.setClip(circle);
Pane root = new Pane();
root.getChildren().add(clipedRectangle);
clipedRectangle.setLayoutX(100);
clipedRectangle.setLayoutY(100);
primaryStage.setScene(new Scene(root, 200, 200));
primaryStage.show();
System.out.println(String.format("Expected circle local bounds %s to have the same local bounds than clipedRectangle %s OK",
circle.getBoundsInLocal(),
clipedRectangle.getBoundsInLocal()
));
System.out.println(String.format("Expected circle layout bounds %s to have the same layout bounds than clipedRectangle %s OK",
circle.getLayoutBounds(),
clipedRectangle.getLayoutBounds()
));
System.out.println(String.format("Expected circle parent bounds %s to have different parent bounds than clipedRectangle %s OK",
circle.getBoundsInParent(),
clipedRectangle.getBoundsInParent()
));
System.out.println(String.format("Expected circle topLeft corner %s to have the same 'scene relative' position than clipedRectangle topLeft corner %s KO",
circle.localToScene(0, 0, true),
clipedRectangle.localToScene(0, 0, true)
));
System.out.println(String.format("Expected scene position 100,100 to match toLeft corner of clipedRectangle %s OK",
clipedRectangle.sceneToLocal(100, 100, true)
));
System.out.println(String.format("Expected scene position 100,100 to match toLeft corner of circle %s KO expected 0,0",
circle.sceneToLocal(100, 100, true)
));
}
public static void main(String[] args) {
launch(args);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
void localToScene(com.sun.javafx.geom.Point2D pt) {
localToParent(pt);
if (getParent() != null) { // if the Node used as clip can return his correct owner instead of null the calculation is correct
getParent().localToScene(pt);
}
}
FREQUENCY : always
Nodes used as clip or shape return null when calling getParent() which leads to incorrect calculation in sceneToLocal/localToScene.
Nodes used as clip or shape return null when calling getParent() is the good behaviour as they are in some kind of detached graph.
Nodes used as clip or shape need to know their owner to correctly calculate their position
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Add a Rectangle to the scene and move it to 100,100
Add a Circle clip to the previous Rectangle with a radius of 50 then move center X,Y to 50,50
print the value of circle.localToScene(0, 0, true)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Point2D [x = 100.0, y = 100.0]
ACTUAL -
Point2D [x = 0.0, y = 0.0]
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Test extends Application {
@Override
public void start(Stage primaryStage) {
Rectangle clipedRectangle = new Rectangle(100, 100);
clipedRectangle.setFill(Color.BLUE);
Circle circle = new Circle(50);
// set circle to share the same bounding box and position than clipedRectangle
circle.setCenterX(50);
circle.setCenterY(50);
clipedRectangle.setClip(circle);
Pane root = new Pane();
root.getChildren().add(clipedRectangle);
clipedRectangle.setLayoutX(100);
clipedRectangle.setLayoutY(100);
primaryStage.setScene(new Scene(root, 200, 200));
primaryStage.show();
System.out.println(String.format("Expected circle local bounds %s to have the same local bounds than clipedRectangle %s OK",
circle.getBoundsInLocal(),
clipedRectangle.getBoundsInLocal()
));
System.out.println(String.format("Expected circle layout bounds %s to have the same layout bounds than clipedRectangle %s OK",
circle.getLayoutBounds(),
clipedRectangle.getLayoutBounds()
));
System.out.println(String.format("Expected circle parent bounds %s to have different parent bounds than clipedRectangle %s OK",
circle.getBoundsInParent(),
clipedRectangle.getBoundsInParent()
));
System.out.println(String.format("Expected circle topLeft corner %s to have the same 'scene relative' position than clipedRectangle topLeft corner %s KO",
circle.localToScene(0, 0, true),
clipedRectangle.localToScene(0, 0, true)
));
System.out.println(String.format("Expected scene position 100,100 to match toLeft corner of clipedRectangle %s OK",
clipedRectangle.sceneToLocal(100, 100, true)
));
System.out.println(String.format("Expected scene position 100,100 to match toLeft corner of circle %s KO expected 0,0",
circle.sceneToLocal(100, 100, true)
));
}
public static void main(String[] args) {
launch(args);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
void localToScene(com.sun.javafx.geom.Point2D pt) {
localToParent(pt);
if (getParent() != null) { // if the Node used as clip can return his correct owner instead of null the calculation is correct
getParent().localToScene(pt);
}
}
FREQUENCY : always