JavaFX:带有CSS的动态着色窗口 [英] JavaFX: Dynamically Colored Window with CSS

查看:53
本文介绍了JavaFX:带有CSS的动态着色窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用JavaFX创建具有三种不同颜色的Pane对象:背景颜色,文本颜色和按钮颜色.这三种颜色中的每一种都是在运行时根据传递给该方法的自定义对象的值动态确定的.我想出了如何在我的代码中直接轻松实现此行为的方法,而且似乎可以利用控制器和initialize方法来通过FXML进行设置.但是我想知道是否有可能或建议使用CSS进行类似的设置.

I am attempting to create a Pane object with JavaFX that has three different colors: A color for the background, a color for the text, and a color for the buttons. Each of these three colors is determined dynamically at run-time, based on the values of a custom object passed into the method. I figured out how to implement this behavior directly in my code fairly easily, and it seems like I could make use of a controller and an initialize method to set it up with FXML. But I'm wondering if it would be possible or advisable to set something like this up with CSS.

据我所知,CSS并没有真正利用代码中的变量,而只是预先设置了硬编码的值.鉴于潜在组合的数量众多,为每个组合制作一张不同的表似乎没有太大的价值.仍然,我听说使用CSS是现代做法,所以我想知道是否可以使用单个工作表来制作多种不同类型的窗格,或者是否必须用自己的工作表来唯一定义每个可能的窗格,甚至而有关窗格的其他所有信息都是相同的.

As far as I can tell, CSS doesn't really make use of variables from the code, just hardcoded values to be set beforehand. Given the sheer number of potential combinations, it doesn't seem like it would be of much worth to make a different sheet for each one. Still, I heard that making use of CSS is modern practice, so I'm wondering if it's possible to use a single sheet to make multiple different types of Panes or if every possible Pane would have to be uniquely defined with its own sheet, even with everything else about the Pane being identical.

推荐答案

我同意@Sedrick在评论中提到的方法.

I agree with the approach of what @Sedrick has mentioned in the comments.

如果只想更改颜色而不修改其余CSS,则也可以遵循以下方法.如果您有一个非常大的CSS文件需要主题化,这将非常有用.

If you want to change only colors without modifying the rest of CSS, you can follow the below approach as well. This can be quite useful if you have a very large css file that needs to be themed.

基本思想是让所有的CSS都是一个基本的CSS文件.在该基本文件的.root类中,将所有颜色定义为变量.对于每个主题CSS,您只需要覆盖颜色变量即可.并将主题css文件加载到基本文件之上.这样,您将不会遇到任何可能的复制粘贴问题或缺少CSS问题:)

The basic idea is to have all your css is one base css file. Define all your colors as variables in .root class in that base file. And for each of your theme css, you just need to override the color variables only. And load the theme css file on top of base file. This way you will not encounter any possible copy-paste issues or missing css issues :)

下面是一个完整的工作示例:

A complete working example is below:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.stream.Stream;

public class DynamicStyling_Demo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        VBox root = new VBox();
        root.setAlignment(Pos.CENTER);
        root.setSpacing(10);
        Stream.of("Default", "Type1", "Type2", "Type3").forEach(type -> {
            Button button = new Button("Open " + type);
            button.setOnAction(e -> {
                Stage subStage = buildStage(type);
                subStage.initOwner(stage);
                if (!type.equalsIgnoreCase("default")) {
                    subStage.getScene().getStylesheets().add(this.getClass().getResource(type.toLowerCase() + ".css").toExternalForm());
                }
                subStage.show();
            });
            root.getChildren().add(button);
        });
        Scene sc = new Scene(root, 400, 400);
        sc.getStylesheets().add(this.getClass().getResource("base.css").toExternalForm());
        stage.setScene(sc);
        stage.show();
    }

    private Stage buildStage(String title) {
        Label label = new Label("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
        label.setWrapText(true);
        VBox.setVgrow(label, Priority.ALWAYS);
        Button btn = new Button("Sample Button");
        VBox pane = new VBox(label, btn);
        pane.getStyleClass().add("my-pane");

        StackPane subRoot = new StackPane(pane);
        subRoot.setPadding(new Insets(10));

        Stage subStage = new Stage();
        subStage.setTitle(title);
        subStage.setScene(new Scene(subRoot, 300, 300));
        subStage.getScene().getStylesheets().add(this.getClass().getResource("base.css").toExternalForm());
        return subStage;
    }

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

base.css:

.root{
   -fx-window-border: #444444;
   -fx-window-color: #999999;
   -fx-window-text: #111111;
   -fx-button-color: #555555;
}

.my-pane{
   -fx-border-width: 2px;
   -fx-border-color: -fx-window-border;
   -fx-background-color: -fx-window-color;
   -fx-padding: 10px;
   -fx-spacing: 10px;
}

.my-pane .label{
  -fx-text-fill: -fx-window-text;
  -fx-font-size: 16px;
}

.my-pane .button{
  -fx-base: -fx-button-color;
}

type1.css:

.root{
   -fx-window-border: red;
   -fx-window-color: yellow;
   -fx-window-text: brown;
   -fx-button-color: pink;
}

type2.css:

.root{
   -fx-window-border: green;
   -fx-window-color: lightblue;
   -fx-window-text: white;
   -fx-button-color: grey;
}

type3.css:

.root{
   -fx-window-border: brown;
   -fx-window-color: lightgreen;
   -fx-window-text: blue;
   -fx-button-color: yellow;
}

这篇关于JavaFX:带有CSS的动态着色窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆