Files
contract-manager/client/src/main/java/com/ecep/contract/controller/ComboBoxUtils.java
songqq 39dbce013f feat(converter): 实现通用枚举转换器和供应商类型转换器
添加EnumEntityStringConverter作为通用枚举转换基类
实现VendorTypeStringConverter用于供应商类型本地化转换
在VendorTypeService中添加findByLocaleAndValue方法支持转换器
优化ComboBoxUtils的绑定逻辑使其支持可选属性
新增VendorCatalogService提供供应商目录CRUD功能
2025-09-22 23:54:50 +08:00

230 lines
7.7 KiB
Java

package com.ecep.contract.controller;
import java.util.List;
import org.springframework.util.StringUtils;
import com.ecep.contract.model.BaseEnumEntity;
import com.ecep.contract.model.BasedEntity;
import com.ecep.contract.model.IdentityEntity;
import com.ecep.contract.model.NamedEntity;
import com.ecep.contract.service.IEntityService;
import javafx.beans.property.Property;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
public class ComboBoxUtils {
static String formatEntity(Object t) {
if (t == null) {
return "全部";
}
if (t instanceof BasedEntity e) {
return e.toPrettyString();
}
if (t instanceof BaseEnumEntity<?> e) {
return e.getValue();
}
if (t instanceof NamedEntity named) {
return named.getName();
}
return t.toString();
}
static <T> T fromString(List<T> dataset, String string) {
if (dataset == null) {
// 没办法识别
return null;
}
if (!StringUtils.hasText(string)) {
// 没办法识别
return null;
}
for (T t : dataset) {
if (t == null) {
continue;
}
if (t instanceof BasedEntity e) {
if (e.toPrettyString().equals(string)) {
return t;
}
}
if (t instanceof BaseEnumEntity<?> e) {
if (e.getValue().equals(string)) {
return t;
}
}
if (t instanceof NamedEntity named) {
if (named.getName().equals(string)) {
return t;
}
}
if (t.toString().equals(string)) {
return t;
}
}
return null;
}
private static class ComboBoxStringConverter<T> extends javafx.util.StringConverter<T> {
private final List<T> dataset;
public ComboBoxStringConverter(ObservableList<T> list) {
dataset = list;
}
@Override
public String toString(T t) {
return formatEntity(t);
}
@Override
public T fromString(String string) {
return ComboBoxUtils.fromString(dataset, string);
}
}
public static <T> void initialComboBox(ComboBox<T> comboBox, List<T> items, boolean hasNull) {
ObservableList<T> list = FXCollections.observableArrayList();
if (hasNull) {
list.add(null);
}
list.addAll(items);
comboBox.setItems(list);
comboBox.setConverter(new ComboBoxStringConverter<>(list));
}
static class EntityStringConverter<T> extends javafx.util.StringConverter<T> {
private final List<T> dataset;
EntityStringConverter(List<T> dataset) {
this.dataset = dataset;
}
@Override
public String toString(T t) {
return formatEntity(t);
}
@Override
public T fromString(String string) {
return ComboBoxUtils.fromString(dataset, string);
}
}
public static <T extends IdentityEntity> void initialComboBox(
ComboBox<T> comboBox, Property<Integer> property, IEntityService<T> queryService, boolean hasNull) {
ObservableList<T> list = FXCollections.observableArrayList();
if (hasNull) {
list.add(null);
}
list.addAll(queryService.findAll());
comboBox.setItems(list);
EntityStringConverter<T> converter = new EntityStringConverter<>(list);
comboBox.setConverter(converter);
if (property != null) {
// 从ComboBox选择到property的单向绑定
comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
property.setValue(newValue != null ? newValue.getId() : null);
});
// 从property到ComboBox的单向绑定
property.addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
comboBox.getSelectionModel().clearSelection();
return;
}
list.stream()
.filter(item -> item != null && newValue.equals(item.getId()))
.findFirst()
.ifPresent(comboBox.getSelectionModel()::select);
});
// 初始化ComboBox的值
if (property.getValue() != null) {
list.stream()
.filter(item -> item != null && property.getValue().equals(item.getId()))
.findFirst()
.ifPresent(comboBox.getSelectionModel()::select);
}
}
}
public static <T extends IdentityEntity & NamedEntity> void initialComboBox(
ComboBox<T> comboBox, Property<T> property, List<T> dataSet, boolean hasNull) {
ObservableList<T> list = FXCollections.observableArrayList();
if (hasNull) {
list.add(null);
}
list.addAll(dataSet);
comboBox.setItems(list);
comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
property.setValue(newValue);
});
EntityStringConverter<T> converter = new EntityStringConverter<>(dataSet);
comboBox.setConverter(converter);
comboBox.valueProperty().bindBidirectional(property);
}
public static <K> void bindComboBox(ComboBox<K> comboBox, Property<K> property) {
property.addListener((observable, oldValue, newValue) -> {
comboBox.setValue(newValue);
// comboBox.getItems().stream().filter(k->k.equals(newValue)).findFirst().ifPresent(comboBox::setValue);
});
comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
property.setValue(null);
return;
}
property.setValue(newValue);
});
}
public static <K extends Enum<?>, T extends BaseEnumEntity<K>> void bindComboBox(ComboBox<T> comboBox,
Property<K> property, List<T> dataSet) {
property.addListener((observable, oldValue, newValue) -> {
dataSet.stream().filter(l -> l.getType() == newValue).findFirst().ifPresent(comboBox::setValue);
});
comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
property.setValue(null);
return;
}
property.setValue(newValue.getType());
});
// comboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
// if (newValue == null) {
// property.setValue(null);
// return;
// }
// property.setValue(newValue.getType());
// });
comboBox.setCellFactory(param -> new ListCell<>() {
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(item.getValue());
}
}
});
K value = property.getValue();
if (value != null) {
dataSet.stream().filter(l -> l.getType() == value).findFirst().ifPresent(comboBox::setValue);
}
}
}