[英]JavaFX ComboBox background color per selected item
我想根據所選項目更改ComboBox
的背景。
例如:如果選擇了第一項,則背景應為綠色,如果選擇了第二項,則背景應為紅色。
這可能嗎?
當然可以。 在與ComboBox
使用的cellFactory
創建自定義ListCell
,並根據它包含的項目使用它來修改Cell
的樣式。
例:
public class Item {
public Item(String value, Color color) {
this.value = value;
this.color = color;
}
private final String value;
private final Color color;
public String getValue() {
return value;
}
public Color getColor() {
return color;
}
}
ComboBox<Item> comboBox = new ComboBox<>(FXCollections.observableArrayList(
new Item("Summer", Color.RED),
new Item("Winter", Color.CYAN),
new Item("Spring", Color.LIME),
new Item("Autumn", Color.BROWN)
));
comboBox.setCellFactory(lv -> new ListCell<Item>(){
@Override
protected void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setBackground(Background.EMPTY);
setText("");
} else {
setBackground(new Background(new BackgroundFill(item.getColor(),
CornerRadii.EMPTY,
Insets.EMPTY)));
setText(item.getValue());
}
}
});
comboBox.setButtonCell(comboBox.getCellFactory().call(null));
如果只想設置ComboBox
本身的顏色,而不是下拉列表中ComboBox
的項目,則可以在buttonCellProperty和ComboBox
的valueProperty之間創建自定義綁定,以實現自定義着色。
例
本示例將ComboBox
顏色選擇為綠色(如果選擇了第一項),將其着色為紅色(如果選擇了第二項),否則將顏色保持不變。
更新:現在, ComboBox
的箭頭按鈕的背景色也已着色,因為可以使用查找方法來獲取箭頭按鈕: StackPane arrowButton = (StackPane) combo.lookup(".arrow-button");
。
ComboBox<String> combo = new ComboBox<>();
combo.setItems(FXCollections.observableArrayList("First", "Second", "Third", "Fourth"));
combo.buttonCellProperty().bind(Bindings.createObjectBinding(() -> {
int indexOf = combo.getItems().indexOf(combo.getValue());
Color color = Color.TRANSPARENT;
switch (indexOf) {
case 0: color = Color.GREEN; break;
case 1: color = Color.RED; break;
default: break;
}
final Color finalColor = color;
// Get the arrow button of the combo-box
StackPane arrowButton = (StackPane) combo.lookup(".arrow-button");
return new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setBackground(Background.EMPTY);
setText("");
} else {
setBackground(new Background(new BackgroundFill(finalColor, CornerRadii.EMPTY, Insets.EMPTY)));
setText(item);
}
// Set the background of the arrow also
if (arrowButton != null)
arrowButton.setBackground(getBackground());
}
};
}, combo.valueProperty()));
結果是這樣的:
筆記
1)如果您還要在下拉列表中為項目着色,則可以從此處的其他答案中選擇解決方案。
2)如果您不顯示String
而是能夠存儲項目顏色的項目,則解決方案甚至更短,只需在updateItem
方法中使用所選項目的顏色,而不是計算自己的顏色即可。
public class Main extends Application {
Random r = new Random();
private class Item {
Color c;
String s;
public Item(Color a,String b){
c = a;
s = b;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return s;
}
}
private void addAll(List<String> items){
for(String s : items){
box.getItems().add(new Item(Color.WHITE,s));
}
}
ComboBox<Item> box;
@Override
public void start(Stage primaryStage) {
Pane p;
try {
p = new StackPane();
box = new ComboBox<Item>();
box.setMinWidth(100);
addAll(Font.getFontNames());
box.setCellFactory(new Callback<ListView<Item>, ListCell<Item>>() {
@Override
public ListCell<Item> call(ListView<Item> param) {
// TODO Auto-generated method stub
return new ListCell<Item>(){
@Override
public void updateSelected(boolean selected) {
super.updateSelected(selected);
if(selected){
getItem().c = Color.rgb(r.nextInt(205),
r.nextInt(205), r.nextInt(205), 1);
}
setStyle("-fx-text-fill: black; -fx-background-color: #" +
getItem().c.toString().substring(2)+";");
}
@Override
protected void updateItem(Item item, boolean empty) {
// TODO Auto-generated method stub
super.updateItem(item, empty);
if(empty){
return;
}
setText(item.toString());
setStyle("-fx-text-fill: black; -fx-background-color: #" +
getItem().c.toString().substring(2)+";");
}
};
}
});
p.getChildren().add(box);
p.setPrefSize(500, 500);
Scene scene = new Scene(p);
scene.getStylesheets().add(getClass().
getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
combobox.valueProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue ov, String t, String t1) {
if (t1.equals("Option 1")) {
combobox.setStyle(" -fx-background-color: #000000");
}
if (t1.equals("Option 2")) {
combobox.setStyle(" -fx-background-color: #FFFFFF");
}
}
});
您應該能夠使用基本的更改偵聽器來完成類似上述的操作,您可能需要刷新頁面(我通常只是刪除並重新添加組件,以便可以看到更改發生了)
這是基於您要選擇一個組合框項目然后更改該框的基礎,而不是每個項目從一開始就具有不同的顏色
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.