Radosław Łazarz
Radosław Łazarz

Reputation: 968

JavaFX 2.2 built-in controls have no default style

While the CSS styling tutorials mention both default style sheet (caspian.css) and default classes for built-in controls (like .line for Line), my controls seem to lack both (checked by debugger).

As a result, the do not react for additional custom CSS if I do not set their class explicitly, which is annoying and destroys the whole point of global CSS styling.

I would be grateful for any ideas of what may cause such behaviour.

Upvotes: 0

Views: 220

Answers (1)

James_D
James_D

Reputation: 209684

In JavaFX, three CSS selectors are supported, which are analogous to Type Selectors, Class selectors, and ID selectors in standard CSS. It's important to be a bit careful with the word "class", which has different meanings in the Java world and the CSS world: a Java class is a CSS Type; a CSS class is set on a node via a property called styleClass.

The Type Selector is determined by the result of calling the method getTypeSelector, which is declared in the interface Styleable. Node implements this interface, and implements getTypeSelector to return

getClass().getName() without the package name

So any Node may be styled by specifying its simple class name:

Label {
    -fx-text-fill: green ;
}
Line {
    -fx-stroke: red ;
}

etc.

CSS classes are determined by the getStyleClass() method in Styleable, which returns a list of strings. (Note that nodes may have multiple style classes, though I have never understood why this is a List rather than a Set.) By default, this list is empty, but Control subclasses set this value via their default skin to be the "css-ized" version of the class name (Button becomes button, ComboBox becomes combo-box, etc.). Thus

.label {
    -fx-text-fill: green ;
}

works, but

.line {
    -fx-stroke: red ;
}

does not work without previously setting the style class:

Line line = new Line();
line.getStyleClass().add("line");

Finally, ID Selectors work by specifying an id on the node. Ids are intended to be unique among all nodes in the scene graph. So you can do

Line line = new Line();
line.setId("my-line");

with

#my-line {
    -fx-stroke: red ;
}

So in your example, the style class is not set by default (Line is not a Control subclass). You must either set it "by hand", or use a type selector.

One last note: you mentioned that your line "lacked caspian.css". I'm not quite sure what that means (as Lines are not styled at all by the default stylesheet), but the default stylesheet is only loaded the first time a Control is instantiated. This is intended as a performance enhancement for scene graphs that use no controls (and so would not benefit from the default stylesheet anyway).

Upvotes: 1

Related Questions