SteeveDroz SteeveDroz - 1 month ago 5
Java Question

Why is the Circle hidden behind the Line?

Yes, the title looks like the set up of a joke and yet it isn't.

The problem



I am writing a program using JavaFX. I add some drawings in a Pane (standard Line, Circle, Rectangle, and so on from
javafx.scene.shape
). I have set a
onMouseEnter()
on some circles to change their color. That works great, except when I place a line like in the image below:

Connector bug

The circle
A
changes color normally until I add the line
B
. When I hover the circle
A
then, nothing happens.

I figured out by testing that there was a problem when the circle was in the bounding box of the line (if the circle is halfway in the bounding box, the half that is out behaves correctly and the one inside doesn't).

Is it a normal behavious? What can I do to prevent it?

Partial code



In ConnectorWidget.java:

Circle circle = new Circle(...);
circle.setOnMouseEntered(event -> circle.setFill(Color.RED));
circle.setOnMouseExited(event -> circle.setFill(Color.WHITE));
getChildren().add(circle);


In TransistorWidget.java:

ConnectorWidget base = new ConnectorWidget(...);
getChildren().add(base);


In WireWidget:

Line line = new Line(...);
getChildren().add(line);


A new
TransisorWidget
can be added to the main pane on click.

A new
WireWidget
can be created in the main pane after a click on a
ConnectorWidget
followed by a click on another
ConnectorWidget
.

The rest of the code can be found on GitHub (permalink to the last commit I have when asking the question).

NOTE: To run the code from GitHub, you need this library.

Answer

Obviously it has to do with the fact that one Node overlays the other Node here.

Imagine that you are using StackPane as Layout.Adding first the Circle and then the Line,if the Line includes some pixels that the Circle already does then some parts of the Circle will not be visible.

Here i can imagine 3 possible solutions.

1)If you are using a Canvas , choose which is drawn first.The Circle or the Line?

2)If you are using some kind of Layout ,the you can play with getChilder.add/addAll methods.So you add first the Circle and then the Line as children to the Layout.

3 and better)

Using a StackPane you can add the children however you want.Then you can use already existing Node class methods(toFront(); and toBack();)

For example imagine that the Line is infront of the Circle, then call Circle.toFront(); and the Circle will come to front.

Comments