skip to Main Content

here’s the problem

enter image description here

the css FX code is

.custom-combobox .arrow-button {
    -fx-background-color: transparent;
    -fx-background-size: contain;
    -fx-background-repeat: no-repeat;
    -fx-background-position: center;
    -fx-background-image: url('../img/downArrow.png');
}

.custom-combobox .list-cell {
    -fx-pref-height: 70px;
    -fx-pref-width: 150px;
    -fx-background-color: red;
    -fx-background-size: 100% 100%; 
    -fx-background-position: center;
    -fx-alignment: center;
}

.custom-combobox .combo-box {
    -fx-max-height: 70px;
    -fx-max-width: 150px;
    -fx-background-size: 100% 100%; 
    -fx-background-repeat: no-repeat;
    -fx-background-position: center;
    -fx-padding: 0; 
}

.custom-combobox .arrow {
    -fx-background-color: transparent;
    -fx-padding: 0;
    -fx-background-image: url('../img/downArrow.png');
    -fx-background-size: contain;
    -fx-background-repeat: no-repeat;
    -fx-background-position: center;
    -fx-shape: null;
}

(custom-combobox is a css class in my fxml)
I can’t get the red behind the arrow

get the red behind the arrow

2

Answers


  1. You need to first understand how the ComboBox is structured.

    enter image description here

    From the above picture you can notice that the ComboBox is made with two node placed side to side (ListCell & StackPane). The stuff in red boxes is the styleClasses of the corresponding node.

    In your code you applied background color to only list cell. To get your desired effect, you can do either of the below two things:

    • Add background-color to arrow-button (as mentioned by @VGR in the comment)

    • Add background-color to the comboBox itself, so that you dont need to add background colors separately to listCell and arrow-button.

      .custom-combobox{
      -fx-background-color: red;
      }

    Login or Signup to reply.
  2. This answer uses JavaFX’s in-built color theming and SVG path capabilities.

    Looked-up Colors

    Sometimes (not always), rather than explicitly setting specific colors, utilizing the theming setup defined in the modena.css file inside the javafx controls jar for your distribution is better.

    For example, if you set the looked-up color -fx-base to some value on a Scene or control, it will change all the colors in that scene or controller to a color theme based on that color. The same is true, in more limited ways, for many other looked-up-colors defined in modena.css.

    This answer provides an example of the looked-up color approach.

    SVG Paths

    It may be more flexible to define the arrow in the combo box using an SVG path, as is done in the standard modena.css, by changing the SVG path to represent the arrow shape you want.

    But you could stick with replacing the SVG-defined arrow with a bitmap image as you have done if you wished.

    This answer provides an example of the SVG Path approach.

    Themed Stylesheet Definition

    The example uses an inline stylesheet, but you could externalize the stylesheet in a CSS file instead if you wish.

    In the example, the stylesheet is just applied to the combo box, but you could apply it to the entire scene if you wished all combo boxes to have a similar appearance.

    In the example, the -fx-base color is defined just for a custom style that is applied to the combo box. If instead, you wanted all UI elements to take the red theme, you could set the -fx-base in a .root class in your external stylesheet that is applied to the entire scene, then everything in the scene would have a red theme.

    Creating a Custom SVG Path

    For defining the SVG path for the arrow, the SVG was downloaded from:

    Then the SVG was converted to a path using an online tool:

    In the example, the font size of the combo box is changed, and it can be seen that the SVG path for the arrow scales with the font size.

    Some default JavaFX controls feature a layered background to allow for a faux-3D look. As we don’t want that on the arrow in this case, we redefine the background insets for both backgrounds containing the arrow to be 0.

    Color Derivation and Laddering

    The colors used for the JavaFX controls are, by default, based on (mainly) colors derived from the theme colors such as -fx-base and use JavaFX CSS functions for:

    • color derivation: allows multiple shades of required colors based on the main theme colors.
    • laddering: allows overlaid items such as text to have a contrasting color when the theme color is changed.

    If you want to understand color derivation and laddering, refer to the ample examples in the modena.css stylesheet and the color section of the JavaFX CSS reference.

    Example Screenshot

    screenshot

    Example Code

    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.ComboBox;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class PeopleComboApp extends Application {
    
        private static final String CSS_DATA = "data:text/css,";
    
        private static final String COMBO_CSS = CSS_DATA + // language=CSS
                """ 
                .custom-combo {
                    -fx-base: red;
                    -fx-font-size: 20px;
                }
                
                .custom-combo .arrow {
                    -fx-background-insets: 0, 0;
                    -fx-shape: "M12 17.414L3.293 8.707L4.707 7.293L12 14.586L19.293 7.293L20.707 8.707L12 17.414z";
                }
                """;
    
        @Override
        public void start(Stage stage) throws Exception {
            ComboBox<String> comboBox = new ComboBox<>();
            comboBox.getItems().setAll(
                    "Liam", "Emily", "Kian"
            );
            comboBox.getSelectionModel().select(0);
            comboBox.setPrefWidth(150);
            comboBox.getStylesheets().add(COMBO_CSS);
            comboBox.getStyleClass().add("custom-combo");
    
            StackPane layout = new StackPane(
                    comboBox
            );
            layout.setPadding(new Insets(20));
    
            Scene scene = new Scene(layout);
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search