/** * Get more info at : www.jrebirth.org . * Copyright JRebirth.org © 2011-2013 * Contact : sebastien.bordes@jrebirth.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jrebirth.af.core.ui; import javafx.event.Event; import javafx.scene.Node; import javafx.util.Callback; import org.jrebirth.af.api.command.Command; import org.jrebirth.af.api.command.CommandBean; import org.jrebirth.af.api.exception.CoreException; import org.jrebirth.af.api.exception.CoreRuntimeException; import org.jrebirth.af.api.service.Service; import org.jrebirth.af.api.ui.Model; import org.jrebirth.af.api.ui.View; import org.jrebirth.af.api.wave.Wave; import org.jrebirth.af.api.wave.WaveBean; import org.jrebirth.af.api.wave.contract.WaveData; import org.jrebirth.af.api.wave.contract.WaveType; import org.jrebirth.af.core.ui.handler.AbstractNamedEventHandler; import org.jrebirth.af.core.wave.JRebirthWaves; /** * The abstract class <strong>AbstractController</strong>. * * Base implementation of the controller. * * @author Sébastien Bordes * * @param <M> the class type of the model of the view controlled * @param <V> the class type of the view controlled */ public abstract class AbstractController<M extends Model, V extends View<M, ?, ?>> extends AbstractBaseController<M, V> { /** * Default Constructor. * * @param view the controlled view * * @throws CoreException if an error occurred while creating event handlers */ public AbstractController(final V view) throws CoreException { super(view); } /** * Link the creation of a wave to an event triggered on a node. * * This method doesn't use any callback function to trigger the launch the wave. * * @param node the node to follow * @param eventType the type of the event to follow * @param waveType the type of the wave to create * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkWave(final Node node, final javafx.event.EventType<E> eventType, final WaveType waveType, final WaveData<?>... waveData) { linkWave(node, eventType, waveType, null, waveData); } /** * Link the creation of a wave to an event triggered on a node. * * @param node the node to follow * @param eventType the type of the event to follow * @param waveType the type of the wave to create * @param callback the call back to use to check if the wave can be sent * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkWave(final Node node, final javafx.event.EventType<E> eventType, final WaveType waveType, final Callback<E, Boolean> callback, final WaveData<?>... waveData) { node.addEventHandler(eventType, new AbstractNamedEventHandler<E>("LinkWave") { /** * Handle the triggered event. */ @Override public void handle(final E event) { if (callback == null || callback.call(event)) { getModel().sendWave(waveType, waveData); } } }); } /** * Link a command to an event triggered on a node. * * This method doesn't use any callback function to trigger the command. * * @param node the node to follow * @param eventType the type of the event to follow * @param commandClass the command to launch * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkCommand(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Command> commandClass, final WaveData<?>... waveData) { linkCommand(node, eventType, commandClass, null, waveData); } /** * Link a command to an event triggered on a node. * * @param node the node to follow * @param eventType the type of the event to follow * @param commandClass the command to launch * @param callback the call back to use to check if the command can be called * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkCommand(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Command> commandClass, final Callback<E, Boolean> callback, final WaveData<?>... waveData) { // LinkCommand node.addEventHandler(eventType, event -> { if (callback == null || callback.call(event)) { getModel().callCommand(commandClass, waveData); } }); } /** * Link an User Interface action to an event triggered on a node. * * This method doesn't use any callback function to trigger attach the node. * * Don't forget to add a placeholder to indicate where to attach the model node created * * @param node the node to follow * @param eventType the type of the event to follow * @param modelClass the model to display * @param waveData additional Wave data, Must contain either #JRebirthWaves.ATTACH_UI_NODE_PLACEHOLDER or #JRebirthWaves.ADD_UI_CHILDREN_PLACEHOLDER wave data to indicate where to attach the * created model * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkUi(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Model> modelClass, final WaveData<?>... waveData) { linkUi(node, eventType, modelClass, null, waveData); } /** * Link an User Interface action to an event triggered on a node. * * Don't forget to add a placeholder to indicate where to attach the model node created * * @param node the node to follow * @param eventType the type of the event to follow * @param modelClass the model to display * @param callback the call back to use to check if the ui can be attached * @param waveData additional Wave data, Must contain either #JRebirthWaves.ATTACH_UI_NODE_PLACEHOLDER or #JRebirthWaves.ADD_UI_CHILDREN_PLACEHOLDER wave data to indicate where to attach the * created model * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkUi(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Model> modelClass, final Callback<E, Boolean> callback, final WaveData<?>... waveData) { boolean noHookFound = true; // Check if the contract is respected by searching a placeholder from WaveData WaveData<?> wd; for (int i = 0; i < waveData.length && noHookFound; i++) { wd = waveData[i]; if ((JRebirthWaves.ATTACH_UI_NODE_PLACEHOLDER.equals(wd.getKey()) || JRebirthWaves.ADD_UI_CHILDREN_PLACEHOLDER.equals(wd.getKey())) && wd.getValue() != null) { noHookFound = false; } } // Stop the process if no placeholder have been found to attach the model-view created if (noHookFound) { throw new CoreRuntimeException("LinkUi must be called with either JRebirthWaves.ATTACH_UI_NODE_PLACEHOLDER or JRebirthWaves.ADD_UI_CHILDREN_PLACEHOLDER Wave Data provided"); } // LinkUi node.addEventHandler(eventType, event -> { if (callback == null || callback.call(event)) { getModel().attachUi(modelClass, waveData); } }); } /** * Link a Service to an event triggered on a node. * * This method doesn't use any callback function to call the service. * * @param node the node to follow * @param eventType the type of the event to follow * @param serviceClass the service to call * @param waveType the method of the service call * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkService(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Service> serviceClass, final WaveType waveType, final WaveData<?>... waveData) { linkService(node, eventType, serviceClass, waveType, null, waveData); } /** * Link a Service to an event triggered on a node. * * @param node the node to follow * @param eventType the type of the event to follow * @param serviceClass the service to call * @param waveType the method of the service call * @param callback the call back to use to check if the service can be called * @param waveData additional Wave data * * @param <E> The type of JavaFX Event to track */ protected <E extends Event> void linkService(final Node node, final javafx.event.EventType<E> eventType, final Class<? extends Service> serviceClass, final WaveType waveType, final Callback<E, Boolean> callback, final WaveData<?>... waveData) { // LinkService node.addEventHandler(eventType, event -> { if (callback == null || callback.call(event)) { getModel().returnData(serviceClass, waveType, waveData); } }); } /** * Redirect to {@link Model#callCommand(Class, WaveData...)}. * * @param commandClass the command class to call * @param data the data to transport * * @return the wave created and sent to JIT, be careful when you use a strong reference it can hold a lot of objects */ protected Wave callCommand(final Class<? extends Command> commandClass, final WaveData<?>... data) { return getModel().callCommand(commandClass, data); } /** * Redirect to {@link Model#callCommand(Class, WaveBean)}. * * @param commandClass the command class to call * @param waveBean the WaveBean that holds all required wave data * * @param <WB> the type of the wave bean to used * * @return the wave created and sent to JIT, be careful when you use a strong reference it can hold a lot of objects */ protected <WB extends WaveBean> Wave callCommand(final Class<? extends CommandBean<WB>> commandClass, final WB waveBean) { return getModel().callCommand(commandClass, waveBean); } }