I need to dynamically create Rectangles over Pane in JavaFX 2.1. Next I need to center/wrap/truncate Text over the Rectangle. The text has to fit within the rectangle. I am able to center and wrap the text with the following code, however, if the text length is too long, it will appear out of the rectangle. I want to create the behavior like Label within StackPane, essentially if the Rectangle grows, the Text will grow with it but always remain in the center of the Rectangle and if the Text cannot fit within the Rectangle, it will be truncated accordingly.
Rectangle r;
Text t;
...
//center and wrap text within rectangle
t.wrappingWidthProperty().bind(rect.widthProperty().multiply(0.9);
t.xProperty().bind(rect.xProperty().add(rect.widthProperty().subtract(t.boundsInLocalProperty().getValue().getWidth().divide(2)));
t.yProperty().bind(rect.yProperty().add(rect.heightProperty().divide(2)));
t.setTextAlignment(TextAlignment.CENTER);
t.setTextOrigin(VPos.CENTER);
What properties can I use to achieve that or is there a better way of doing this?
Here is a sample alternate implementation.
It uses a subclass of
Group
with alayoutChildren
implementation rather than the binding api.Sample output of the sample app:
A couple of notes:
It is usually best to use a
Label
rather than trying to recreate part of a Label's functionality.The layout in
layoutChildren
approach is a similar to that used by the JavaFX team in implementing the JavaFX control library. There are probably reasons they uselayoutChildren
rather than binding for layout, but I am not aware of what all of those reasons are.I find for simple layouts, using the pre-built controls and layout managers from the JavaFX library is best (for instance the above control could have been implemented using just a Label or Text in StackPane). Where I can't quite get the layout I need from the built-in layouts, then I will supplement their usage with bindings, which I find also very easy to work with. I don't run into the need to use
layoutChildren
that much. It's probably just a question of scaling up to lay out complex node groups - most likely doing the calculations in thelayoutChildren
method performs better and may be easier to work with and debug when applied to complex node groups.Rather than truncating
Text
by calculating a text size and eliding extra characters from aString
as aLabel
does, the code instead callssetClip
on the text node to visually clip it to the rectangle's size. If instead you would like to truncateText
more like aLabel
, then you could look at the code for the JavaFX utility class which does the computation of clipped text.The sample code in the question does not compile because it is missing a bracket on the
wrappingWidthProperty
expression and it usesgetValue
andgetWidth
methods inside a bind expression, which is not possible - instead it needs to use a listener on theboundsInLocalProperty
.Also, created a small sample app demoing adding text placed in a Label with a rectangular background to a Pane with precise control over the x,y position of the labeled rectangle via binding.