java - 文本组合框工厂调用

标签 java javafx combobox

对于我的 Java FX 项目,我有一个字符串列表,我需要将它们添加到组合框中,并要求其中只有一个(第一个)为红色。

我考虑过将字符串封装在文本中,并使用适当的 setStyle("fx-text-fill: Color.xxx") 将它们添加到组合框中。这需要 setCellFactory() 方法,但我不知道如何正确设置它。

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Callback;

public class Mainu extends Application 
{
    final ObservableList<Text> SAMPUNITFRONT = FXCollections.observableArrayList(
            new Text("complete"), new Text("seconds"), new Text("minutes"), new Text("hours"), new Text("days")); 
    @Override
    public void start(Stage stage) throws Exception 
    {
        ComboBox<Text> cb = new ComboBox<Text>();
        for(int j = 0; j < SAMPUNITFRONT.size(); j++) // cycle over the list and generate a line with dashing defined by list
            {
                Text text = SAMPUNITFRONT.get(j);
                if(text.getText().equals("complete"))
                    text.setStyle("-fx-text-fill: RED");
                else
                    text.setStyle("-fx-text-fill: BLACK");
                cb.getItems().add(text);
            }

        cb.setCellFactory(new Callback<ListView<Text>, ListCell<Text>>() 
        {
            @Override public ListCell<Text> call(ListView<Text> p) 
            {
                return new ListCell<Text>() 
                {
                    private final Text text;
                        { 
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
                            text = new Text();
                        } // end Text
                    @Override protected void updateItem(Text item, boolean empty) 
                        {   
                            super.updateItem(item, empty);
                            if (item == null || empty) 
                                {   
                                    setGraphic(null);
                                }
                            else 
                                {
                                    text.setStyle(item.getStyle());
                                    setGraphic(text); 
                                    setItem(text);
                                }
                        }  // end updateItem()
                }; // end ListCell return
            }
        });

        cb.getSelectionModel().selectFirst();
        Pane root = new Pane();
        root.getChildren().add(cb);
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {launch(args);}
}

目前,组合的下拉列表为空。

最佳答案

这里提出的一些建议:

  • 不要使用Node类型作为项目类型。相反,存储确定项目中 ListCell 外观所需的数据,并让 ListCell 实现处理其余部分。如果您应该仅根据文本或索引完成着色,或者您可以创建一个包含 2 个属性的类,则可以简单地使用 String 作为项目类型。
  • 不要自己调用setItem。让 ComboBox/ListView 来处理这个问题。
  • 对于Text,您需要使用-fx-fill css属性而不是-fx-text-fill。如果您使用 ListCell 本身的 text 属性,则后一种方法可行。
  • 如果您不使用 ObservableList 的功能,那么创建它是没有意义的。对于 SAMPUNITFRONT,您可以简单地使用 ListArrays.asList 而不是 ObservableListFXCollections.observableArrayList
final ObservableList<String> SAMPUNITFRONT = FXCollections.observableArrayList("complete",
        "seconds", "minutes", "hours", "days");

@Override
public void start(Stage stage) throws Exception {
    ComboBox<String> cb = new ComboBox<String>(SAMPUNITFRONT);

    cb.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
        @Override
        public ListCell<String> call(ListView<String> p) {
            return new ListCell<String>() {
                private final Text text;

                {
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                    text = new Text();
                }

                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setGraphic(null);
                    } else {
                        text.setStyle(item.equals("complete") ? "-fx-fill: red" : "-fx-fill: black");
                        text.setText(item);
                        setGraphic(text);
                    }
                }
            };
        }
    });

    cb.getSelectionModel().selectFirst();
    Pane root = new Pane();
    root.getChildren().add(cb);
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

或者不使用文本作为图形:

return new ListCell<String>() {

    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        setText(item);
        if (item != null) {
            setStyle(item.equals("complete") ? "-fx-text-fill: red" : "-fx-text-fill: black");
        }
    }
};

关于java - 文本组合框工厂调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56472087/

相关文章:

java - 递归对象到 JSON

java - 如何在FXML Controller 中填充javafx.TableView?

java - 按钮 ActionListener 同时运行两个组合框选项,为什么?

c++ - QT5 C++,有没有办法我可以在qlist容器中获取小部件的当前文本

java - 如何防止多次点击 JComboBox

具有返回被调用对象的方法的 Java 接口(interface)?

java - 有什么方法可以在 if else 条件中分离这个 "OR"(||) 条件吗?

user-interface - JavaFX - 文本字段/文本区域中的内联图像

javafx - 为什么 TableCloumn<S,T> 需要 2 个元素?

javascript - 在extJS中动态设置组合框的multiSelect