Search code examples
javafx-8javafx-css

How to change TextArea background color more than once?


I have a TextArea in my JavaFX program that I want to be able to allow the user to set the background color of. I was able to figure out how to change the background color using an external css file by doing this.

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

However, this would only allow me to have a default setting and the user would not be able to select a color from a menu to change it.

I also tried doing this in Java code.

textArea.setStyle("-fx-background-color: green");

But it doesn't change anything because the TextArea has more depth to it.

Is there any way I can change the background multiple times without having to modify the css file?


Solution

  • Use the external CSS file to define the background color using a looked-up color (scroll down the link to just below all the color swatches):

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

    (Here text-area-background is essentially an arbitrary variable name of your choosing.)

    Then you can programmatically update the definition of the looked-up-color:

    textArea.setStyle("text-area-background: green;");
    

    Here's an SSCCE:

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.ContentDisplay;
    import javafx.scene.control.ListCell;
    import javafx.scene.control.TextArea;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
    
    public class TextAreaColorSelection extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            ComboBox<Color> choices = new ComboBox<>();
            choices.getItems().addAll(Color.ALICEBLUE, Color.AQUAMARINE, Color.CORNFLOWERBLUE,
                    Color.ANTIQUEWHITE, Color.BLANCHEDALMOND);
            choices.setCellFactory(lv -> new ColorCell());
            choices.setButtonCell(new ColorCell());
    
            TextArea textArea = new TextArea();
    
            choices.valueProperty().addListener((obs, oldColor, newColor) -> {
    
                textArea.setStyle("text-area-background: "+ format(newColor) +";");
    
            });
    
            Scene scene = new Scene(new BorderPane(textArea, choices, null, null, null));
            scene.getStylesheets().add("text-area-background.css");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        private String format(Color c) {
            int r = (int) (255 * c.getRed());
            int g = (int) (255 * c.getGreen());
            int b = (int) (255 * c.getBlue());
            return String.format("#%02x%02x%02x", r, g, b);
        }
    
        public static class ColorCell extends ListCell<Color> {
            private final Rectangle rect = new Rectangle(80, 20);
    
            public ColorCell() {
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            }
    
            @Override
            public void updateItem(Color color, boolean empty) {
                super.updateItem(color, empty);
                if (empty) {
                    setGraphic(null);
                } else {
                    setGraphic(rect);
                    rect.setFill(color);
                }
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    With the css file text-area-background.css:

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