Mark Mark - 3 months ago 69
CSS Question

How to lookup the applied font on JavaFX Label?

I need to automatically resize the font on my JavaFX Label if the text doesn't all fit in the label's boundaries. I found some awesome code online (here Resize JavaFX Label if overrun) to do this but the problem is the code takes font size and as an argument. It seems like determining the font size would be very easy, but Label.getFont() returns the default settings because my application is using css to set the font sizes. My css is setting the font size to 30, but everything I have figured out how to look up on the Label so far is returning default settings of 12.

So I tried looking it up but I don't understand where to look for it. Label.getStyle() returns an empty string. getCSSMetaData() returns a whole bunch of interesting settings and I was able to find font there and look at the sub properties, but again it is storing the default values of font size 12 and a different style name.

This is the setting from my style sheet file that I'm using so I know I need to locate feedback card and font size:

._Feedback_Card {
-fx-font-size: 30px;
-fx-font-weight: bold;
-fx-text-fill: rgba(0,0,0,.9);
-fx-background-color: white;
-fx-border-color: white;
-fx-border-width: 0;
-fx-alignment: center;
-fx-text-alignment: center;
-fx-font-family: Arial Unicode MS;
-fx-effect: dropshadow(gaussian, #b4b4b4, 6,0,0,2);
}


Don't be swayed by the name, there's a mapping somewhere else in the code that maps this component to that class name somehow. It's written by a co-worker so I'm unaware of the exact mechanics. But given that name I tried looking up the region on the root node with:

Region node = (Region)jsLayoutCollection.jsDisplayLayoutCollection.fGetFXParent().lookup("._Feedback_Card");
String sStream = node.getCssMetaData().stream()


and then I looked through the stream for font properties. But that again returned font but the size was the default 12, not 30 that the style sheet sets it to.

So where is this property being applied and how do I look it up? It seems like it should be straightforward to figure out this information but I can't find it. It's very easy to set the font after with:

Label.setStyle("-fx-font-size: " + fontSize + "px");


Any help is greatly appreciated.

Answer

Once the stylesheet has been loaded by the label's scene (or parent), and CSS has been applied, getFont() will return the font set by CSS.

This code:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class GetCSSFont extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label label = new Label("Big label");
        StackPane root = new StackPane(label);
        Scene scene = new Scene(root);
        scene.getStylesheets().add("set-font.css");

        System.out.println("Default font: "+label.getFont());

        label.applyCss();

        System.out.println("Font from CSS: "+label.getFont());

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

with set-font.css:

.label {
    /* Note the font family needs quoting if it has spaces: */
    -fx-font-family: 'Arial Unicode MS' ;
    -fx-font-size: 30px ;
    -fx-font-weight: bold ;
}

.root {
    -fx-padding: 20 ;
}

produces the output:

Default font: Font[name=System Regular, family=System, style=Regular, size=13.0]
Font from CSS: Font[name=Arial Unicode MS, family=Arial Unicode MS, style=Regular, size=30.0]

(And you can, of course, get the point size with double size = label.getFont().getSize().)