mr0406
mr0406

Reputation: 47

Javafx shapes dislocation

I have problem with shape dislocation in javafx. I'm using javafx.scene.shape.Shape to make some calculation with shapes. When I put all shapes together like a first code below, everything is fine. But in my more expanded program the idea is to dynamically adding shapes to AnchorPane(if it will help I can use other type of Pane). I pasted second code below which is showing shape dislocation.

First code(good result):

public class Controller {
public AnchorPane displayPane;

public Circle circleA = new Circle();
public Circle circleB = new Circle();
public Shape resultShape;

public void initialize() {
    setupShapes();
    displayPane.getChildren().add(circleA);
    displayPane.getChildren().add(circleB);
}

public void setupShapes() {
    double d = 100;
    double x = Math.sqrt(3 * Math.pow(d, 2) / 4);

    circleA.setCenterX(300.0);
    circleA.setCenterY(300.0 - d);
    circleA.setRadius(150);
    circleA.setFill(Color.TRANSPARENT);
    circleA.setStroke(Color.BLACK);
    circleA.setStrokeWidth(2);

    circleB.setCenterX(300.0 + x);
    circleB.setCenterY(300.0 + d / 2);
    circleB.setRadius(150);
    circleB.setFill(Color.TRANSPARENT);
    circleB.setStroke(Color.BLACK);
    circleB.setStrokeWidth(2);

    resultShape = Shape.intersect(circleA, circleB);
    resultShape.setFill(Color.DEEPSKYBLUE);
    displayPane.getChildren().add(resultShape);
}
}

Second code(wrong result):

public class Controller {
    public AnchorPane displayPane;

    public Circle circleA = new Circle();
    public Circle circleB = new Circle();
    public Shape resultShape;

    public void initialize() {
        setupShapes();
        displayPane.getChildren().add(circleA);
        displayPane.getChildren().add(circleB);

        resultShape = Shape.intersect(circleA, circleB);
        resultShape.setFill(Color.DEEPSKYBLUE);
        displayPane.getChildren().add(resultShape);
    }

    public void setupShapes() {
        double d = 100;
        double x = Math.sqrt(3 * Math.pow(d, 2) / 4);

        circleA.setCenterX(300.0);
        circleA.setCenterY(300.0 - d);
        circleA.setRadius(150);
        circleA.setFill(Color.TRANSPARENT);
        circleA.setStroke(Color.BLACK);
        circleA.setStrokeWidth(2);

        circleB.setCenterX(300.0 + x);
        circleB.setCenterY(300.0 + d / 2);
        circleB.setRadius(150);
        circleB.setFill(Color.TRANSPARENT);
        circleB.setStroke(Color.BLACK);
        circleB.setStrokeWidth(2);
    }
}

This code shows only simplifier version of my larger code, but ilustrates my problem complex way, I think the way I am doing it is maybe not the best. I would like to get your ideas to make this working properly. Thank you for your future comments and answers.

left -first code, right- second code

[Edit] My simple fxml:

<AnchorPane fx:controller="sample.Controller"
        xmlns:fx="http://javafx.com/fxml" prefHeight="720" prefWidth="1280">
<children>
    <AnchorPane fx:id="displayPane" layoutX="60.0" layoutY="60.0" prefHeight="600.0" prefWidth="600.0" />
</children>

When I change anchorPane to Pane nothing changes.

Upvotes: 1

Views: 69

Answers (1)

Maderaffie
Maderaffie

Reputation: 36

If you want to see details of your shapes and their location, you can print out them in the console using System.out.println(resultShape).

After doing this for both of your versions, you will notice the wrong one is translocated by 60.0 on the X-axis and the same on the Y-axis. It happens only when you add your resultShape after the circles, and it is caused by the values of layoutX and layoutY in the AnchorPane.

The circles' centres are set to specific values. If you intersect them before adding them to the Pane, your resultShape's location will be calculated using these values. After that, displayPane.getChildren().add() will translocate all three objects only once - this is the expected result.

When you try to get resultShape after adding circles to the AnchorPane, its location will be calculated using values that are already translocated by displayPane.getChildren().add(), and that would be a good location. Unfortunately, adding resultShape to that AnchorPane will move it once again - it will be translocated "twice".

There are some ways to deal with this problem:

1) add resultShape to main AnchorPane (the parent of displayPane) - you will avoid the second translocation.

2) intersect the circles before adding them to the displayPane (just like in the first version of the code) - all objects will translocate only once.

3) get rid of layoutX and layoutY if they're not necessary.

Hope that will help.

Upvotes: 2

Related Questions