Declaring Variable In JavaFX CSS File
Asked Answered
C

5

29

I've been inspecting the "caspian.css" distributed by Oracle in the JavaFX runtime library, and I see they have declared some color values as variables. Eg:

-fx-base: #d0d0d0; // Caspian.css, Line 47

...and then they used it as value of some other property, like:

-fx-color: -fx-base; // Caspian.css, Line 96

Now, what I want to do is to declare a measurement unit (-fx-radius-default: 10px) and then use it everytime I need to set radius of a control, for instance:

-fx-border-radius: -fx-radius-default;
-fx-background-radius: -fx-radius-default;

I have been unsuccessful so far. My question is: Is this possible, at all?

Details

Here is my Experiment.fxml file that I created on JavaFX Scene Builder 1.1:

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

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <TextArea layoutX="200.0" layoutY="119.0" prefWidth="200.0" styleClass="track" wrapText="true" />
  </children>
  <stylesheets>
    <URL value="@css/Experiment.css" />
  </stylesheets>
</AnchorPane>

And below is the css/Experiment.css that I have used:

* {
    -fx-radius-default: 10px;
}
.track {
    -fx-border-radius: -fx-radius-default;
    -fx-border-color: black;
}

Unfortunately this doesn't work, giving an error message like this:

Could not resolve '-fx-radius-default' while resolving lookups for '-fx-border-radius' from rule '*.track' in stylesheet file: /home/abdullah/codebase/src/package/css/Experiment.css

If I use plain syntax (-fx-border-radius: 10px), there is no problem with that.

What am I doing wrong here?

Cain answered 26/11, 2012 at 13:50 Comment(1)
I don't know if it would be easy or practical to implement, but currently it looks like JavaFX's classes which define their own css properties use the javafx.css.CssMetaData classApelles
B
37

Unfortunately it seems to work only for colors. But you need to ensure that your variable is "visible" from rule which uses it:

* {
   -fx-base2: #e00;
}
.track {-fx-background-color: -fx-base2;}
Buxton answered 26/11, 2012 at 14:17 Comment(3)
I've added some details to my question after your answer. Can you review it? Thanks.Cain
I asked the same question on OTN JavaFX2 forums too. If nobody else comes with a positive answer (or a workaround), I will accept your answer. Thanks for replying.Cain
Even if JavaFX supports variables only for colors, it helps very much. Thank you for sharing this important information.Chapnick
O
7

I know it is a quite old question but I couldn't find any answer with a similar approach as mine. As the previous answer already says it is not possible with standard css except for colors. (Please correct me if I am wrong)

Nevertheless, it is possible if you are using less. I use less in one of my JavaFX projects and it works really well. You just have to configure your build process to compile your less files and generate the actual css files. I used maven in my project and below you can find my build configuration.

<build>
    <!-- exclude less files from output directory -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.less</exclude>
            </excludes>
        </resource>
    </resources>

    <plugins>

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.2</version>
        </plugin>

        <plugin>
            <groupId>com.zenjava</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>8.7.0</version>
            <configuration>
                <mainClass>com.example.project.Main</mainClass>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.example.project.Main</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </plugin>

        <!-- maven less plugin which I'm using to compile the less files -->
        <plugin>
            <groupId>biz.gabrys.maven.plugins</groupId>
            <artifactId>lesscss-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirectory>${project.basedir}/src/main/resources/com/example/project</sourceDirectory>
                        <outputDirectory>${project.build.outputDirectory}/com/example/project</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

With this configuration I'm now able to use less and there is no problem to define custom variables. I use a color-catalogue.less file in my project which all other less files can import via the import attribute. Maybe this solution helps anyone.


Edit: If anyone is interested, a working example can be found here.

Oldline answered 23/1, 2017 at 11:36 Comment(2)
will be nice if you create a working sample with less and variables and upload it to github. What you think? thanksCeciliacecilio
Just wanted to add it is also possible with sass/scss, which after a short comparison, I found better for my purposes.Boniface
R
7

I aways separate my css code.

I create a importer file named all.css with code bellow:

@import url("Root.css");
@import url("Base.css");
...

In Root.css file, i set the variables:

.root {
    -fx-color1: #FFFF00;
    -fx-color2: rgb(255,255,0);
    -fx-color3: rgba(255,255,0, 0.5);
}

Now, i can call variables in all bellow of imported code after import(Root.css). In Base.css for example.

.bg-yellow1 {
    -fx-background-color: -fx-color1;
}

That's it!

Ramshackle answered 25/6, 2019 at 22:53 Comment(1)
Welcome to StackOverflow. The OP is trying to set a variable for a measurement unit and, as stated in their question and the accepted answer, variables can only be used for colours. So, whilst your answer is appreciated, it doesn't really provide any additional information from the existing answers.Manouch
B
5

Just a little correction to your answers: it is possible also with numbers, not only colors.

For example:

*{
    -preferred-scroll-bar-thumb-size: 25;
}

.scroll-bar:vertical .thumb {
    -fx-pref-width: -preferred-scroll-bar-thumb-size;
}

Works for me, and JavaFx taking the value '25' as '25px' (if I wrote '25px' it would fail). It's not exactly variables as with using less/sass but it can help people that don't need more than this.

Boniface answered 4/6, 2018 at 8:47 Comment(2)
I have not been able to confirm this, I get error trying to define font sizes.Thiele
Also unable to confirm this. Using a number causes a ClassCastException, java.lang.Double cannot be case to com.sun.javafx.css.SizeSethsethi
W
1

In addon for grill2010's solution:
I recommend to use SCSS with maven's builder (plugin) into CSS in "generate-resources" stage. So, You can use variables with any numbers or colors for any selector.

I'm using this scenario, and it works fine :)

P.S. You cannot do that directly in the CSS file for current OpenJFX versions.

           <plugins>
                <plugin>
                <groupId>com.github.warmuuh</groupId>
                <artifactId>libsass-maven-plugin</artifactId>
                <version>0.2.10-libsass_3.5.3</version>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <outputPath>${project.build.directory}/generated-sources/resources</outputPath>
                    <inputPath>${basedir}/src/main/resources</inputPath>
                    <!--<includePath>${basedir}/src/sass-plugins/</includePath>-->
                    <outputStyle>nested</outputStyle>
                    <generateSourceComments>false</generateSourceComments>
                    <generateSourceMap>false</generateSourceMap>
                    <sourceMapOutputPath>${project.build.directory}/generated-sources/resources
                    </sourceMapOutputPath>
                    <omitSourceMapingURL>true</omitSourceMapingURL>
                    <embedSourceMapInCSS>false</embedSourceMapInCSS>
                    <embedSourceContentsInSourceMap>false</embedSourceContentsInSourceMap>
                    <precision>5</precision>
                    <enableClasspathAwareImporter>true</enableClasspathAwareImporter>
                    <copySourceToOutput>false</copySourceToOutput>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.build.directory}/generated-sources/resources</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
Wimsatt answered 28/3, 2019 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.