Initial project
This commit is contained in:
317
src/main/java/com/imyeyu/fx/config/BindingsConfig.java
Normal file
317
src/main/java/com/imyeyu/fx/config/BindingsConfig.java
Normal file
@@ -0,0 +1,317 @@
|
||||
package com.imyeyu.fx.config;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.FloatProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleFloatProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.ObservableSet;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import com.imyeyu.config.BaseConverter;
|
||||
import com.imyeyu.config.ConfigLoader;
|
||||
import com.imyeyu.fx.TimiFX;
|
||||
import com.imyeyu.fx.utils.BgFill;
|
||||
import com.imyeyu.java.ref.Ref;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 配置绑定
|
||||
*
|
||||
* @author 夜雨
|
||||
* @since 2021-10-26 10:27
|
||||
*/
|
||||
public final class BindingsConfig {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @version 2024-04-14 09:30
|
||||
*/
|
||||
public abstract static class PropertyConverter<T extends Property<?>, K> extends BaseConverter<T, Object> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected K serialize(Field field, T t) {
|
||||
if (t.getValue() == null) {
|
||||
return null;
|
||||
}
|
||||
return (K) t.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 夜雨
|
||||
* @version 2024-04-28 15:23
|
||||
*/
|
||||
public interface ObjectPropertyConverter<T> {
|
||||
|
||||
T serialize(Object t);
|
||||
|
||||
Object deserialize(String data);
|
||||
}
|
||||
|
||||
public static final PropertyConverter<StringProperty, String> STRING = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected StringProperty deserialize(Field field, Object data) {
|
||||
SimpleStringProperty property = new SimpleStringProperty();
|
||||
if (data != null) {
|
||||
property.set(data.toString());
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final PropertyConverter<IntegerProperty, Integer> INTEGER = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected IntegerProperty deserialize(Field field, Object data) {
|
||||
SimpleIntegerProperty property = new SimpleIntegerProperty();
|
||||
if (data != null) {
|
||||
property.set(Integer.parseInt(data.toString()));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final PropertyConverter<LongProperty, Long> LONG = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected LongProperty deserialize(Field field, Object data) {
|
||||
SimpleLongProperty property = new SimpleLongProperty();
|
||||
if (data != null) {
|
||||
property.set(Long.parseLong(data.toString()));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final PropertyConverter<DoubleProperty, Double> DOUBLE = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected DoubleProperty deserialize(Field field, Object data) {
|
||||
SimpleDoubleProperty property = new SimpleDoubleProperty();
|
||||
if (data != null) {
|
||||
property.set(Double.parseDouble(data.toString()));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final PropertyConverter<FloatProperty, Float> FLOAT = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected FloatProperty deserialize(Field field, Object data) {
|
||||
SimpleFloatProperty property = new SimpleFloatProperty();
|
||||
if (data != null) {
|
||||
property.set(Float.parseFloat(data.toString()));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final PropertyConverter<BooleanProperty, Boolean> BOOLEAN = new PropertyConverter<>() {
|
||||
|
||||
@Override
|
||||
protected BooleanProperty deserialize(Field field, Object data) {
|
||||
SimpleBooleanProperty property = new SimpleBooleanProperty();
|
||||
if (data != null) {
|
||||
property.set(Boolean.parseBoolean(data.toString()));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** 颜色转换,配置值格式为 0x11223344 */
|
||||
public static final BaseConverter<ObjectProperty<Color>, String> COLOR = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected String serialize(Field field, ObjectProperty<Color> property) {
|
||||
return TimiFX.toHexString(property.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectProperty<Color> deserialize(Field field, String data) {
|
||||
SimpleObjectProperty<Color> property = new SimpleObjectProperty<>();
|
||||
if (data != null) {
|
||||
property.set(TimiFX.fromHexString(data));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
/** 颜色配置转换 */
|
||||
public static final BaseConverter<ObjectProperty<Paint>, String> PAINT = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected String serialize(Field field, ObjectProperty<Paint> property) {
|
||||
return TimiFX.toHexString(Color.valueOf(property.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectProperty<Paint> deserialize(Field field, String data) {
|
||||
SimpleObjectProperty<Paint> property = new SimpleObjectProperty<>();
|
||||
if (data != null) {
|
||||
property.set(Paint.valueOf(data));
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
/** 基本填充背景颜色配置转换 */
|
||||
public static final BaseConverter<ObjectProperty<Background>, String> BG_FILL = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected String serialize(Field field, ObjectProperty<Background> property) {
|
||||
return TimiFX.toHexString(Color.valueOf(property.getValue().getFills().getFirst().getFill().toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectProperty<Background> deserialize(Field field, String data) {
|
||||
SimpleObjectProperty<Background> property = new SimpleObjectProperty<>();
|
||||
if (data != null) {
|
||||
property.set(new BgFill(data).build());
|
||||
}
|
||||
return property;
|
||||
}
|
||||
};
|
||||
|
||||
public static final BaseConverter<ObjectProperty<?>, String> OBJECT = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected String serialize(Field field, ObjectProperty<?> property) {
|
||||
Type genericType = field.getGenericType();
|
||||
if (genericType instanceof ParameterizedType pt) {
|
||||
try {
|
||||
Class<?> propertyGenericClass = Class.forName(pt.getActualTypeArguments()[0].getTypeName());
|
||||
if (Enum.class.isAssignableFrom(propertyGenericClass)) {
|
||||
if (property.get() == null) {
|
||||
return null;
|
||||
}
|
||||
return property.get().toString();
|
||||
}
|
||||
if (OBJECT_CONVERTER_MAP.containsKey(propertyGenericClass)) {
|
||||
return OBJECT_CONVERTER_MAP.get(propertyGenericClass).serialize(property.get()).toString();
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("not found " + field.getType() + " property converter");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected ObjectProperty<?> deserialize(Field field, String data) {
|
||||
Type genericType = field.getGenericType();
|
||||
if (genericType instanceof ParameterizedType pt) {
|
||||
try {
|
||||
Class<?> propertyGenericClass = Class.forName(pt.getActualTypeArguments()[0].getTypeName());
|
||||
if (Enum.class.isAssignableFrom(propertyGenericClass)) {
|
||||
SimpleObjectProperty<Object> property = new SimpleObjectProperty<>();
|
||||
property.set(Ref.toType((Class<Enum<?>>) propertyGenericClass, data));
|
||||
return property;
|
||||
}
|
||||
if (OBJECT_CONVERTER_MAP.containsKey(propertyGenericClass)) {
|
||||
SimpleObjectProperty<Object> property = new SimpleObjectProperty<>();
|
||||
property.set(OBJECT_CONVERTER_MAP.get(propertyGenericClass).deserialize(data));
|
||||
return property;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("not found " + genericType + " property converter");
|
||||
}
|
||||
};
|
||||
|
||||
public static final BaseConverter<ObservableList<?>, List<?>> OBS_LIST = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected List<?> serialize(Field field, ObservableList<?> obsList) {
|
||||
return new ArrayList<>(obsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObservableList<?> deserialize(Field field, List<?> list) {
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
return FXCollections.observableList(list);
|
||||
}
|
||||
};
|
||||
|
||||
public static final BaseConverter<ObservableSet<?>, Set<?>> OBS_SET = new BaseConverter<>() {
|
||||
|
||||
@Override
|
||||
protected Set<?> serialize(Field field, ObservableSet<?> obsSet) {
|
||||
return new HashSet<>(obsSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObservableSet<?> deserialize(Field field, Set<?> set) {
|
||||
if (set == null) {
|
||||
set = new HashSet<>();
|
||||
}
|
||||
return FXCollections.observableSet(set);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Map<Class<?>, PropertyConverter<?, ?>> DEFAULT_CONVERTER_MAP = Collections.unmodifiableMap(new HashMap<>() {{
|
||||
put(StringProperty.class, STRING);
|
||||
put(IntegerProperty.class, INTEGER);
|
||||
put(LongProperty.class, LONG);
|
||||
put(DoubleProperty.class, DOUBLE);
|
||||
put(FloatProperty.class, FLOAT);
|
||||
put(BooleanProperty.class, BOOLEAN);
|
||||
}});
|
||||
|
||||
public static final Map<Class<?>, ObjectPropertyConverter<?>> OBJECT_CONVERTER_MAP = new HashMap<>();
|
||||
|
||||
public static <T> ConfigLoader<T> build(String path, Class<T> clazz) {
|
||||
return build(path, path, clazz);
|
||||
}
|
||||
|
||||
public static <T> ConfigLoader<T> build(String srcPath, String distPath, Class<T> clazz) {
|
||||
ConfigLoader<T> loader = new ConfigLoader<>(srcPath, distPath, clazz);
|
||||
addAllFXConverter(loader);
|
||||
return loader;
|
||||
}
|
||||
|
||||
public static void addAllFXConverter(ConfigLoader<?> loader) {
|
||||
for (Map.Entry<Class<?>, BindingsConfig.PropertyConverter<?, ?>> item : BindingsConfig.DEFAULT_CONVERTER_MAP.entrySet()) {
|
||||
loader.addConverter(item.getKey(), item.getValue());
|
||||
}
|
||||
loader.addConverter(ObjectProperty.class, BindingsConfig.OBJECT);
|
||||
loader.addConverter(ObservableSet.class, BindingsConfig.OBS_SET);
|
||||
loader.addConverter(ObservableList.class, BindingsConfig.OBS_LIST);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user