java 带有复选框的 JavaFX ComboBox
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26631041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaFX ComboBox with CheckBoxes
提问by lumo
Description of the Question
问题描述
I try to create a JavaFX
ComboBox
which holds CheckBoxes
in the dropdown menu.
The ComboBox
shall be editable and gets fed by a simple Class
lets call it CheckItem
.
the list of CheckItems
shall be checkable - and shall not close the dropdown menu after a selection is made.
我尝试创建一个JavaFX
ComboBox
持有CheckBoxes
在下拉菜单中。本ComboBox
应是可编辑和可获取的速度从一个简单的Class
让调用它CheckItem
。列表CheckItems
应是可检查的 - 并且在选择后不应关闭下拉菜单。
finally the Text in the ComboBox
should be available and a Selection (all checked Items)
最后,文本中的文本ComboBox
应该可用和一个选择(所有选中的项目)
this is what i already worked out
这是我已经制定出来的
(1) a ComboBox
rendering the CheckItem
as CheckedBox
with correct selection
(1)使用正确选择ComboBox
渲染CheckItem
asCheckedBox
(2) gaining the Text from the ComboBox
(2) 从文本中获取文本 ComboBox
problems coming up
出现的问题
(1) After clicking on one item the dropdown closes & selection state of the item does not change.
(1) 单击一项后,下拉菜单关闭,该项的选择状态不会改变。
(2) As far as i noticed its only possible to have oneitem selected at a time?
(2)至于我注意到其只可能有一个在一个时间选择的项目?
here is my code for testing the stuff:
这是我用于测试这些东西的代码:
Test Program
测试程序
public class ComboButtonSample extends Application {
@Override
public void start(Stage stage) {
final ObservableList<CheckItem> items = fetchItems();
ComboBox<CheckItem> combo = createComboBox(items);
combo.setPromptText("enter searchstring here");
combo.setEditable(true);
// order the components vertically
VBox vBox = new VBox();
vBox.getChildren().add(combo);
// Button to write out the text and the items of the combobox
Button btn = new Button();
btn.setText("combo text to console");
btn.setOnAction((event) -> {
System.out.println("Text is: "+combo.getEditor().getText());
System.out.println("Content is: ");
for (Iterator<CheckItem> iterator = combo.getItems().iterator(); iterator.hasNext();) {
CheckItem ci = (CheckItem) iterator.next();
System.out.println(String.format("[%s] %s -> %s", ci.selected ? "X" : " ",ci.getDisplayName(), ci.getInternalName()));
}
});
vBox.getChildren().add(btn);
// show you do not need any code to change the selection of the box.
CheckBox checkBox = new CheckBox();
checkBox.setText("test box");
vBox.getChildren().add(checkBox);
stage.setScene(new Scene(vBox));
stage.show();
}
private ComboBox<CheckItem> createComboBox(ObservableList<CheckItem> data) {
ComboBox<CheckItem> combo = new ComboBox<>();
combo.getItems().addAll(data);
combo.setCellFactory(listView -> new CheckItemListCell());
return combo;
}
class CheckItemListCell extends ListCell<CheckItem> {
private final CheckBox btn;
CheckItemListCell() {
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
btn = new CheckBox();
}
@Override
protected void updateItem(CheckItem item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
btn.setText(item.getDisplayName());
btn.selectedProperty().setValue(item.selected);
setGraphic(btn);
}
}
}
private ObservableList<CheckItem> fetchItems() {
final ObservableList<CheckItem> data = FXCollections
.observableArrayList();
for (int i = 1; i < 15; i++) {
CheckItem chkItem = new CheckItem();
chkItem.selected = i%3==0;
chkItem.setDisplayName("DisplayName" + i);
chkItem.setInternalName("InternalName" + i);
data.add(chkItem);
}
return data;
}
public static void main(String[] args) {
launch(args);
}
CheckItem
检查项
public class CheckItem {
boolean selected;
String displayName;
String internalName;
public boolean isChecked() {
return selected;
}
public void setChecked(boolean checked) {
this.selected = checked;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getInternalName() {
return internalName;
}
public void setInternalName(String internalName) {
this.internalName = internalName;
}
}
回答by José Pereda
If you have problems in your implementation, you should have a look to the CheckComboBoxcontrol in the ControlsFXproject.
如果你在你的实施中的问题,您应该看一看到CheckComboBox在控制ControlsFX项目。
Source code can be found here.
源代码可以在这里找到。
回答by Андрей Стариков
My sample code:
我的示例代码:
class Person
班级人物
public class Person {
private StringProperty name = new SimpleStringProperty();
private ObjectProperty<LocalDate> birthday = new SimpleObjectProperty<>();
public Person() {
}
public Person(String name, LocalDate birthday) {
setNameValue(name);
setBirthdayValue(birthday);
}
public StringProperty getNameProperty() {
return name;
}
public String getNameValue() {
return name.getValue();
}
public void setNameValue(String value) {
name.setValue(value);
}
public ObjectProperty<LocalDate> getBirthdayProperty() {
return birthday;
}
public LocalDate getBirthdayValue() {
return birthday.getValue();
}
public void setBirthdayValue(LocalDate value) {
birthday.setValue(value);
}
@Override
public String toString() {
return getNameValue()+" ("+getBirthdayValue()+")";
}
}
simple wrapper
简单包装
public class ComboBoxItemWrap<T> {
private BooleanProperty check = new SimpleBooleanProperty(false);
private ObjectProperty<T> item = new SimpleObjectProperty<>();
ComboBoxItemWrap() {
}
ComboBoxItemWrap(T item) {
this.item.set(item);
}
ComboBoxItemWrap(T item, Boolean check) {
this.item.set(item);
this.check.set(check);
}
public BooleanProperty checkProperty() {
return check;
}
public Boolean getCheck() {
return check.getValue();
}
public void setCheck(Boolean value) {
check.set(value);
}
public ObjectProperty<T> itemProperty() {
return item;
}
public T getItem() {
return item.getValue();
}
public void setItem(T value) {
item.setValue(value);
}
@Override
public String toString() {
return item.getValue().toString();
}
}
sample code
示例代码
public class MainApplication extends Application {
@Override
public void start(Stage stage) {
Scene scene = new Scene(new VBox(), 450, 250);
ComboBox<ComboBoxItemWrap<Person>> cb = new ComboBox<>();
@SuppressWarnings("unchecked")
ObservableList<ComboBoxItemWrap<Person>> options = FXCollections.observableArrayList(
new ComboBoxItemWrap<>(new Person("A", LocalDate.now().minusDays(12))),
new ComboBoxItemWrap<>(new Person("B", LocalDate.now().minusDays(34))),
new ComboBoxItemWrap<>(new Person("C", LocalDate.now().minusDays(48))),
new ComboBoxItemWrap<>(new Person("D", LocalDate.now().minusDays(56))),
new ComboBoxItemWrap<>(new Person("E", LocalDate.now().minusDays(72))),
new ComboBoxItemWrap<>(new Person("F", LocalDate.now().minusDays(96)))
);
cb.setCellFactory( c -> {
ListCell<ComboBoxItemWrap<Person>> cell = new ListCell<>(){
@Override
protected void updateItem(ComboBoxItemWrap<Person> item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
final CheckBox cb = new CheckBox(item.toString());
cb.selectedProperty().bind(item.checkProperty());
setGraphic(cb);
}
}
};
cell.addEventFilter(MouseEvent.MOUSE_RELEASED, event -> {
cell.getItem().checkProperty().set(!cell.getItem().checkProperty().get());
StringBuilder sb = new StringBuilder();
cb.getItems().filtered( f-> f!=null).filtered( f-> f.getCheck()).forEach( p -> {
sb.append("; "+p.getItem());
});
final String string = sb.toString();
cb.setPromptText(string.substring(Integer.min(2, string.length())));
});
return cell;
});
cb.setItems(options);
VBox root = (VBox) scene.getRoot();
Button bt = new Button("test");
bt.setOnAction(event -> {
cb.getItems().filtered( f -> f.getCheck()).forEach( item -> System.out.println(item.getItem()));
});
root.getChildren().addAll(cb, bt);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}