在我的应用程序中,我hava combobox从数据库中获取了一些值(一些实时更新列表)。此ComboBox列表每1分钟更新一次。 列表没有空值。当我将此列表设置为ComboBox ..
ComboBox box = new ComboBox(items);
..有一个额外的“空”行,这是完全正常的,因为选择了非值。 在我选择一些值之后,我的“空”值从列表中消失。 我的主要问题是如何将此值保留在列表中?
为什么这是一个问题......
答案 0 :(得分:0)
虽然这是一个老问题,但我花了很多时间试图解决应用程序中的同一问题,并认为我也可以在这里添加解决方案。
一种可能的解决方法是创建一个额外的列表,其中包含null
和您希望选择的项目。
ObservableList<String> selectableActivities = FXCollections.observableArrayList("a", "b", "c");
ObservableList<String> selectableActivitiesWithNull = FXCollections.observableArrayList();;
selectableActivitiesWithNull.add(null);
selectableActivitiesWithNull.addAll(selectableActivities);
为了支持原始列表的更新,您需要一个ListChangeListener
来根据原始列表的更改来更新额外列表。
selectableActivities.addListener((ListChangeListener<String>)(change -> {
while (change.next()) {
if (change.wasPermutated()) {
selectableActivitiesWithNull.sort((a, b) -> {
return Integer.compare(selectableActivities.indexOf(a), selectableActivities.indexOf(b));
});
} else if (change.wasRemoved()) {
selectableActivitiesWithNull.remove(change.getFrom()+1, change.getTo()+2);
} else if (change.wasAdded()) {
selectableActivitiesWithNull.addAll(change.getFrom()+1, selectableActivities.subList(change.getFrom(), change.getTo()));
} else if (change.wasUpdated()) {
for (int i = change.getFrom(); i < change.getTo(); ++i) {
selectableActivitiesWithNull.set(i+1, selectableActivities.get(i));
}
}
}
}));
最后,您将额外的列表用于ComboBox项。
ComboBox<String> combobox = new ComboBox<String>();
combobox.setItems(selectableActivitiesWithNull);
现在,您可以像往常一样修改原始列表,并且ComboBox将进行相应更新,同时将第一项也留空。最重要的是,您的原始列表不会被占位符对象污染,这些占位符对象可能会导致应用程序其他部分出现问题。
这也将与其他对象一起使用,假设您向ComboBox添加了一个合适的StringConverter
。请注意,如果使用上述方法,转换器还必须能够处理空值。
StringConverter<Object> activityConverter = new StringConverter<Object>() {
@Override
public String toString(Object object) {
return object != null ? object.toString() : "";
}
@Override
public ActivityDataRow fromString(String string) {
return null;
}
};
combobox.setConverter(activityConverter);
虽然这种方法并非您所需要的,但我相信这是无需实施自定义组合框即可获得的结果。
答案 1 :(得分:-1)
您只需要添加" "
作为其中一项,然后选择它,这真的很容易:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ComboBoxSample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override public void start(Stage stage) {
stage.setTitle("ComboBoxSample");
Scene scene = new Scene(new Group(), 450, 250);
final ComboBox<String> fooComboBox = new ComboBox<String>();
fooComboBox.getItems().addAll(
" ",
"foo",
"bar",
"FooBar"
);
fooComboBox.setValue(" ");
HBox box = new HBox();
box.getChildren().add(fooComboBox);
Group root = (Group)scene.getRoot();
root.getChildren().add(box);
stage.setScene(scene);
stage.show();
}
}
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxSample extends Application {
ObservableList<Person> people =
FXCollections.observableArrayList(
new Person(null,null),
new Person("Paul", "Mc"),
new Person("Bill", "Apple"),
new Person("Foo", "Bar")
);
@Override
public void start(Stage primaryStage) {
final ComboBox comboBox = new ComboBox(people);
comboBox.getSelectionModel().selectFirst(); //select the first element
comboBox.setCellFactory(new Callback<ListView<Person>,ListCell<Person>>(){
@Override
public ListCell<Person> call(ListView<Person> p) {
final ListCell<Person> cell = new ListCell<Person>(){
@Override
protected void updateItem(Person t, boolean bln) {
super.updateItem(t, bln);
if(t != null){
setText(t.toString());
}else{
setText(null);
}
}
};
return cell;
}
});
final Label label = new Label();
Button btn = new Button();
btn.setText("Read comboBox");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if(!(comboBox.getValue().toString()==null))
label.setText("selected: " + comboBox.getValue());
else
label.setText("null");
}
});
VBox vBox = new VBox();
vBox.setPadding(new Insets(5, 5, 5, 5));
vBox.setSpacing(5);
vBox.getChildren().addAll(label, comboBox, btn);
StackPane root = new StackPane();
root.getChildren().add(vBox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Combo!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
public class Person {
private String firstName;
private String lastName;
public Person(String first, String last){
this.lastName = last;
this.firstName = first;
}
public String getName() {
return firstName;
}
public void setName(String name) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setFullName(String first, String last){
this.lastName = last;
this.firstName = first;
}
@Override
public String toString() {
if(firstName != null)
return "" + firstName + " " + lastName;
else
return null;
}
}