包含包裹标签的对照皮肤的优选高度

时间:2015-05-12 10:50:15

标签: java javafx label javafx-8 textwrapping

我写了一个基本控件和它的皮肤。 label显示在皮肤的HBox中。如果没有足够的空间,此标签应包装其文本。

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);
        }
    }
}

但标签没有换行(显示省略号),因为我的控件的首选宽度未正确计算:

actual label behavior

我想要获得的是:

expected label behavior

如何配置皮肤来计算皮肤首选高度以获得所需的行为(我从不想要显示省略号)?

注意:

  • 我不想在标签或其他皮肤组件上设置明确的最大尺寸:label.setMaxWidth(150)。唯一的显式宽度集应该是BorderPane中的根start method。该宽度(150)可以是可变的,控制可以在不同的地方使用。
  • 这种基本控制当然是对真实控制的简化。真实的一个显示了几个Label里面的变量文本。
  • 如果我增加窗口高度直到它有足够的空间
  • ,标签会正确包裹
  • 此代码在OSX 10.10.2上的java 1.8.0_40-b27上运行

1 个答案:

答案 0 :(得分:1)

AFAIK,要将text打包到label,您应该为此标签定义width,因为请参阅setWrapText(Boolean)文档:

  

public final void setWrapText(boolean value)

     

设置属性wrapText的值。

     

物业描述:   如果文本 超过Labeled 的宽度,则此变量指示文本是否应换行到另一行。

此处声明 超出了标签 的宽度,您已为width定义了label,这就是为什么你可以当没有定义width时使用它。

所以你的代码应该是:

    Label label = new Label("This text should wrap because it is too long");
    label.setMaxWidth(150);
    label.setWrapText(true);

另一种方法是使用Text element代替Label,并使用setWrappingWidth()这样的方法:

Text t = new Text("This text should wrap because it is too long"  );
t.setWrappingWidth(150);

你会得到这个结果:

Wrap text result

<强>结论:

要包装文本(在LabelText元素中),您必须定义宽度,以便在超出此宽度时文本将返回到新行。

编辑:

为了让它更有活力并避免为您的标签设置宽度,如果您为PrefWidth设置borderPane,则可以使用static double WIDTH得到这个PrefWidth并将其设置为标签的MaxWidth,这是示例代码:

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);
        }
    }
}