package com.ecep.contract.util; import java.time.LocalDateTime; import java.util.concurrent.CompletableFuture; import com.ecep.contract.Desktop; import com.ecep.contract.SpringApp; import com.ecep.contract.model.SysConf; import com.ecep.contract.service.SysConfService; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; import javafx.scene.control.Control; import lombok.Getter; import lombok.Setter; public abstract class AbstractConfigBounder implements ConfigBounder { @Setter private SysConfService confService; String key; SysConf conf; @Getter @Setter Control control; @Getter @Setter javafx.util.StringConverter converter; @Setter Property property; ObjectProperty modified = new SimpleObjectProperty<>(this, "modified"); ObjectProperty created = new SimpleObjectProperty<>(this, "created"); public AbstractConfigBounder(String key) { this.key = key; } @Override public CompletableFuture runAsync(Runnable runnable) { return CompletableFuture.runAsync(runnable, Desktop.instance.getExecutorService()).exceptionally(ex -> { ex.printStackTrace(); return null; }); } @Override public SysConfService getConfService() { if (confService == null) { confService = SpringApp.getBean(SysConfService.class); } return confService; } @Override public void initialize() { getControl().setDisable(true); runAsync(this::asyncHandle); } protected void asyncHandle() { conf = getConfService().findById(key); if (conf == null) { conf = new SysConf(); conf.setId(key); conf.setCreated(LocalDateTime.now()); conf.setModified(LocalDateTime.now()); conf = getConfService().save(conf); } Property property = getProperty(); property.addListener(this::propertyChanged); bindBidirectional(property); modified.set(conf.getModified()); created.set(conf.getCreated()); getControl().setDisable(false); } public Property getProperty() { if (property == null) { T value = getConverter().fromString(conf.getValue()); property = createProperty(value); setProperty(property); } return property; } public ObjectProperty getModifiedProperty() { return modified; } public ObjectProperty getCreatedProperty() { return created; } @SuppressWarnings("unchecked") protected Property createProperty(T value) { if (value instanceof Boolean b) { return (Property) new SimpleBooleanProperty(b); } else if (value instanceof Integer i) { return (Property) new SimpleIntegerProperty(i); } else if (value instanceof Double d) { return (Property) new SimpleDoubleProperty(d); } else if (value instanceof String s) { return (Property) new SimpleStringProperty(s); } return new SimpleObjectProperty<>(value); } abstract void bindBidirectional(Property property); void propertyChanged(ObservableValue observable, T oldValue, T newValue) { conf.setValue(getConverter().toString(newValue)); conf.setModified(LocalDateTime.now()); save(); } public void save() { SysConf saved = getConfService().save(conf); modified.set(saved.getModified()); created.set(saved.getCreated()); } }