2014-11-24 67 views
3

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

有谁知道该怎么办?

**编辑:**我创建的“自定义”控件将在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

基于通过对他的编辑问题的任择议定书中的代码,这段代码解决了标题窗格上创建的事实在舞台显示之前的听众,在自定义类上。

@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); 
    } 
} 
+0

但是当我在场景中有另一个节点时,我无法将场景的根设置为标题栏,或者我错了吗? – 2014-11-24 13:34:18

+1

我使用的是简单的根。您只需将您的标题栏作为孩子添加到适当的容器中即可。 – 2014-11-24 13:35:30

+0

现在工作。非常感谢你的帮助! – 2014-11-24 13:41:07

2

没有必要包装图形和文字在一个盒子里,因为你可以选择如何与setContentDisplay()显示您的内容:

title.setContentDisplay(ContentDisplay.RIGHT); 

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

最后,我们将间隙空间绑定到标题的宽度属性,然后减去这些尺寸。

EDIT

样品现在支持创建示出了阶段之前。

@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

+0

感谢您的快速回答,但是我在'.getPadding()'和每个'.lookup()'方法都得到'NullPointerException'? – 2014-11-24 10:20:45

+0

'lookup'试图找到一个CSS选择器。它返回一个Node,或者如果找不到选择器,则返回null。你是否将自定义CSS应用于你的标题栏?那么你应该寻找你的选择器。无论如何,尝试运行我的示例并检查它是否适合您。 – 2014-11-24 10:24:03

+0

是的,我正在应用自定义CSS,但这不是问题,因为您的示例在测试应用程序中可以正常工作。那么还有什么可能导致NullPointerException? – 2014-11-24 10:39:12