2

Quite frustrating as I follow guidelines and basic tutorial. I can apply CSS styles to differnt elements but not to vbox or hbox.

I have the following simple Apps creating a simple scene using a FMXL and CSS:

import java.net.URL;

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


public class BingRen extends Application {
    @Override
    public void start(Stage primaryStage) {
        Parent root = null;
        FXMLLoader loader = new FXMLLoader();
        URL xmlUrl = getClass().getResource("/BingRen.fxml");
        loader.setLocation(xmlUrl);
        try {
            root = loader.load();
            Scene scene = new Scene(root,400,400);
            scene.getStylesheets().add(getClass().getResource("BingRen.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

With FXML, creating just a BordPane and 2 HBox containing one label each. Almost as simple as HellopApp :

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

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


<BorderPane fx:id="rootBorderPane"
        xmlns="http://javafx.com/javafx"
        xmlns:fx="http://javafx.com/fxml"
        fx:controller="MainControler">
    <top>
        <HBox>
            <Label text="BingRen app" />
        </HBox>
    </top>
    <bottom>
        <HBox>
            <Label text="Status bar" />
        </HBox>
    </bottom>
    <center>
    </center>
</BorderPane>

And CSS to set some basic properties:

.hbox {
    -fx-background-color: #00ff00;
    -fx-border-color: #00ff00;
    -fx-border-width: 2px;
    -fx-padding: 10;
    -fx-spacing: 8;
}

.label {
    -fx-text-fill: #0000ff;
}

Label properly turn blue but not of the hbox style are applied


In fact none of the suggestion worked.

I tried :

  • Change .hbox to .Hbox in css file
  • Make a #allbox in css file and add fx-id="allbox" and fxml file

For every change, I change the color for label to ensure the new version of css is read through.

Label always change color but I never get backgroung or paddings in the Hboxes

ChrisF
  • 134,786
  • 31
  • 255
  • 325

1 Answers1

6

Why your current approach fails

Look at the CSS documentation.

For HBox

Style class: empty by default

For Label

Style class: label

So there is no such style class as ".hbox" for a HBox unless you add one, which you have not done.

Background on CSS selectors and JavaFX

Read the section titled "CSS and the JavaFX Scene Graph":

CSS selectors are used to match styles to scene‑graph nodes. The relationship of a Node to a CSS selector is as follows:

  • Node's getTypeSelector method returns a String which is analogous to a CSS Type Selector. By default, this method returns the simple name of the class. Note that the simple name of an inner class or of an anonymous class may not be usable as a type selector. In such a case, this method should be overridden to return a meaningful value.
  • Each node in the scene‑graph has a styleClass property. Note that a node may have more than one style‑class. A Node's styleClass is analogous to the class="..." attribute that can appear on HTML elements. See Class Selectors.
  • Each node in the scene‑graph has an id variable, a string. This is analogous to the id="..." attribute that can appear HTML elements. See ID Selectors.

Application examples

So there are three ways you can fix this:

  1. Use a type selector in your CSS file:

    HBox { <css rules> }
    
  2. Apply a style class in your CSS file:

    .my-hbox-styleclass { <css rules> }
    

    And in FXML write:

    <HBox styleClass="my-hbox-styleclass">
    

    OR in code write:

    myHBox.getStyleClass().add("my-hbox-styleclass");
    
  3. Apply a style id in your CSS file:

    #my-hbox-id { <css rules> }
    

    And in FXML write:

    <HBox id="my-hbox-id">
    

    OR in code write:

    myHBox.setId("my-hbox-id");
    

Selector scope differences

There are differences in the meaning for the standard application of each approach:

  1. The type selector will apply to all HBox types in your UI.
  2. The class selector will apply to anything which has the given style class applied.
  3. The id selector is usually used for a single node in the UI, rather than a type or class of node. It should be unique within an FXML document or scene graph tree, though this is not enforced.
James_D
  • 201,275
  • 16
  • 291
  • 322
jewelsea
  • 150,031
  • 14
  • 366
  • 406