JavaFX 8 - 向右侧的TitledPane添加图形

时间:2014-11-24 08:25:33

标签: java layout javafx-8

我想在TitledPane的标题中添加一个小图标。因此,我设置了一个空标题,并添加了一个HBox,其中包含LabelImageView图形。通过这种方式,图标显示在文本末尾附近。我希望它始终显示在TitledPane的右边框旁边。 我怎样才能做到这一点? 我还尝试使用BorderPane并将Label添加到中心,将ImageView添加到右侧,但BorderPane未获得TitledPane的最大大小。 所以我尝试将MaxWidth设置为Max-Value,但这没有帮助

有人知道该怎么办吗?

**编辑:**我创建的“自定义”控件将在stage.setOnShown中调用的方法中初始化。

public class CustomTitledPane extends TitledPane {
private Image alert;
private Image registered;
private Image deleted;
private ImageView img;

public CustomTitledPane(String titleText, Node node) {
    super(titleText, node);
    setAnimated(true);
    setCollapsible(true);
    img = new ImageView();
    img.setFitHeight(10d);
    img.setPreserveRatio(true);
    img.setSmooth(true);
    setGraphic(img);
    setContentDisplay(ContentDisplay.RIGHT);
    // apply css and force layout of nodes
    applyCss();
    layout();

    // title region
    Node titleRegion = lookup(".title");
    // padding
    Insets padding = ((StackPane) titleRegion).getPadding();
    // image width
    double graphicWidth = img.getLayoutBounds().getWidth();
    // arrow
    double arrowWidth = titleRegion.lookup(".arrow-button")
            .getLayoutBounds().getWidth();
    // text
    double labelWidth = titleRegion.lookup(".text").getLayoutBounds()
            .getWidth();

    double nodesWidth = graphicWidth + padding.getLeft()
            + padding.getRight() + arrowWidth + labelWidth;
    System.out.println("w: " + graphicWidth + " " + arrowWidth + " "
            + labelWidth);
    graphicTextGapProperty().bind(widthProperty().subtract(nodesWidth));
    try {
        alert = new Image(new FileInputStream("img/Alert.png"));
        registered = new Image(new FileInputStream("img/Registered.png"));
        deleted = new Image(new FileInputStream("img/Deleted.png"));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
} }

这是TitledPane的CSS:

    .titled-pane {
    -fx-text-fill: #006FD8;
}

.titled-pane > .title {
    -fx-background-color: transparent;
    -fx-border-color: linear-gradient(to right, white 0%, grey 30%, grey 70%, white 100%) transparent transparent transparent;
}

.titled-pane:expanded > .title {
    -fx-border-color: grey transparent transparent transparent;
    -fx-background-color: linear-gradient(to bottom, #DCE7F5, white);
}

.titled-pane:expanded > *.content {
    -fx-border-width: 0;
}

2 个答案:

答案 0 :(得分:2)

没有必要在一个框中包装图形和文字,因为您可以选择如何使用setContentDisplay()显示您的内容:

title.setContentDisplay(ContentDisplay.RIGHT);

一旦你有了右边的图像,你需要设置图像和文本之间的差距。为此,一旦显示舞台,我们就可以使用一些查找来获得标题中节点的真实尺寸。

最后,我们将间隙空间绑定到标题的width属性,减去这些维度。

修改

示例现在支持在显示舞台之前创建。

@Override
public void start(Stage primaryStage) {
    Scene scene = new Scene(new StackPane(), 300, 250);

    primaryStage.setScene(scene);

    primaryStage.setOnShown(e -> {
        TitledPane title = new TitledPane("Title",
                new StackPane(new Label("Graphic to the Right")));

        ImageView imageView = new ImageView(new Image(getClass().getResource("unlock24.png").toExternalForm()));

        title.setGraphic(imageView);
        title.setContentDisplay(ContentDisplay.RIGHT);

        scene.setRoot(title);

        // apply css and force layout of nodes
        title.applyCss();
        title.layout();

        // title region
        Node titleRegion=title.lookup(".title");
        // padding
        Insets padding=((StackPane)titleRegion).getPadding();
        // image width
        double graphicWidth=imageView.getLayoutBounds().getWidth();
        // arrow
        double arrowWidth=titleRegion.lookup(".arrow-button").getLayoutBounds().getWidth();
        // text
        double labelWidth=titleRegion.lookup(".text").getLayoutBounds().getWidth();

        double nodesWidth = graphicWidth+padding.getLeft()+padding.getRight()+arrowWidth+labelWidth;  

        title.graphicTextGapProperty().bind(title.widthProperty().subtract(nodesWidth));
    });

    primaryStage.show();

}

这就是它的样子:

Titled Pane

答案 1 :(得分:2)

根据OP在其编辑问题上显示的代码,此代码解决了在自定义类上显示舞台之前在侦听器上创建标题窗格的事实。

@Override
public void start(Stage primaryStage) {

    Scene scene = new Scene(new StackPane(), 300, 250);

    primaryStage.setScene(scene);

    primaryStage.setOnShown(e -> {
        CustomTitledPane customTitledPane = new CustomTitledPane("Title", new StackPane(new Label("Graphic to the Right")));
        scene.setRoot(customTitledPane);
        customTitledPane.applyCss();
        customTitledPane.layout();

        // title region
        Node titleRegion=customTitledPane.lookup(".title");
        // padding
        Insets padding=((StackPane)titleRegion).getPadding();
        // image width
        double graphicWidth=customTitledPane.getGraphic().getLayoutBounds().getWidth();
        // arrow
        double arrowWidth=titleRegion.lookup(".arrow-button").getLayoutBounds().getWidth();
        // text
        double labelWidth=titleRegion.lookup(".text").getLayoutBounds().getWidth();

        double nodesWidth = graphicWidth+padding.getLeft()+padding.getRight()+arrowWidth+labelWidth;

        customTitledPane.graphicTextGapProperty().bind(customTitledPane.widthProperty().subtract(nodesWidth));
    });

    primaryStage.show();

}

class CustomTitledPane extends TitledPane {

    public CustomTitledPane(String titleText, Node node) {
        super(titleText, node);
        setAnimated(true);
        setCollapsible(true);
        ImageView img = new ImageView(new Image(getClass().getResource("unlock24.png").toExternalForm()));
        img.setFitHeight(10d);
        img.setPreserveRatio(true);
        img.setSmooth(true);
        setGraphic(img);
        setContentDisplay(ContentDisplay.RIGHT);
    }
}