对于我的 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,您可以简单地使用
List
和Arrays.asList
而不是ObservableList
和FXCollections.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/