I wrote a basic control and its skin. A label
is displayed in a HBox
in the skin. This label should wrap its text if there isn't enough space.
public class LabelWrap extends Application {
public static void main(String[] args) {
launch(LabelWrap.class);
}
@Override
public void start(Stage stage) throws Exception {
BasicControl basicControl = new BasicControl();
BorderPane borderPane = new BorderPane();
borderPane.setPrefWidth(150);
borderPane.setCenter(basicControl);
stage.setScene(new Scene(borderPane));
stage.centerOnScreen();
stage.show();
}
private static class BasicControl extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new BasicControlSkin(this);
}
}
private static class BasicControlSkin extends SkinBase<BasicControl> {
protected BasicControlSkin(BasicControl control) {
super(control);
VBox box = new VBox();
Label label = new Label("This text should wrap because it is too long");
label.setWrapText(true);
box.getChildren().add(label);
getChildren().add(box);
}
}
}
But the label does not wrap (the ellipsis is displayed) because the preferred width of my control is not correctly computed:
what i want to obtain is:
How can i configure the skin to compute the skin preferred height to obtain the desired behavior (i never want an ellipsis displayed) ?
Notes:
label.setMaxWidth(150)
. The sole explicit width set should be the root BorderPane
in the start method
. This width (150) could be variable, the control could be used in different place. Label
with variable texts inside.AFAIK, to wrap a text
in a label
you should define a width
to this label because referring to the setWrapText(Boolean) documentation:
public final void setWrapText(boolean value)
Sets the value of the property wrapText.
Property description: If a run of text exceeds the width of the Labeled, then this variable indicates whether the text should wrap onto another line.
Here the statement exceeds the width of the Labeled induce that you have already defined a width
for your label
, that's why you can't use it when there's no width
defined.
So your code should be:
Label label = new Label("This text should wrap because it is too long");
label.setMaxWidth(150);
label.setWrapText(true);
Another alternative is to use a Text element instead of a Label
and use the method setWrappingWidth()
like this:
Text t = new Text("This text should wrap because it is too long" );
t.setWrappingWidth(150);
And you will get this result:
Conclusion:
To wrap a text (either in a Label
or in a Text
element) you have to define a width so the text will return to a new line when we exceed this width.
And to make it a little bit more dynamic and avoid setting a width to your label, and if you are setting a PrefWidth
to your borderPane
you can use a static double WIDTH
that will get this PrefWidth
and set it to the MaxWidth
of the label, here's the example code:
public class LabelWrap extends Application {
static double WIDTH;
public static void main(String[] args) {
launch(LabelWrap.class);
}
@Override
public void start(Stage stage) throws Exception {
BasicControl basicControl = new BasicControl();
BorderPane borderPane = new BorderPane();
borderPane.setPrefWidth(150);
borderPane.setCenter(basicControl);
//get the PrefWidth value in the WIDTH attribute
WIDTH = borderPane.getPrefWidth();
stage.setScene(new Scene(borderPane));
stage.centerOnScreen();
stage.show();
}
private static class BasicControl extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new BasicControlSkin(this);
}
}
private static class BasicControlSkin extends SkinBase<BasicControl> {
protected BasicControlSkin(BasicControl control) {
super(control);
VBox box = new VBox();
Label label = new Label("This text should wrap because it is too long");
//set the WIDTH value to the label MaxWidth
label.setMaxWidth(WIDTH);
label.setWrapText(true);
box.getChildren().add(label);
this.getChildren().add(box);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With