Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fly office fixing #36

Merged
merged 7 commits into from
Sep 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
import dev.rico.internal.projector.ui.IdentifiableModel;

public interface PostProcessor {
void postProcess(String id, IdentifiableModel model, Object node);
void postProcess(Projector projector, String id, IdentifiableModel model, Object uiObject);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import dev.rico.internal.projector.ui.ManagedUiModel;
import javafx.scene.Node;

import java.util.List;
import java.util.Map;

public interface Projector {
Expand All @@ -33,9 +34,7 @@ public interface Projector {

ControllerProxy<? extends ManagedUiModel> getControllerProxy();

@Deprecated
Map<IdentifiableModel, Node> getModelToNodeMap();

@Deprecated
PostProcessor getPostProcessor();
List<PostProcessor> getPostProcessors();
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,16 @@
import dev.rico.internal.projector.ui.IdentifiableModel;
import dev.rico.internal.projector.ui.ItemModel;
import dev.rico.internal.projector.ui.ManagedUiModel;
import dev.rico.internal.projector.ui.WithPadding;
import dev.rico.internal.projector.ui.dialog.DialogModel;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.layout.Region;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.WeakHashMap;
import java.util.*;
import java.util.function.Supplier;

import static dev.rico.client.remoting.FXBinder.bind;
Expand All @@ -47,7 +45,7 @@ public class JavaFXProjectorImpl implements Projector {

private final ControllerProxy<? extends ManagedUiModel> controllerProxy;

private final PostProcessor postProcessor;
private final List<PostProcessor> postProcessors;

private final Map<Class<? extends ItemModel>, ProjectorNodeFactory> factories;

Expand All @@ -57,9 +55,9 @@ public class JavaFXProjectorImpl implements Projector {

private final ObjectProperty<Node> root = new SimpleObjectProperty<>();

public JavaFXProjectorImpl(final ControllerProxy<? extends ManagedUiModel> controllerProxy, final PostProcessor postProcessor) {
public JavaFXProjectorImpl(final ControllerProxy<? extends ManagedUiModel> controllerProxy, List<PostProcessor> postProcessors) {
this.controllerProxy = Assert.requireNonNull(controllerProxy, "controllerProxy");
this.postProcessor = Assert.requireNonNull(postProcessor, "postProcessor");
this.postProcessors = postProcessors;

try {
factories = loadServiceProviders(ProjectorNodeFactory.class);
Expand Down Expand Up @@ -120,17 +118,28 @@ public ObjectProperty<Node> rootProperty() {
@Override
public <N extends Node> N createNode(final ItemModel itemModel) {
if (itemModel == null) return null;
if (modelToNodeMap.containsKey(itemModel)) {
return (N) modelToNodeMap.get(itemModel);
}
final ProjectorNodeFactory factory = factories.get(itemModel.getClass());
if (factory == null) {
throw new IllegalArgumentException("No factory found for " + itemModel.getClass());
}
final N node = (N) factory.create(this, itemModel);
modelToNodeMap.put(itemModel, node);
bindDefaultProperties(node, itemModel);
postProcess(node, itemModel);
return node;
}

private <N extends Node> void bindDefaultProperties(final N node, final ItemModel<?> model) {
bind(node.disableProperty()).to(model.disableProperty(), value -> fallback(value, node::isDisable));
bind(node.visibleProperty()).to(model.visibleProperty(), value -> fallback(value, node::isVisible));
bind(node.managedProperty()).to(model.managedProperty(), value -> fallback(value, node::isManaged));
model.getStyleClass().addAll(node.getStyleClass());
bind(node.styleProperty()).to(model.styleProperty());
bind(node.getStyleClass()).bidirectionalTo(model.getStyleClass());

if (node instanceof Region) {
final Region region = (Region) node;
bind(region.minWidthProperty()).to(model.minWidthProperty(), value -> fallback(value, region::getMinWidth));
Expand All @@ -139,13 +148,11 @@ private <N extends Node> void bindDefaultProperties(final N node, final ItemMode
bind(region.maxHeightProperty()).to(model.maxHeightProperty(), value -> fallback(value, region::getMaxHeight));
bind(region.prefWidthProperty()).to(model.prefWidthProperty(), value -> fallback(value, region::getPrefWidth));
bind(region.prefHeightProperty()).to(model.prefHeightProperty(), value -> fallback(value, region::getPrefHeight));
if (model instanceof WithPadding) {
WithPadding withPadding = (WithPadding) model;
bind(region.paddingProperty()).to(withPadding.paddingProperty(), value -> value == null ? new Insets(0) : new Insets(withPadding.getPadding()));
}
}
bind(node.disableProperty()).to(model.disableProperty(), value -> fallback(value, node::isDisable));
bind(node.visibleProperty()).to(model.visibleProperty(), value -> fallback(value, node::isVisible));
bind(node.managedProperty()).to(model.managedProperty(), value -> fallback(value, node::isManaged));
model.getStyleClass().addAll(node.getStyleClass());
bind(node.styleProperty()).to(model.styleProperty());
bind(node.getStyleClass()).bidirectionalTo(model.getStyleClass());
}

private <T> T fallback(final T fromBinding, final Supplier<T> fallbackGetter) {
Expand All @@ -156,9 +163,9 @@ private void postProcess(final Node node, final ItemModel itemModel) {
Assert.requireNonNull(itemModel, "itemModel");
itemModel.idProperty().onChanged(evt -> {
final String newId = evt.getNewValue();
postProcessor.postProcess(newId, itemModel, node);
postProcessors.forEach(processor -> processor.postProcess(this, newId, itemModel, node));
});
postProcessor.postProcess(itemModel.getId(), itemModel, node);
postProcessors.forEach(processor -> processor.postProcess(this, itemModel.getId(), itemModel, node));
}

@Override
Expand All @@ -172,7 +179,7 @@ public Map<IdentifiableModel, Node> getModelToNodeMap() {
}

@Override
public PostProcessor getPostProcessor() {
return postProcessor;
public List<PostProcessor> getPostProcessors() {
return postProcessors;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import dev.rico.client.projector.Projector;
import dev.rico.client.remoting.ControllerProxy;
import dev.rico.client.remoting.Param;
import dev.rico.internal.client.projector.uimanager.UnexpectedErrorDialog;
import dev.rico.internal.core.Assert;
import dev.rico.internal.projector.ui.IdentifiableModel;
Expand All @@ -32,22 +33,22 @@

public interface ActionHandlerFactory {

default EventHandler<ActionEvent> createOnActionHandler(final String type, final IdentifiableModel identifiableModel, final Projector projector) {
default EventHandler<ActionEvent> createOnActionHandler(final Projector projector, final String action, final IdentifiableModel identifiableModel, Param... args) {
Assert.requireNonNull(projector, "projector");
final Map<IdentifiableModel, Node> modelToNodeMap = projector.getModelToNodeMap();
Assert.requireNonNull(modelToNodeMap, "modelToNodeMap");
return createOnActionHandler(type, modelToNodeMap.get(identifiableModel), projector);
return createOnActionHandler(projector, action, modelToNodeMap.get(identifiableModel), args);
}

default EventHandler<ActionEvent> createOnActionHandler(final String type, final Node node, final Projector projector) {
Assert.requireNonNull(type, "type");
default EventHandler<ActionEvent> createOnActionHandler(final Projector projector, final String action, final Node node, Param... args) {
Assert.requireNonNull(action, "action");
Assert.requireNonNull(node, "node");
Assert.requireNonNull(projector, "projector");
final ControllerProxy<? extends ManagedUiModel> controllerProxy = projector.getControllerProxy();
Assert.requireNonNull(controllerProxy, "controllerProxy");
return event -> {
event.consume();
final CompletableFuture<Void> typeInvocation = controllerProxy.invoke(type);
final CompletableFuture<Void> typeInvocation = controllerProxy.invoke(action, args);
Assert.requireNonNull(typeInvocation, "typeInvocation");
typeInvocation.exceptionally(throwable -> UnexpectedErrorDialog.showError(node, throwable));
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private static <T> void subscribe(final Property<T> property, final Consumer<T>
protected S createButtonBase(final Projector projector, final T model, final S node) {
configureButton(model, node);
if (model.getAction() != null) {
node.setOnAction(createOnActionHandler(model.getAction(), node, projector));
node.setOnAction(createOnActionHandler(projector, model.getAction(), node));
}
return node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public CheckBox create(final Projector projector, final CheckBoxModel model) {
bind(checkBox.selectedProperty()).bidirectionalTo(model.selectedProperty());
bind(checkBox.textProperty()).to(model.captionProperty());
if (model.getAction() != null) {
checkBox.setOnAction(createOnActionHandler(model.getAction(), checkBox, projector));
checkBox.setOnAction(createOnActionHandler(projector, model.getAction(), checkBox));
}
return checkBox;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.io.InputStream;

import static dev.rico.client.remoting.FXBinder.bind;

Expand Down Expand Up @@ -55,12 +55,12 @@ private Image getImageForPath(final String v) {
if (v == null) {
return null;
} else {
final URL resource = Image.class.getResource(v.substring("classpath:".length()));
final InputStream resource = ImageViewFactory.class.getResourceAsStream(v.substring("classpath:".length()));
if (resource == null) {
LOG.warn("Image '{}' not found!", v);
return null;
}
return new Image(resource.toExternalForm());
return new Image(resource);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@

import dev.rico.client.projector.Projector;
import dev.rico.client.projector.spi.ProjectorNodeFactory;
import dev.rico.internal.client.projector.uimanager.TextInputControlConfigurator;
import dev.rico.internal.core.Assert;
import dev.rico.internal.projector.ui.PasswordFieldModel;
import dev.rico.internal.projector.ui.flowpane.FlowPaneModel;
import javafx.scene.control.PasswordField;
import javafx.scene.layout.FlowPane;

import static dev.rico.client.remoting.FXBinder.bind;
import static dev.rico.internal.client.projector.uimanager.TextField.configureTextInputControl;

public class PasswordFieldFactory implements ProjectorNodeFactory<PasswordFieldModel, PasswordField> {
public class PasswordFieldFactory implements ProjectorNodeFactory<PasswordFieldModel, PasswordField>, TextInputControlConfigurator {

@Override
public PasswordField create(final Projector projector, final PasswordFieldModel model) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public RadioButton create(final Projector projector, final RadioButtonModel mode
bind(button.selectedProperty()).bidirectionalTo(model.selectedProperty());
bind(button.textProperty()).to(model.captionProperty());
if (model.getAction() != null) {
button.setOnAction(createOnActionHandler(model.getAction(), button, projector));
button.setOnAction(createOnActionHandler(projector, model.getAction(), button));
}
return button;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
*/
package dev.rico.internal.client.projector.factories;

import static dev.rico.client.remoting.FXBinder.bind;

import java.time.Instant;

import dev.rico.client.projector.Projector;
import dev.rico.client.projector.spi.ProjectorNodeFactory;
import dev.rico.client.remoting.FXBinder;
Expand All @@ -34,12 +30,7 @@
import dev.rico.internal.client.projector.uimanager.UnexpectedErrorDialog;
import dev.rico.internal.core.Assert;
import dev.rico.internal.projector.ui.IdentifiableModel;
import dev.rico.internal.projector.ui.table.TableCheckBoxColumnModel;
import dev.rico.internal.projector.ui.table.TableChoiceBoxColumnModel;
import dev.rico.internal.projector.ui.table.TableColumnModel;
import dev.rico.internal.projector.ui.table.TableModel;
import dev.rico.internal.projector.ui.table.TableRowModel;
import dev.rico.internal.projector.ui.table.TableStringColumnModel;
import dev.rico.internal.projector.ui.table.*;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
Expand All @@ -50,7 +41,12 @@
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.ChoiceBoxTableCell;
import javafx.scene.control.cell.TextFieldTableCell;
import dev.rico.internal.projector.ui.table.TableInstantColumnModel;
import javafx.util.Callback;
import javafx.util.converter.IntegerStringConverter;

import java.time.Instant;

import static dev.rico.client.remoting.FXBinder.bind;

public class TableFactory implements ProjectorNodeFactory<TableModel, TableView> {

Expand Down Expand Up @@ -87,10 +83,24 @@ public Class<TableModel> getSupportedType() {
bind(tableColumn.textProperty()).to(conversionInfo.getInput().captionProperty());
bind(tableColumn.prefWidthProperty()).to(conversionInfo.getInput().prefWidthProperty(), value -> getValue(value, 80));
bind(tableColumn.editableProperty()).to(conversionInfo.getInput().editableProperty(), value -> getValue(value, true));
bind(tableColumn.visibleProperty()).to(conversionInfo.getInput().visibleProperty(), value -> getValue(value, true));

tableColumn.setCellValueFactory(param -> FXWrapper.wrapObjectProperty(
param.getValue().getCells().get(conversionInfo.getIndex()).valueProperty()));
if (conversionInfo.getInput() instanceof TableInstantColumnModel) {
if (conversionInfo.getInput() instanceof TableIntegerColumnModel) {
((TableColumn) tableColumn).setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
tableColumn.setOnEditCommit(event -> onCommit("onTableIntegerCommit", projector, table, event, conversionInfo));
} else if (conversionInfo.getInput() instanceof TableDoubleColumnModel) {
bind(tableColumn.cellFactoryProperty()).to(conversionInfo.getInput().cellFactoryClassProperty(), className -> {
if (className == null) return null;
try {
return (Callback) Class.forName(className).getConstructor().newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
});
tableColumn.setOnEditCommit(event -> onCommit("onTableDoubleCommit", projector, table, event, conversionInfo));
} else if (conversionInfo.getInput() instanceof TableInstantColumnModel) {
final TableInstantColumnModel columnModel = (TableInstantColumnModel) conversionInfo.getInput();
tableColumn.setCellFactory(column -> new TableCell<TableRowModel, Object>() {
protected void updateItem(final Object item, final boolean empty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@
import javafx.beans.property.ObjectProperty;
import javafx.scene.Node;

import java.util.List;

public class ClientUiManager {

private final JavaFXProjectorImpl projector;

public ClientUiManager(final ControllerProxy<? extends ManagedUiModel> controllerProxy) {
this(controllerProxy, null);
public ClientUiManager(final ControllerProxy<? extends ManagedUiModel> controllerProxy, List<PostProcessor> postProcessors) {
projector = newProjector(controllerProxy, postProcessors);
}

public ClientUiManager(final ControllerProxy<? extends ManagedUiModel> controllerProxy, final PostProcessor postProcessor) {
projector = new JavaFXProjectorImpl(controllerProxy, postProcessor);
protected JavaFXProjectorImpl newProjector(ControllerProxy<? extends ManagedUiModel> controllerProxy, List<PostProcessor> postProcessors) {
return new JavaFXProjectorImpl(controllerProxy, postProcessors);
}

public Node createNode(final ItemModel itemModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.util.LinkedList;
import java.util.List;

public class ManagedUiViewController<M extends ManagedUiModel> extends AbstractViewController<M> implements ViewPresenter {

private static final Logger LOGGER = LoggerFactory.getLogger(ManagedUiViewController.class);

private final BorderPane pane = new BorderPane();
private final List<PostProcessor> postProcessors = new LinkedList<>();

private ClientUiManager factory;
private ClientUiManager uiManager;

public ManagedUiViewController(final String controllerName) {
super(ClientContextHolder.getContext(), controllerName);
Expand All @@ -60,13 +63,17 @@ protected void init() {
try {
FXBinder.bind(isWorkingProperty()).to(getModel().isWorkingProperty());
addCSSIfAvailable(pane);
factory = new ClientUiManager(getControllerProxy(), newPostProcessor());
pane.centerProperty().bind(factory.rootProperty());
uiManager = newClientUiManager();
pane.centerProperty().bind(uiManager.rootProperty());
} catch (final Exception e) {
throw e;
}
}

protected ClientUiManager newClientUiManager() {
return new ClientUiManager(getControllerProxy(), postProcessors);
}

private void addCSSIfAvailable(final Parent parent) {
final URL uri = getClass().getResource(getStyleSheetName());
if (uri != null) {
Expand All @@ -75,11 +82,6 @@ private void addCSSIfAvailable(final Parent parent) {
}
}

protected PostProcessor newPostProcessor() {
return (id, model, node) -> {
};
}

private String getStyleSheetName() {
return getResourceCamelOrLowerCase(false, ".css");
}
Expand Down Expand Up @@ -162,4 +164,8 @@ public SimpleBooleanProperty isWorkingProperty() {
});
return result;
}

public List<PostProcessor> getPostProcessors() {
return postProcessors;
}
}
Loading