最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Is there a way to add a style class to the popup of a specific ComboBox? - Stack Overflow

programmeradmin4浏览0评论

I want to have a special style class for a ComboBox that I could reuse. For example, I want to create a class yellowed that will provide yellow background. This is my code:

Java:

public class NewMain extends Application {

    @Override
    public void start(Stage primaryStage) {
        ComboBox<String> comboBox = new ComboBox<>();
        comboBox.getItems().addAll("Option 1", "Option 2", "Option 3");
        comboBox.getStyleClass().add("yellowed");

        VBox vbox = new VBox(comboBox);
        Scene scene = new Scene(vbox, 400, 300);
        scene.getStylesheets().add(NewMain.class.getResource("test.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

CSS:

bo-box.yellowed {
    -fx-background-color: yellow;
}

bo-box-popup.yellowed > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell {
    -fx-background-color: yellow;
}

The problem is that the popup (of my ComboBox with yellowed style class) that will be shown won't have a yellowed class.

Could anyone say, if there is a way to add a style class to the popup of a specific ComboBox?

I want to have a special style class for a ComboBox that I could reuse. For example, I want to create a class yellowed that will provide yellow background. This is my code:

Java:

public class NewMain extends Application {

    @Override
    public void start(Stage primaryStage) {
        ComboBox<String> comboBox = new ComboBox<>();
        comboBox.getItems().addAll("Option 1", "Option 2", "Option 3");
        comboBox.getStyleClass().add("yellowed");

        VBox vbox = new VBox(comboBox);
        Scene scene = new Scene(vbox, 400, 300);
        scene.getStylesheets().add(NewMain.class.getResource("test.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

CSS:

.combo-box.yellowed {
    -fx-background-color: yellow;
}

.combo-box-popup.yellowed > .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell {
    -fx-background-color: yellow;
}

The problem is that the popup (of my ComboBox with yellowed style class) that will be shown won't have a yellowed class.

Could anyone say, if there is a way to add a style class to the popup of a specific ComboBox?

Share Improve this question edited Jan 18 at 23:09 andrewJames 21.9k11 gold badges29 silver badges64 bronze badges asked Jan 18 at 22:09 SilverCubeSilverCube 4402 silver badges11 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

The popup is considered a descendant of the ComboBox1. This is documented by the JavaFX CSS Reference Guide:

ComboBox

Style class: combo-box

The ComboBox control has all the properties and pseudo‑classes of ComboBoxBase

Substructure
  • list-cell — a ListCell instance used to show the selection in the button area of a non-editable ComboBox
  • text-input — a TextField instance used to show the selection and allow input in the button area of an editable ComboBox
  • combo-box-popup — a PopupControl that is displayed when the button is pressed [emphasis added]
    • list-view — a ListView
      • list-cell — a ListCell

So, all you need to do is:

.combo-box.yellowed .combo-box-popup .list-cell {
  -fx-background-color: yellow;
}

Technically, combo-box.yellowed .list-cell is sufficient, but note that will also target the node used to display the actual combo box (i.e., the "button cell", which is also a ListCell). And of course you can make the selector more specific if you want/need to.

Here's a runnable example:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Main extends Application {

  // Text blocks require Java 15+
  private static final String STYLESHEET =
      """
      .combo-box.yellow,
      .combo-box.yellow .combo-box-popup .list-cell {
        -fx-background-color: yellow;
      }

      .combo-box.red,
      .combo-box.red .combo-box-popup .list-cell {
        -fx-background-color: red;
      }
      """;

  @Override
  public void start(Stage primaryStage) {
    var box1 = createComboBox();
    box1.getStyleClass().add("yellow");

    var box2 = createComboBox();
    box2.getStyleClass().add("red");

    var root = new HBox(10, box1, box2);
    root.setAlignment(Pos.CENTER);

    var scene = new Scene(root, 500, 300);
    // Adding stylesheet via data URI requires JavaFX 17+
    scene.getStylesheets().add("data:text/css," + STYLESHEET);

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

  private ComboBox<String> createComboBox() {
    var box = new ComboBox<String>();
    for (int i = 1; i <= 5; i++) {
      box.getItems().add("Option #" + i);
    }
    // The 'getFirst' method requires Java 21+
    box.setValue(box.getItems().getFirst());
    return box;
  }

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

Note the example, as written, requires Java 21+ and JavaFX 17+.


1. For the curious, this is implemented by overriding PopupControl#getStyleableParent() to return the control.

发布评论

评论列表(0)

  1. 暂无评论