【问题标题】:JavaFX-CSS: How to "move" style of parent to a child?JavaFX-CSS:如何将父母的风格“移动”给孩子?
【发布时间】:2015-03-22 16:36:47
【问题描述】:

触发此问题的原因是解决TreeItem selection width 的快速实验:要求仅突出显示文本,而不是整个树单元格。没有比这更容易的了(弗雷德里克说 :)

  • 实现一个自定义 TreeCell,将标签作为图形(并根据需要配置带有项目的标签)
  • 删除选择样式(主要是从单元格中突出显示背景
  • 为标签添加高亮样式

类似的东西(最后是一个使用这个的可运行示例):

public static class MyTreeCell extends TreeCell<String> {

    private Label label;

    public MyTreeCell() {
        getStyleClass().add("tree-text-only");
    }
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if (label == null) {
                label = new Label();
            }
            label.setText(item);
            setGraphic(label);
        }
    }
}

CSS:

/* remove the highlight from cell as a whole, 
   c&p'd the unselected style from modena */
.tree-text-only:filled:selected {
    -fx-background: -fx-control-inner-background; 
    -fx-background-color: -fx-background;
}
/* c&p'd selected style */
/* using > doesn't make a different to the behaviour */ 
/* .tree-text-only:filled:selected > .label { */

.tree-text-only:filled:selected .label {
    /* following is the selection color from themes, doesn't show */
    -fx-background: -fx-selection-bar; 
    /* hard-coded color does show */
    /*   -fx-background-color: -fx-accent ; */
    /* auto-adjust text fill */
    /* no effect for hard-coded color, showing nothing for selection bar */
    -fx-text-fill: -fx-text-background-color;
}

预期行为

  • 标签在使用选择栏时突出显示背景
  • 文本自动调整其填充

实际行为:

  • 使用“语义”(?) 突出显示颜色选择栏,标签的背景颜色不会更改为突出显示颜色但文本填充更改为“白色”,因此文本不显示
  • 使用硬编码颜色(任何颜色,甚至是上面的重音)会更改标签的背景,但不会更新文本填充

显而易见的问题:如何让它按预期工作?

为方便起见,举个可运行的例子:

public class TreeCellExample extends Application {

    public static class MyTreeCell extends TreeCell<String> {

        private Label label;

        public MyTreeCell() {
            getStyleClass().add("tree-text-only");
        }
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (label == null) {
                    label = new Label();
                }
                label.setText(item);
                setGraphic(label);
            }
        }
    }

    private Parent getContent() {
        TreeItem root = createSubTree("root");
        root.setExpanded(true);
        TreeView tree = new TreeView(root);
        tree.getStylesheets().add(
                getClass().getResource("treetextonly.css").toExternalForm());
        tree.setCellFactory(p -> new MyTreeCell());
        BorderPane pane = new BorderPane(tree);
        return pane;
    }

    ObservableList rawItems = FXCollections.observableArrayList(
            "9-item", "8-item", "7-item", "6-item", 
            "5-item", "4-item", "3-item", "2-item", "1-item");

    protected TreeItem createSubTree(Object value) {
        TreeItem child = new TreeItem(value);
        child.getChildren().setAll((List<TreeItem>) rawItems.stream()
                .map(TreeItem::new)
                .collect(Collectors.toList()));
        return child;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(getContent());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【问题讨论】:

  • &gt; css 语法可能会对您有所帮助。这意味着您可以指定子组件的样式
  • @eugener 感谢您的建议,但没有任何区别(使用变体编辑 css)
  • 如果我查看modena.css,我会看到以下内容:-fx-selection-bar: -fx-accent; 那么,如果它有效,为什么不直接使用-fx-background-color: -fx-accent;
  • @eckig 是的,我知道它看起来一样 - 但似乎在某种程度上/在哪里有所不同。为什么一个工作而另一个不工作?我认为额外的间接(重音->选择)是有原因的,所以为了获得最高抽象的可用选择感觉更合适另请注意,文本填充不会用重音更新(它是有选择的,即使它没有显示)......真的很奇怪

标签: java javafx-8 treecell javafx-css


【解决方案1】:

同样,我不能 100% 确定我理解您的要求,但以下快速测试对我有用(Label 分配给 Button 的图形属性):

.button {
    -fx-text-fill: red;
    -fx-background-color: yellow;
}

.button > .label {
    -fx-text-fill: blue;
    -fx-background-color: yellow;
}

.button:pressed > .label {
    -fx-text-fill: white;
    -fx-background-color: black;
}

【讨论】:

  • 是的,我注意到硬编码正在起作用(可能不够清楚,抱歉) - 但为什么它没有“语义”颜色?
【解决方案2】:

它不起作用的原因是因为.label 没有应用-fx-background 的规则,因此分配给它的任何值都不会影响任何Label 属性。

此外,Label 不使用 -fx-background-color 属性。

所以一个简单的解决方案是添加它:

.tree-text-only > .label {
    -fx-background-color: -fx-background; 
}

现在您可以仅使用这种“语义”颜色来应用所有样式。

注意,我还添加了控件没有焦点的情况:

/* 
 * remove the highlight from cell as a whole 
 */

/* Selected rows */
.tree-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-text-only:filled:selected {
    -fx-background: -fx-control-inner-background; 
}
/* Selected when control is not focused */
.tree-text-only:filled:selected {
    -fx-background: -fx-control-inner-background; 
}
/* focused cell (keyboard navigation) */
.tree-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-text-only:focused {
    -fx-cell-focus-inner-border: -fx-control-inner-background; 
}

/* 
 * highlight only the label
 */

// Add background color rule
.tree-text-only > .label {
    -fx-background-color: -fx-background; 
}
/* Selected rows */
.tree-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-text-only:filled:selected > .label {
    -fx-background: -fx-selection-bar; 
}
/* Selected when control is not focused */
.tree-text-only:filled:selected > .label {
    -fx-background: -fx-selection-bar-non-focused;
}
/* focused cell (keyboard navigation) */
.tree-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-text-only:focused > .label {
    -fx-background: -fx-selection-bar; 
}

【讨论】:

  • 愚蠢地将规则与颜色值混为一谈 - 难怪它不起作用 ;-) 再次感谢您的详尽解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
相关资源
最近更新 更多