JavaFX setStyle with -fx-background-color paints only the edges of a TextArea

10,704

Solution 1

You actually need to style the .content region that is a child of the TextArea (see CSS Reference: TextArea - Substructure).

You can get that node using lookup, but only after the skin is applied, which does not happen until layout. Then however you can do something like this:

Region content = (Region) ta.lookup(".content");
content.setStyle("-fx-background-color:orangered;");

An alternative would be using a CSS stylesheet and changing the class of the TextArea (provided only a limited number of colors is used):

.text-area.color-orangered .content {
     -fx-background-color: orangered;
}

.text-area.color-white .content {
     -fx-background-color: white;
}

.text-area.color-green .content {
    ...
// remove old class for coloring
ta.getStyleClass().removeIf(s -> s.startsWith("color-"));

// add new class
ta.getStyleClass().add("color-orangered");

Solution 2

The CSS style class you are looking for is .text-area .content. You have several options to affect this style class, one possibility is to use PseudoClass which makes you able to use CSS selectors.

Main.java

public class Main extends Application {


    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            root.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            // Add the CSS style class
            TextArea ta = new TextArea();
            ta.getStyleClass().add("my-text-area");


            ChoiceBox<String> cb = new ChoiceBox<String>(FXCollections.observableArrayList("green", "orangered"));
            cb.valueProperty().addListener(new ChangeListener<String>() {

                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                // On selection, change the pseudo class of the TextArea
                ta.pseudoClassStateChanged(PseudoClass.getPseudoClass(newValue), true);
                }
            });

            root.setCenter(ta);
            root.setBottom(cb);

            Scene scene = new Scene(root,400,400);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

application.css

.my-text-area:orangered .content {  
   -fx-background-color: orangered ;  
}  

.my-text-area:green .content {  
   -fx-background-color: green ;  
}  
Share:
10,704
E. Muuli
Author by

E. Muuli

Updated on August 04, 2022

Comments

  • E. Muuli
    E. Muuli over 1 year

    So, I have a dynamically created list of TextArea's and I want to paint them depending on which CheckBox I select. Currently, it only colors the borders, but not the inside of the TextArea.

    Here is my code:

    if (cb.isSelected()) {
      ta.setStyle("-fx-background-color:#38ee00;");
    }
    if (cb2.isSelected()) {
      ta.setStyle("-fx-background-color:orangered;");
    }
    if (!cb2.isSelected() && !cb.isSelected()) {
      ta.setStyle("-fx-background-color:white;");
    }
    

    And here is the result that it brings:

    enter image description here

    If you need any other information, please feel free to let me know.