带有复选框的JavaFX组合框 问题说明
我尝试创建一个带有复选框的JavaFX组合框 问题说明,java,checkbox,combobox,javafx,Java,Checkbox,Combobox,Javafx,我尝试创建一个JavaFX组合框,其中包含下拉菜单中的复选框。 组合框应是可编辑的,并由一个简单的类提供。 检查项列表应可检查,且在选择后不得关闭下拉菜单 最后,组合框中的文本应可用,并有一个选项(所有选中项) 这是我已经做过的 (1) 一个组合框通过正确选择将检查项呈现为检查框 (2) 从组合框中获取文本 出现的问题 (1) 单击一个项目后,下拉列表关闭,项目的选择状态不变 (2) 据我所知,一次只能选择一个项目 下面是我测试这些东西的代码: 测试程序 如果您在实现中遇到问题,您应该查看项目中
JavaFX
组合框
,其中包含下拉菜单中的复选框
。
组合框应是可编辑的,并由一个简单的类提供。
检查项列表应可检查,且在选择后不得关闭下拉菜单
最后,组合框
中的文本应可用,并有一个选项(所有选中项)
这是我已经做过的
(1) 一个组合框
通过正确选择将检查项
呈现为检查框
(2) 从组合框中获取文本
出现的问题
(1) 单击一个项目后,下拉列表关闭,项目的选择状态不变
(2) 据我所知,一次只能选择一个项目
下面是我测试这些东西的代码:
测试程序
如果您在实现中遇到问题,您应该查看项目中的控件
可以找到源代码。我的示例代码:
班级人员
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()+")";
}
}
公共类人物{
私有StringProperty名称=新的SimpleStringProperty();
private ObjectProperty生日=新的SimpleObjectProperty();
公众人士(){
}
公众人物(字符串名称、LocalDate生日){
setNameValue(名称);
setBirthdayValue(生日);
}
公共StringProperty getNameProperty(){
返回名称;
}
公共字符串getNameValue(){
返回name.getValue();
}
公共void setNameValue(字符串值){
name.setValue(值);
}
公共对象属性getBirthdayProperty(){
回归生日;
}
public LocalDate getBirthdayValue(){
返回birthday.getValue();
}
public void setBirthdayValue(LocalDate值){
生日设置值(value);
}
@凌驾
公共字符串toString(){
返回getNameValue()+”(“+getBirthdayValue()+”);
}
}
简单包装器
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();
}
}
公共类ComboBoxItemWrap{
私有布尔属性检查=新的SimpleBoleanProperty(false);
private ObjectProperty项=新的SimpleObject属性();
ComboBoxItemWrap(){
}
ComboBoxItemWrap(T项){
本.项.集(项);
}
ComboBoxItemWrap(T项,布尔检查){
本.项.集(项);
这个.检查.设置(检查);
}
公共布尔属性checkProperty(){
退货检查;
}
公共布尔getCheck(){
返回check.getValue();
}
公共void setCheck(布尔值){
检查。设置(值);
}
公共对象属性itemProperty(){
退货项目;
}
公共T getItem(){
return item.getValue();
}
公共无效设置项(T值){
项目.设置值(值);
}
@凌驾
公共字符串toString(){
返回item.getValue().toString();
}
}
示例代码
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);
}
}
public类main应用程序扩展应用程序{
@凌驾
公众假期开始(阶段){
场景=新场景(新VBox(),450,250);
ComboBox cb=新ComboBox();
@抑制警告(“未选中”)
ObservableList options=FXCollections.observableArrayList(
新的ComboBoxItemWrap(newPerson(“A”,LocalDate.now().minusDays(12)),
新的ComboBoxItemWrap(newPerson(“B”,LocalDate.now().minusDays(34)),
新建ComboBoxItemWrap(newPerson(“C”,LocalDate.now().minusDays(48)),
新建ComboxItemWrap(newPerson(“D”,LocalDate.now().minusDays(56)),
新的ComboBoxItemWrap(newPerson(“E”,LocalDate.now().minusDays(72)),
新ComboBoxItemWrap(newPerson(“F”,LocalDate.now().minusDays(96)))
);
cb.setCellFactory(c->{
ListCell=新ListCell(){
@凌驾
受保护的void updateItem(ComboBoxItemWrap项,布尔值为空){
super.updateItem(项,空);
如果(!空){
最终复选框cb=新复选框(item.toString());
cb.selectedProperty().bind(item.checkProperty());
设定图形(cb);
}
}
};
cell.addEventFilter(MouseEvent.MOUSE_已发布,事件->{
cell.getItem().checkProperty().set(!cell.getItem().checkProperty().get());
StringBuilder sb=新的StringBuilder();
cb.getItems().filtered(f->f!=null).filtered(f->f.getCheck()).forEach(p->{
sb.append(“;”+p.getItem());
});
最后一个字符串=sb.toString();
setPrompText(string.substring(Integer.min(2,string.length()));
});
返回单元;
});
cb.设置项目(选项);
VBox root=(VBox)scene.getRoot();
按钮bt=新按钮(“测试”);
bt.setOnAction(事件->{
cb.getItems().filtered(f->f.getCheck()).forEach(item->System.out.println(item.getItem());
});
root.getChildren().addAll(cb,bt);
舞台场景;
stage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
组合框
es专门用于从项目列表中选择一个项目。我想对于你想要的功能,我会从一个填充的开始。项目中还有一个你可能想看看。谢谢JoséPereda,不知怎么的,我错过了这个!你能加上这个作为回答来接受它吗?谢谢你好如何将此复选框添加到FXML文件中?请创建一个新问题。
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();
}
}
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);
}
}