简体   繁体   English

如何在不使用 css 的情况下以编程方式更改 JavaFX 中的 TreeView 颜色?

[英]How to change TreeView Color in JavaFX programmatically without using css?

I am trying to implement dark mode functionality.我正在尝试实现暗模式功能。 For that purpose I need to change the color of treeView to dark grey.为此,我需要将 treeView 的颜色更改为深灰色。 The following code is not working.以下代码不起作用。

treeView.setStyle("-fx-background-color:#242424;");

I am not using CSS separately.我没有单独使用 CSS。 So solution like the above code will be highly appreciated.所以像上面的代码这样的解决方案将受到高度赞赏。

You need to change the background colors of the cells.您需要更改单元格的背景 colors。 Doing this in Java code is tricky, because it forces you to use a custom cellFactory on the tree to access the cells.在 Java 代码中执行此操作很棘手,因为它会强制您使用树上的自定义cellFactory来访问单元格。 Instead, I recommend using an external style sheet.相反,我建议使用外部样式表。 You can do你可以做

.tree-cell {
    -fx-background-color:#242424;
}

By default, the background of a tree cell (and many other controls) is set to a "looked-up color" (essentially a CSS variable) called -fx-background .默认情况下,树单元格(和许多其他控件)的背景设置为名为-fx-background的“查找颜色”(本质上是 CSS 变量)。 The text in the tree cell (and again, in many other controls) is set to a color dependent on that value, so it will automatically become a light color if the background is dark (and vice-versa).树单元格中的文本(以及许多其他控件中的文本)设置为取决于该值的颜色,因此如果背景是暗的,它将自动变为浅色(反之亦然)。 So it's probably better to do所以这可能会更好

.tree-cell {
    -fx-background:#242424;
}

In general, for "theming" your application, the default stylesheet modena.css defines all colors in terms of a small collection of looked-up colors.通常,对于您的应用程序“主题化”,默认样式表modena.css定义了所有 colors 以查找 colors 的小集合。 Those colors, and their defaults, are那些 colors 及其默认值是

/* A light grey that is the base color for objects.  Instead of using
 * -fx-base directly, the sections in this file will typically use -fx-color.
 */
-fx-base: #ececec;


/* A very light grey used for the background of windows.  See also
 * -fx-text-background-color, which should be used as the -fx-text-fill
 * value for text painted on top of backgrounds colored with -fx-background.
 */
-fx-background: derive(-fx-base,26.4%);

/* Used for the inside of text boxes, password boxes, lists, trees, and
 * tables.  See also -fx-text-inner-color, which should be used as the
 * -fx-text-fill value for text painted on top of backgrounds colored
 * with -fx-control-inner-background.
 */
-fx-control-inner-background: derive(-fx-base,80%);
/* Version of -fx-control-inner-background for alternative rows */
-fx-control-inner-background-alt: derive(-fx-control-inner-background,-2%);

/* A bright blue for highlighting/accenting objects.  For example: selected
 * text; selected items in menus, lists, trees, and tables; progress bars */
-fx-accent: #0096C9;

/* Default buttons color, this is similar to accent but more subtle */
-fx-default-button: #ABD8ED;

/* A bright blue for the focus indicator of objects. Typically used as the
 * first color in -fx-background-color for the "focused" pseudo-class. Also
 * typically used with insets of -1.4 to provide a glowing effect.
 */
-fx-focus-color: #039ED3;
-fx-faint-focus-color: #039ED322;

So a good strategy for "theming" your entire application is to change the definitions of some of these and apply it to the root of the scene.因此,为整个应用程序“主题化”的一个好策略是更改其中一些的定义并将其应用于场景的根。 For example, a "dark mode" might be implemented just with例如,“暗模式”可能只用

.root {
  -fx-base: #242424 ;
  -fx-control-inner-background: derive(-fx-base,20%);
  -fx-control-inner-background-alt: derive(-fx-control-inner-background,-10%);
  -fx-accent: #006689;
  -fx-focus-color: #036E83;
  -fx-faint-focus-color: #036E8322;
}

Here's a complete example:这是一个完整的例子:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {


    @Override
    public void start(Stage stage) {

        TreeView<String> tree = createRandomTree();
        BorderPane root = new BorderPane(tree);

        HBox controls = new HBox(5,
            new Button("Click"),
            new Label("Choose one:"),
            new ComboBox<>(FXCollections.observableArrayList("One", "Two", "Three")),
            new TextField()
        );
        controls.setAlignment(Pos.CENTER);
        controls.setPadding(new Insets(5));
        root.setTop(controls);

        ListView<String> list = new ListView<>();
        IntStream.range(1, 51).mapToObj(i -> "Item "+i).forEach(list.getItems()::add);
        root.setLeft(list);


        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource("darkmode.css").toExternalForm());

        stage.setScene(scene);
        stage.show();
    }



    private TreeView<String> createRandomTree() {
        Random rng = new Random();
        List<TreeItem<String>> items = new ArrayList<>();
        TreeItem<String> root = new TreeItem<>("Item 1");
        root.setExpanded(true);
        items.add(root);
        TreeView<String> tree = new TreeView<>(root);
        for (int i = 2 ; i <=20 ; i++) {
            TreeItem<String> item = new TreeItem<>("Item "+i);
            item.setExpanded(true);
            items.get(rng.nextInt(items.size())).getChildren().add(item);
            items.add(item);
        }
        return tree ;
    }



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

}

Where darkmode.css is the CSS file above.其中darkmode.css是上面的 CSS 文件。 This gives:这给出了:

在此处输入图像描述

Note that if you really want to do this without an external CSS file, you can just set those inline styles directly on your root node:请注意,如果您真的想在没有外部 CSS 文件的情况下执行此操作,则可以直接在根节点上设置那些内联 styles :

Pane root = ... ;

root.setStyle(
        "  -fx-base: #242424 ;\n" + 
        "  -fx-control-inner-background: derive(-fx-base,20%);\n" + 
        "  -fx-control-inner-background-alt: derive(-fx-control-inner-background,-10%);\n" + 
        "  -fx-accent: #006689;\n" + 
        "  -fx-focus-color: #036E83;\n" + 
        "  -fx-faint-focus-color: #036E8322;");

And you could even just set them for a TreeView , which would apply them only to the tree:您甚至可以将它们设置为TreeView ,这会将它们仅应用于树:

TreeView<String> tree = new TreeView<>();

tree.setStyle(
        "  -fx-base: #242424 ;\n" + 
        "  -fx-control-inner-background: derive(-fx-base,20%);\n" + 
        "  -fx-control-inner-background-alt: derive(-fx-control-inner-background,-10%);\n" + 
        "  -fx-accent: #006689;\n" + 
        "  -fx-focus-color: #036E83;\n" + 
        "  -fx-faint-focus-color: #036E8322;");

but generally, using and external style sheet is better in a number of ways.但一般来说,使用和外部样式表在许多方面都更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM