我在自定义JavaFX控件中使用带有Text的TextFlow,并将此控件放在TitledPane中。
控制声明:
public class CustomControl extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new CustomControlSkin(this);
}
}
皮肤声明:
public class CustomControlSkin extends SkinBase<CustomControl> implements Skin<CustomControl> {
public CustomControlSkin(CustomControl customControl) {
super(customControl);
TextFlow textFlow = new TextFlow();
textFlow.getChildren().add(new Text("This is a long long long long long long long long long long long long long long text"));
getChildren().add(new StackPane(textFlow));
}
}
申请:
@Override
public void start(Stage primaryStage) throws Exception {
TitledPane titledPane = new TitledPane();
titledPane.setContent(new CustomControl());
Scene scene = new Scene(new StackPane(titledPane));
primaryStage.setScene(scene);
primaryStage.show();
}
当场景水平调整大小时,文本会被包裹并且其高度会增加。但是,TitledPane没有垂直调整大小。
当TextFlow直接放在TitledPane中而不使用自定义控件时,不会发生这种情况。
使用Scenic View我注意到,当在自定义控件中使用TextFlow时,控件的布局边界与父级中的边界不同。实际上,父级中的边界似乎是正确计算的,但未使用。
这可能是此问题的根源。我已经尝试了所有计算(Min / Pref / Max)皮肤的高度方法,但没有设法正确调整TitledPane的大小。
任何想法为什么TextFlow在自定义控件/皮肤中使用时表现不同以及如何正确调整TitledPane的大小?
答案 0 :(得分:2)
我向Oracle报告了此问题,并将其视为JavaFX错误:JDK-8144128
作为此错误的解决方法,我已完成以下操作:
将控件内容偏向设置为Orientation.HORIZONTAL
public class CustomControl extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new CustomControlSkin(this);
}
@Override
public Orientation getContentBias() {
return Orientation.HORIZONTAL;
}
}
在调用node.minHeight时,覆盖皮肤computeMinHeight以使用节点宽度而不是-1
public class CustomControlSkin extends SkinBase<CustomControl> implements Skin<CustomControl> {
public CustomControlSkin(CustomControl customControl) {
super(customControl);
TextFlow textFlow = new TextFlow();
textFlow.getChildren().add(new Text("This is a long long long long long long long long long long long long long long text"));
getChildren().add(new StackPane(textFlow));
}
@Override
protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
double minY = 0;
double maxY = 0;
boolean firstManagedChild = true;
for (int i = 0; i < getChildren().size(); i++) {
Node node = getChildren().get(i);
if (node.isManaged()) {
final double y = node.getLayoutBounds().getMinY() + node.getLayoutY();
if (!firstManagedChild) {
minY = Math.min(minY, y);
maxY = Math.max(maxY, y + node.minHeight(width));
} else {
minY = y;
maxY = y + node.minHeight(width);
firstManagedChild = false;
}
}
}
double minHeight = maxY - minY;
return topInset + minHeight + bottomInset;
}
}