2

カスタム 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

これは、カスタム コントロールを使用せずに TextFlow が TitledPane に直接配置されている場合には発生しません。

TitledPane で直接使用される TextFlow

Scenic Viewの使用TextFlow をカスタム コントロールで使用すると、コントロールのレイアウト境界が親の境界と異なることに気付きました。実際、親の境界は正しく計算されているようですが、使用されていません。

シーングラフ

これがこの問題の原因である可能性があります。スキンのすべての計算(最小/優先/最大)高さメソッドを実験しましたが、TitledPane を正しくサイズ変更することができませんでした。

カスタム コントロール/スキンで使用したときに TextFlow の動作が異なる理由と、TitledPane のサイズを正しく変更する方法を教えてください。

4

1 に答える 1

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 を呼び出すときに、-1 の代わりにノード幅を使用するようにスキンの computeMinHeight をオーバーライドします。

    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;
         }
    }
    
于 2015-12-18T14:00:48.173 に答える