Javafx Style All Nodes of The Same Type, E.G., Vbox

JavaFX CSS class for GridPane, VBox, VBox

No, only Control subclasses have default css classes defined. I think this is because applications that want to manage their own graphics (using a Canvas or unmanaged Shapes, for example) probably will not use css, but will likely still use these layout panes. Since css is expensive to apply to the scene graph, nodes that do not necessarily require them do not have style classes.

I don't think there is any way to add a style class to a pane, other than as you show. Obviously, if you need a lot of GridPanes with the same style class, you can just define a method to avoid the repetitive code:

private GridPane createGridPane() {
GridPane grid = new GridPane();
grid.getStyleClass().add("grid-pane");
return grid ;
}

Update

Note that, as in HTML-based CSS, you can use selectors based on types as well as selectors based on style classes, as noted in the documentation. The default style class for any node is its simple class name. Thus you could select grid panes via the type selector:

GridPane {
/* styles ... */
}

This feels a little fragile to me: in particular if you subclass GridPane, the selector would no longer apply, which is very counter-intuitive from an object-oriented perspective. I would recommend using style classes over type selectors.

Also note that if you are wanting to change the color scheme for the entire application (or just a sub-graph of the scene graph), which is probably the most common use case for this, you can simply define values for some standard looked-up colors. For example:

.root {
-fx-base: #bfe7ff;
-fx-accent: #0096c9 ;
-fx-default-button: #abd8ed ;
-fx-focus-color: #039ed3;
-fx-faint-focus-color: #039ed322;
-fx-focused-text-base-color : ladder(
-fx-selection-bar,
-fx-light-text-color 45%,
-fx-dark-text-color 46%,
-fx-dark-text-color 59%,
-fx-mid-text-color 60%
);
-fx-focused-mark-color : -fx-focused-text-base-color ;

-fx-font-family: verdana;
}

will apply a "blue theme" to the whole application, propagating the looked-up colors and properties that default to "inherit" to all child nodes.

Styling Javafx with CSS

For the most part, it is only Control subclasses that have default style classes. Additionally, the root of the scene gets the style class root.

So you need to add the vbox and hbox style classes manually:

    VBox container = new VBox();
container.getStyleClass().add("vbox");
HBox root = new HBox();
root.getStyleClass().add("hbox");
HBox rootA = new HBox();
rootA.getStyleClass().add("hbox");
HBox rootB = new HBox();
rootB.getStyleClass().add("hbox");

Is there a way to remove all the contents in vBox in JavaFx?

Oh! I just figured it out.
I can use vBox.getChildren().clear();
It works!

Why does JavaFX Node have wrong sizes in initialize method after css is applied?

In my case, I was using mainAnchorPane.setPrefHeight(vbox.getHeight()) because after experiments I noticed that without that method mainAnchorPane wouldn't change the height. That is because I set exact pref height value for AnchorPane in SceneBuilder. But after setting USE_COMPUTED_SIZE, my AnchorPane will have the size that I actually want. So all I need is:

set computed size for all fields

Is it possible in JavaFX to not use the parent StyleSheet of a Node?

You can place the child in a SubScene.

SubScenes do not inherit the CSS styles of their parent nodes.

Example

Sample Image

In the example, there are two circles, one circle is in the root layout pane of the main scene, the other is in a SubScene (with a light blue background) which is also in the root layout pane of the main scene.

The layout pane of the main scene (a VBox) has styles defined so that all of the child circles inherit a green fill. However, the SubScene prevents the inheritance of CSS styles, so only the circle which is not in the SubScene is green.

colored-circles.css

.green {
-fx-fill: green;
}

Circle {
-fx-fill: inherit;
}

Note that, by default, -fx-fill CSS attribute values are not inherited by child nodes, hence the additional rule to have circles inherit the CSS attribute value for -fx-fill.

StyleInheritance.java

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class StyleInheritance extends Application {

public static final double R = 50;

@Override
public void start(Stage stage) {
Circle circleInMainScene = new Circle(R, R, R);
Circle circleInSubScene = new Circle(R, R, R);

SubScene subScene = new SubScene(
new Group(circleInSubScene),
circleInSubScene.getLayoutBounds().getWidth(),
circleInSubScene.getLayoutBounds().getHeight()
);
subScene.setFill(Color.LIGHTBLUE);

VBox layout = new VBox(10, circleInMainScene, subScene);
layout.setPadding(new Insets(10));
layout.getStyleClass().add("green");

Scene mainScene = new Scene(layout);

mainScene.getStylesheets().add(
StyleInheritance.class.getResource(
"colored-circles.css"
).toExternalForm()
);

stage.setScene(mainScene);
stage.show();
}

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

}

There is probably also some way of accomplishing what you want via CSS rules alone rather than using a SubScene, but using a SubScene appears to work and is what I came up with.

parent node losing its child

I am passing entry to the constructor in order to copy all the other object attributes/properties that are already set via the FXML form.

It doesn't work this way. That constructor adds the same instance as child of the newly created HBox. Since a Node can only have a single parent and a Node occurs in the child list of it's Parent, JavaFX has to fix the state by removing the Node from the child list of it's former parent.

Note that quite a few Panes allow you to pass children to one of the constructor. Those are not copy constructors, but simply "shortcuts" for that allow you to add the children without using pane.getChildren().addAll(children); In fact I'm not aware of any copy constructor for Nodes in the JavaFX API.

HBox newEntry = new HBox(entry);

Creates a new HBox containing entry as it's only child.

Instead of trying to copy a part of the scene graph, it's most often easier to create a helper method that creates the part of the scene graph (which can also be done using a fxml file).

(There is no functionality in the JavaFX API allowing you to create a copy of a Node hierarchy.)



Related Topics



Leave a reply



Submit