javafx - 同时使用 CSS 和 setStyle

标签 javafx javafx-2

我有一个对象,我用 CSS 对该对象进行样式化。在我的程序中,我想更改样式中的特定元素,例如背景颜色。我遇到的问题是,当我调用 setStyle(-fx-background-color:red) 时,它将覆盖所有样式元素。即使我只是改变背景颜色。

#header {
-fx-background-color: #4d4d4d;
-fx-border-color:  #545454;
-fx-border-width: 1px;
-fx-border-style: solid;
}
#header:hover {
-fx-background-color: #9ACD32;
}

最佳答案

您应该使用“查找的颜色”在 CSS 中定义颜色。

参见 JavaFX CSS reference了解详情。

Looked-up Colors

With looked-up colors you can refer to any other color property that is set on the current node or any of its parents. This is a very powerful feature, as it allows a generic palette of colors to be specified on the scene then used thoughout the application. If you want to change one of those palette colors you can do so at any level in the scene tree and it will affect that node and all its decendents. Looked-up colors are not looked up until they are applied, so they are live and react to any style changes that might occur, such as replacing a palette color at runtime with the "style" property on a node.

In the following example, all background color of all buttons uses the looked up color "abc".

.root { abc: #f00 }
.button { -fx-background-color: abc }

示例应用程序

background-setting

在示例应用中,关键代码是在代码中动态设置查找的颜色值:

headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
    @Override
    public void changed(
        ObservableValue<? extends Toggle> observableValue, 
        Toggle oldToggle, 
        Toggle newToggle
    ) {
        RadioButton radio = (RadioButton) newToggle;
        header.setStyle("header-base-color: " + radio.getText());
    }
});

连同 header-base-color 颜色的查找 id 在下面的 css 中的定义:

header-color.css

.root {
   header-base-color: #4d4d4d;
}

#header {
  -fx-background-color: header-base-color;
  -fx-border-color:  #545454;
  -fx-border-width: 1px;
  -fx-border-style: solid;
}

#header:hover {
  -fx-background-color: #9ACD32;
}

header-color.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?scenebuilder-stylesheet header-color.css?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import java.net.URL?>

<BorderPane id="BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="HeaderColorController">
  <top>
    <HBox fx:id="header" prefHeight="-1.0" prefWidth="-1.0">
      <children>
        <Label text="A really hard to read label" />
      </children>
    </HBox>
  </top>
  <center>
    <VBox prefHeight="-1.0" prefWidth="-1.0" spacing="10.0" style="-fx-background-color: azure;">
      <children>
        <RadioButton mnemonicParsing="false" style="-fx-text-fill: forestgreen;" text="forestgreen">
          <toggleGroup>
            <ToggleGroup fx:id="headerColorToggleGroup" />
          </toggleGroup>
        </RadioButton>
        <RadioButton mnemonicParsing="false" style="-fx-text-fill: firebrick;" text="firebrick" toggleGroup="$headerColorToggleGroup" />
        <RadioButton mnemonicParsing="false" selected="true" style="-fx-text-fill: #4d4d4d;" text="#4d4d4d" toggleGroup="$headerColorToggleGroup" />
      </children>
      <padding>
        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
      </padding>
    </VBox>
  </center>
  <stylesheets>
    <URL value="@header-color.css" />
  </stylesheets>
</BorderPane>

HeaderColorApp.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class HeaderColorApp extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("header-color.fxml"));
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

HeaderColorController.java

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.value.*;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;

public class HeaderColorController {

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private HBox header;

    @FXML
    private ToggleGroup headerColorToggleGroup;

    @FXML
    void initialize() {
        assert header != null : "fx:id=\"header\" was not injected: check your FXML file 'header-color.fxml'.";
        assert headerColorToggleGroup != null : "fx:id=\"headerColorToggleGroup\" was not injected: check your FXML file 'header-color.fxml'.";

        headerColorToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            @Override
            public void changed(ObservableValue<? extends Toggle> observableValue, Toggle oldToggle, Toggle newToggle) {
                RadioButton radio = (RadioButton) newToggle;
                header.setStyle("header-base-color: " + radio.getText());
            }
        });
    }    
}

关于javafx - 同时使用 CSS 和 setStyle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21385117/

相关文章:

java - 从另一个类引用 @FXML TextField,但收到 NullPointerException

JavaFX - 使用 mediaplayer 和 mediaview 播放视频

java - 获取节点上的鼠标位置相对于它的坐标和变换

java - 使用 DbUtils BeanListHandler 在可重用 JavaFX 数据检索服务上摸索通用类型

JavaFX - 保存/加载 - 形状/布局

java - 在 Mac 上运行 JavaFx 应用程序时出错

java - 使用枚举数据填充 JavaFX TableView

JavaFX 任务可调用

java - 如何以编程方式打开新的浏览器窗口

java - FXMLLoader.load 无法解析为类型