拆分模块
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
package com.ecep.contract.controller;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
|
||||
import com.ecep.contract.controller.tab.RefreshableSkin;
|
||||
import com.ecep.contract.controller.tab.TabSkin;
|
||||
import com.ecep.contract.model.IdentityEntity;
|
||||
import com.ecep.contract.service.ViewModelService;
|
||||
import com.ecep.contract.util.UITools;
|
||||
import com.ecep.contract.vm.BaseViewModel;
|
||||
import com.ecep.contract.vm.IdentityViewModel;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.stage.WindowEvent;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public abstract class AbstEntityController<T extends IdentityEntity, TV extends IdentityViewModel<T>>
|
||||
extends BaseController {
|
||||
|
||||
/**
|
||||
* 保存按钮
|
||||
*/
|
||||
public Button saveBtn;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
protected TV viewModel;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
protected CompletableFuture<T> loadedFuture;
|
||||
private final ObservableList<TabSkin> tabSkins = FXCollections.observableArrayList();
|
||||
|
||||
@Override
|
||||
public void onShown(WindowEvent windowEvent) {
|
||||
Class<?> aClass = getClass();
|
||||
super.onShown(windowEvent);
|
||||
loadedFuture = CompletableFuture.supplyAsync(() -> {
|
||||
T entity = loadEntity();
|
||||
if (entity == null) {
|
||||
// fixed, bind change if new view model create
|
||||
if (viewModel != null) {
|
||||
viewModel.bindListener();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
setStatus();
|
||||
viewModel.update(entity);
|
||||
});
|
||||
viewModel.bindListener();
|
||||
return entity;
|
||||
});
|
||||
|
||||
registerTabSkins();
|
||||
if (saveBtn != null) {
|
||||
saveBtn.disableProperty().bind(createTabSkinChangedBindings().not());
|
||||
saveBtn.setOnAction(event -> saveTabSkins());
|
||||
}
|
||||
|
||||
installTabSkins();
|
||||
}
|
||||
|
||||
protected T loadEntity() {
|
||||
return getViewModelService().findById(viewModel.getId().get());
|
||||
}
|
||||
|
||||
public T getEntity() {
|
||||
return getLoadedFuture().join();
|
||||
}
|
||||
|
||||
protected void setEntity(T entity) {
|
||||
loadedFuture = CompletableFuture.completedFuture(entity);
|
||||
BaseViewModel.updateInFxApplicationThread(entity, viewModel);
|
||||
}
|
||||
|
||||
protected T saveEntity(T entity) {
|
||||
return getViewModelService().save(entity);
|
||||
}
|
||||
|
||||
public T save(T entity) {
|
||||
T saved = saveEntity(entity);
|
||||
setEntity(saved);
|
||||
return saved;
|
||||
}
|
||||
|
||||
protected void registerTabSkins() {
|
||||
}
|
||||
|
||||
protected <K extends AbstEntityBasedTabSkin<?, ?, ?>> K registerTabSkin(Tab tab, Function<Tab, K> func) {
|
||||
K f = func.apply(tab);
|
||||
if (f != null) {
|
||||
tabSkins.add(f);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
protected void installTabSkins() {
|
||||
for (TabSkin tabSkin : tabSkins) {
|
||||
try {
|
||||
tabSkin.install();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(tabSkin + ".install", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveTabSkins() {
|
||||
for (TabSkin tabSkin : tabSkins) {
|
||||
try {
|
||||
tabSkin.save();
|
||||
} catch (Exception e) {
|
||||
UITools.showExceptionAndWait("Tab" + tabSkin.getTab().getText() + " 保存失败,请检查", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TabSkin getTabSkin(Tab tab) {
|
||||
for (TabSkin tabSkin : tabSkins) {
|
||||
if (tabSkin.getTab() == tab) {
|
||||
return tabSkin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BooleanBinding createTabSkinChangedBindings() {
|
||||
return Bindings.createBooleanBinding(() -> {
|
||||
for (TabSkin tabSkin : tabSkins) {
|
||||
if (tabSkin.changeProperty().get()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, tabSkins.stream().map(TabSkin::changeProperty).toArray(BooleanProperty[]::new));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <C> C getTabSkin(Class<C> skinClass) {
|
||||
for (TabSkin tabSkin : tabSkins) {
|
||||
if (tabSkin.getClass().isAssignableFrom(skinClass)) {
|
||||
return (C) tabSkin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onHidden(WindowEvent windowEvent) {
|
||||
if (viewModel != null) {
|
||||
try {
|
||||
viewModel.unBindListener();
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
uninstallTabSkins();
|
||||
super.onHidden(windowEvent);
|
||||
}
|
||||
|
||||
protected void uninstallTabSkins() {
|
||||
tabSkins.forEach(TabSkin::dispose);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新
|
||||
*
|
||||
* @param button 按钮
|
||||
*/
|
||||
public void refreshByButton(Button button) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
button.setDisable(true);
|
||||
refresh().whenComplete((v, ex) -> {
|
||||
button.setDisable(false);
|
||||
if (ex != null) {
|
||||
setStatus(ex.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> refresh() {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
T entity = loadEntity();
|
||||
|
||||
Platform.runLater(() -> {
|
||||
setEntity(entity);
|
||||
|
||||
List<RefreshableSkin> list = tabSkins.stream()
|
||||
.filter(v -> v instanceof RefreshableSkin)
|
||||
.map(v -> ((RefreshableSkin) v)).toList();
|
||||
|
||||
if (list.isEmpty()) {
|
||||
future.complete(null);
|
||||
return;
|
||||
}
|
||||
|
||||
CompletableFuture.allOf(list
|
||||
.stream()
|
||||
.map(RefreshableSkin::refresh)
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(CompletableFuture<?>[]::new))
|
||||
.whenComplete((v, ex) -> {
|
||||
if (ex != null) {
|
||||
future.completeExceptionally(ex);
|
||||
} else {
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
public abstract ViewModelService<T, TV> getViewModelService();
|
||||
}
|
||||
Reference in New Issue
Block a user