Issue
I have a general question about the image below. I am a bit confused about how I can create such a component with JavaFX. Each division of the ship graphic below function as a button on itself also changes dynamically as: "dimensions colors etc".
I am not sure if this can be created dynamically with SVG Paths or 2D objects or it is better to use file 2D-3D file types like (".obj, .stl ... etc"). If anyone has been faced before with this situation is welcome to leave an answer and opinion to discuss it.
Solution
Answer Clarifier
When I first read your question, I assumed it was about picking or selecting parts of the image in your question, but perhaps it is not and is only about how to represent and draw the object rather an interact with parts of it. If no interaction is required, you can ignore the picking portions of the answer and just look at the shape representation portion.
Picking
There are a variety of ways you could achieve the described results. The technical term for what you are trying to achieve is "picking", but there are a lot of things beyond picking which might influence how you represent your objects and, whether you use a 2D or 3D system and even whether JavaFX is the most appropriate framework for your application. You might need a 3D system, or a 2D system might suffice in your case (I don't know).
Related information:
PickResult
Sample handler from the linked picking article:
EventHandler<MouseEvent> moveHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
PickResult res = event.getPickResult();
// do something with the pick result.
event.consume();
}
}
That picking article uses a PickResult
. The PickResult can interpret both 2D and 3D information. In the case of 2D information, usually just the node picked is relevant. In the case of 3D picking it provides additional information such as texture co-ordinates and the 3D face picked.
Convenience methods such as setOnMouseClicked
Usually in 2D, you don't require a lot of additional information beyond which nodes have been selected. In this case, you don't need to query and look at all of the information in the PickResult. You can make use of the "convenience methods" for user interaction handling such as setOnMouseClicked
. Set a click handler on all of your nodes and you will be able to action each node as it is clicked (similar to how buttons function) via its related click handler.
For irregular shapes, you probably want to ensure you have setPickOnBounds(false)
. Also note that, if pick on bounds is false, and you want a click inside an irregular shape to register, the inside of the shape must be filled with a color (unlike in your picture). If necessary the color can be translucent, but not completely transparent. This is because if you don't have anything to click on, the click won't register.
Binding on hover
See the smurf answer to this question for an example of taking an action when the hover property of a node changes status.
Implementing your own hit-testing
When you have nodes in the scene graph, then you can make use of JavaFX in-built system of hit-testing for pick correlation.
Another alternative is to render your images within a Canvas without making use of the scene graph, and then implement your own hit-testing algorithm and use that. That is the solution illustrated in trashgod's answer to:
This can get complicated if you use a painter's algorithm to render complicated overlapping shapes within the canvas. Therefore, I'd recommend making use of the scene graph with either 2D or 3D shapes rather than using a canvas for this task.
Shape Representation
Sample ways you could do this:
- 3D meshes imported from 3D data files.
- Collections of 2D
SVGPaths
. - Collections of 2D
Images
.
Which representation to choose depends on the application as some will be better suited for different purposes. For the image you show in your question, where you appear to have various orthographic projections of the same object, using a ParallelCamera
to render 3D representations onto a 2D plane might be best. For many other applications, bitmapped 2D images are best.
To represent irregular 2D shapes you can use an SVGPath
if you have the appropriate path info. If you don't have the appropriate path info, it will be challenging for your to use a 2D system to represent a complex set of images like you have in your question (it will probably be challenging for you even with path info).
Another option for shape representation are Image
s read from bitmap files such as PNG which have transparent backgrounds to allow for irregular shapes.
Aside
This question is probably going to get closed as not focused enough, because that is just what happens to questions like this. This answer is similarly more general in scope rather than specific and, in particular, does not provide the complete code (or really any code at all) for you to implement a solution to the problem you outlined in your question.
Answered By - jewelsea