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

gon*_*ard 11 java label javafx word-wrap javafx-8

我写了一个基本的控件和它的皮肤.A 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

实际标签行为

我想要获得的是:

预期的标签行为

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

笔记:

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

cнŝ*_*ŝdk 1

AFAIK,要将 a 包装text在 a 中label,您应该为此标签定义 a width,因为参考setWrapText(Boolean)文档:

公共最终无效setWrapText(布尔值)

设置属性wrappText的值。

属性描述: 如果一段文本超过 Labeled 的宽度,则此变量指示文本是否应换行。

这里的语句超出了 Labeled 的宽度,导致您已经width为您的定义了 a label,这就是为什么在没有定义的情况下不能使用它width

所以你的代码应该是:

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

另一种选择是使用Text 元素而不是 a并使用如下Label方法:setWrappingWidth()

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

你会得到这样的结果:

文本换行结果

结论:

要换行文本(无论是在 a 中Label还是在Text元素中),您必须定义宽度,以便当超过此宽度时文本将返回到新行。

编辑:

为了使其更加动态并避免为标签设置宽度,如果您将 a 设置PrefWidth为您的borderPane,则可以使用 astatic 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)