Hello,
The class SelectionIteratorModalDialogAction (see code below) displays a set of entities in a modal dialog, one after the other.
It works but when the user changes the position of the dialog on the screen then as soon as he clicks on the previous or the next button, the new dialog is displayed at the originel position and not the position set by the user.
Any idea to keep the dialog in the same place as set by the user?
Pierre
=========================================================================
package org.popsuite.framework.application.frontend.action.wizard;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.jspresso.framework.action.IActionHandler;
import org.jspresso.framework.application.frontend.action.FrontendAction;
import org.jspresso.framework.application.frontend.action.ModalDialogAction;
import org.jspresso.framework.application.frontend.action.wizard.IWizardStepDescriptor;
import org.jspresso.framework.binding.IValueConnector;
import org.jspresso.framework.model.descriptor.IModelDescriptor;
import org.jspresso.framework.util.gui.Dimension;
import org.jspresso.framework.util.i18n.ITranslationProvider;
import org.jspresso.framework.view.IView;
import org.jspresso.framework.view.action.IDisplayableAction;
/**
* Show a list of components one after the other in a dialog view.
* The components must have the same type.
*
* @param <M>
* the actual model component type used.
* @param <E>
* the actual gui component type used.
* @param <F>
* the actual icon type used.
* @param <G>
* the actual action type used.
*/
public class SelectionIteratorModalDialogAction<M, E, F, G> extends FrontendAction<E, F, G> {
private static final String DEFAULT_TITLE_FORMAT = "%s - %s";
private static enum StepReuse {ALLOWED(true), NONE(false);
private final boolean value;
StepReuse(boolean value) {
this.value = value;
}
public boolean getValue() {
return value;
}
};
private List<M> models;
private IDisplayableAction cancelAction;
private IDisplayableAction finishAction;
private IWizardStepDescriptor globalWizardStep;
private Integer height;
private Integer width;
public SelectionIteratorModalDialogAction() {
super();
setCollectionBased(true);
}
/**
* {@inheritDoc}
*/
@Override
public boolean execute(IActionHandler actionHandler,
Map<String, Object> context) {
displayFirstWizardStep(actionHandler, context);
return super.execute(actionHandler, context);
}
private void displayFirstWizardStep(IActionHandler actionHandler, Map<String, Object> context) {
@SuppressWarnings("unchecked")
List<M> selectedModels = (List<M>) getSelectedModels(context);
models = selectedModels;
IValueConnector modelConnector = createWizardStepModelConnector(globalWizardStep, context);
displayWizardStep(null, globalWizardStep, modelConnector, actionHandler, context, StepReuse.NONE);
}
private IValueConnector createWizardStepModelConnector(IWizardStepDescriptor descriptor, Map<String, Object> context) {
return getBackendController(context).createModelConnector(
ACTION_MODEL_NAME,
getWizardStepModelDescriptor(descriptor));
}
private IModelDescriptor getWizardStepModelDescriptor(IWizardStepDescriptor stepDescriptor) {
return stepDescriptor.getViewDescriptor().getModelDescriptor();
}
private M getComponentToEdit(Indexable callingAction) {
int index = 0;
if (callingAction != null) {
index = callingAction.getIndex();
}
return models.get(index);
}
private void displayWizardStep(
Indexable callingAction,
IWizardStepDescriptor wizardStep,
IValueConnector modelConnector,
IActionHandler actionHandler,
Map<String, Object> context,
StepReuse reuseCurrent) {
M component = getComponentToEdit(callingAction);
modelConnector.setConnectorValue(component);
Locale locale = getLocale(context);
IView<E> view = getViewFactory(context).createView(wizardStep.getViewDescriptor(), actionHandler, locale);
getMvcBinder(context).bind(view.getConnector(), modelConnector);
ITranslationProvider translationProvider = getTranslationProvider(context);
StringBuilder title = new StringBuilder();
new Formatter(title).format(DEFAULT_TITLE_FORMAT,
getI18nName(translationProvider, locale),
wizardStep.getI18nName(translationProvider, locale));
Dimension dialogSize = getDialogSize(context);
getController(context).displayModalDialog(
view.getPeer(),
createWizardStepActions(
callingAction,
wizardStep,
view,
actionHandler,
translationProvider,
locale,
modelConnector,
context),
title.toString(),
getSourceComponent(context),
context,
dialogSize,
reuseCurrent.getValue());
}
/**
* Configures the action that will be executed whenever the user cancels the
* wizard.
*
* @param cancelAction
* the cancelAction to set.
*/
public void setCancelAction(IDisplayableAction cancelAction) {
this.cancelAction = cancelAction;
}
/**
* Configures the action that will be executed whenever the user validates the
* wizard.
*
* @param finishAction
* the finishAction to set.
*/
public void setFinishAction(IDisplayableAction finishAction) {
this.finishAction = finishAction;
}
/**
* Configures the wizard step to display.
*
* @param wizardStep
* the wizardStep to set.
*/
public void setWizardStep(IWizardStepDescriptor wizardStep) {
this.globalWizardStep = wizardStep;
}
/**
* Configures explicitely the height of the wizard dialog. It prevents the
* dialog from resizing dynamically depending on the displayed wizard step.
*
* @param height
* the height to set.
*/
public void setHeight(Integer height) {
this.height = height;
}
/**
* Configures explicitely the width of the wizard dialog. It prevents the
* dialog from resizing dynamically depending on the displayed wizard step.
*
* @param width
* the width to set.
*/
public void setWidth(Integer width) {
this.width = width;
}
private G createCancelAction(IWizardStepDescriptor wizardStep,
IActionHandler actionHandler, IView<E> view, Locale locale,
Map<String, Object> context) {
IDisplayableAction cancelActionAdapter = new CancelAction(wizardStep,
cancelAction);
G cancelGAction = getActionFactory(context).createAction(
cancelActionAdapter, actionHandler, view, locale);
return cancelGAction;
}
private G createFinishAction(
Indexable callingAction,
IWizardStepDescriptor wizardStep,
IActionHandler actionHandler,
IView<E> view, Locale locale,
Map<String, Object> context
) {
IDisplayableAction finishActionAdapter = new FinishAction(wizardStep, finishAction);
G finishGAction = getActionFactory(context).createAction(
finishActionAdapter, actionHandler, view, locale);
int index = nextSelectedModelIndex(callingAction, context);
boolean canFinish = wizardStep.canFinish(context) || ! (index > -1);
getActionFactory(context).setActionEnabled(finishGAction, canFinish);
return finishGAction;
}
private G createNextAction(
Indexable callingAction,
IWizardStepDescriptor wizardStep,
IActionHandler actionHandler,
IView<E> view,
ITranslationProvider translationProvider,
Locale locale,
IValueConnector modelConnector,
Map<String, Object> context
) {
NextAction nextAction = new NextAction(wizardStep,
modelConnector,
nextSelectedModelIndex(callingAction, context)
);
nextAction.setIconImageURL(getIconFactory(context).getForwardIconImageURL());
G nextImplementationAction = getActionFactory(context).createAction(nextAction, actionHandler, view, locale);
boolean hasNextStep = hasNextStep(wizardStep, context) && (nextAction.getIndex() > -1);
getActionFactory(context).setActionEnabled(nextImplementationAction, hasNextStep);
String nextStepKey = null;
if (wizardStep.getNextLabelKey() != null) {
nextStepKey = wizardStep.getNextLabelKey();
} else {
nextStepKey = IWizardStepDescriptor.DEFAULT_NEXT_KEY;
}
getActionFactory(context).setActionName(
nextImplementationAction,
translationProvider.getTranslation(nextStepKey, locale)
);
return nextImplementationAction;
}
protected int nextSelectedModelIndex(Indexable callingAction, Map<String, Object> context) {
int[] indices = getSelectedIndices(context);
if (indices == null || indices.length < 1) return -1;
int result = -1;
if (callingAction == null) {
if (indices.length > 1){
result = 1;
}
} else {
int index = callingAction.getIndex();
if ((index > -1) && (index < indices.length)){
result = index + 1;
}
}
return result;
}
protected boolean hasNextStep(IWizardStepDescriptor wizardStep, Map<String, Object> context) {
return wizardStep.getNextStepDescriptor(context) != null ;
}
private G createPreviousAction(
Indexable callingAction,
IWizardStepDescriptor wizardStep,
IActionHandler actionHandler,
IView<E> view,
ITranslationProvider translationProvider,
Locale locale,
IValueConnector modelConnector,
Map<String, Object> context
) {
PreviousAction previousAction = new PreviousAction(wizardStep,
modelConnector,
previousSelectedModelIndex(callingAction, context)
);
previousAction.setIconImageURL(getIconFactory(context).getBackwardIconImageURL());
G previousImplementationAction = getActionFactory(context).createAction(previousAction, actionHandler, view, locale);
boolean hasPreviousStep = hasPreviousStep(wizardStep, context) && (previousAction.getIndex() > -1);
getActionFactory(context).setActionEnabled(previousImplementationAction, hasPreviousStep);
String previousStepKey = null;
if (wizardStep.getPreviousLabelKey() != null) {
previousStepKey = wizardStep.getPreviousLabelKey();
} else {
previousStepKey = IWizardStepDescriptor.DEFAULT_PREVIOUS_KEY;
}
getActionFactory(context).setActionName(
previousImplementationAction,
translationProvider.getTranslation(previousStepKey,
locale));
return previousImplementationAction;
}
protected int previousSelectedModelIndex(Indexable callingAction, Map<String, Object> context) {
int[] indices = getSelectedIndices(context);
if (indices == null || indices.length < 1) return -1;
int result = -1;
if (callingAction != null) {
int index = callingAction.getIndex();
if (index > 0) {
result = index - 1;
}
}
return result;
}
protected boolean hasPreviousStep(IWizardStepDescriptor wizardStep, Map<String, Object> context) {
return wizardStep.getPreviousStepDescriptor(context) != null ;
}
private List<G> createWizardStepActions(
Indexable callingAction,
IWizardStepDescriptor wizardStep,
IView<E> view,
IActionHandler actionHandler,
ITranslationProvider translationProvider,
Locale locale,
IValueConnector modelConnector,
Map<String, Object> context) {
List<G> wizardStepActions = new ArrayList<G>();
G previousGAction = createPreviousAction(callingAction, wizardStep, actionHandler, view, translationProvider, locale, modelConnector, context);
G nextGAction = createNextAction (callingAction, wizardStep, actionHandler, view, translationProvider, locale, modelConnector, context);
G finishGAction = createFinishAction (callingAction, wizardStep, actionHandler, view, locale, context);
G cancelGAction = createCancelAction (wizardStep, actionHandler, view, locale, context);
wizardStepActions.add(previousGAction);
wizardStepActions.add(nextGAction);
wizardStepActions.add(finishGAction);
wizardStepActions.add(cancelGAction);
return wizardStepActions;
}
private Dimension getDialogSize(Map<String, Object> context) {
Dimension dialogSize = (Dimension) context.get(ModalDialogAction.DIALOG_SIZE);
if (width != null && height != null) {
dialogSize = new Dimension(width.intValue(), height.intValue());
}
return dialogSize;
}
private class CancelAction extends FrontendAction<E, F, G> {
@SuppressWarnings("unused")
private IWizardStepDescriptor wizardStep;
private IDisplayableAction wrappedCancelAction;
public CancelAction(IWizardStepDescriptor wizardStep,
IDisplayableAction wrappedCancelAction) {
this.wizardStep = wizardStep;
this.wrappedCancelAction = wrappedCancelAction;
}
@Override
public boolean execute(IActionHandler actionHandler,
Map<String, Object> context) {
actionHandler.execute(wrappedCancelAction, context);
return super.execute(actionHandler, context);
}
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return wrappedCancelAction.getDescription();
}
/**
* {@inheritDoc}
*/
@Override
public String getIconImageURL() {
return wrappedCancelAction.getIconImageURL();
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return wrappedCancelAction.getName();
}
}
private class FinishAction extends FrontendAction<E, F, G> {
private IWizardStepDescriptor wizardStep;
private IDisplayableAction wrappedFinishAction;
public FinishAction(IWizardStepDescriptor wizardStep,
IDisplayableAction wrappedFinishAction) {
this.wizardStep = wizardStep;
this.wrappedFinishAction = wrappedFinishAction;
}
@Override
public boolean execute(IActionHandler actionHandler,
Map<String, Object> context) {
if (wizardStep.getOnLeaveAction() == null
|| actionHandler.execute(wizardStep.getOnLeaveAction(), context)) {
setActionParameter(
getViewConnector(context).getConnectorValue(),
context);
actionHandler.execute(wrappedFinishAction, context);
}
return super.execute(actionHandler, context);
}
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return wrappedFinishAction.getDescription();
}
/**
* {@inheritDoc}
*/
@Override
public String getIconImageURL() {
return wrappedFinishAction.getIconImageURL();
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return wrappedFinishAction.getName();
}
}
interface Indexable {
public int getIndex();
}
protected class NextAction
extends FrontendAction<E, F, G>
implements Indexable {
private IValueConnector modelConnector;
private IWizardStepDescriptor wizardStep;
private int index;
/**
*
* @param wizardStep the current step, ie the one liable to call this action
* @param modelConnector
*/
public NextAction(IWizardStepDescriptor wizardStep,
IValueConnector modelConnector,
int index
) {
this.wizardStep = wizardStep;
this.modelConnector = modelConnector;
this.index = index;
}
@Override
public int getIndex() {
return this.index;
}
@Override
public boolean execute(IActionHandler actionHandler,
Map<String, Object> context) {
if (wizardStep.getOnLeaveAction() == null
|| actionHandler.execute(wizardStep.getOnLeaveAction(), context)) {
IWizardStepDescriptor nextWizardStep = wizardStep
.getNextStepDescriptor(context);
displayWizardStep(this, nextWizardStep, modelConnector, actionHandler,
context, StepReuse.ALLOWED);
if (nextWizardStep.getOnEnterAction() != null) {
actionHandler.execute(nextWizardStep.getOnEnterAction(), context);
}
}
return super.execute(actionHandler, context);
}
}
protected class PreviousAction
extends FrontendAction<E, F, G>
implements Indexable {
private IValueConnector modelConnector;
private IWizardStepDescriptor wizardStep;
private int index;
public PreviousAction(
IWizardStepDescriptor wizardStep,
IValueConnector modelConnector,
int index
) {
this.wizardStep = wizardStep;
this.modelConnector = modelConnector;
this.index = index;
}
@Override
public int getIndex() {
return this.index;
}
@Override
public boolean execute(IActionHandler actionHandler,
Map<String, Object> context) {
IWizardStepDescriptor previousWizardStep = wizardStep.getPreviousStepDescriptor(context);
displayWizardStep(this, previousWizardStep, modelConnector, actionHandler, context, StepReuse.ALLOWED);
return super.execute(actionHandler, context);
}
}
}
package org.popsuite.framework.application.frontend.action.wizard;
import java.util.Map;
import org.jspresso.framework.application.frontend.action.wizard.IWizardStepDescriptor;
import org.jspresso.framework.application.frontend.action.wizard.StaticWizardStepDescriptor;
/**
* The descriptor of the first step is used as descriptor for all the wizard's steps.
*
* @param <P> actual type of the collection's parent
* @param <C> actual type of the collection's items
*/
public class SelectionIteratorStepDescriptor<P, C>
extends StaticWizardStepDescriptor
{
/**
* {@inheritDoc}
*/
public IWizardStepDescriptor getNextStepDescriptor(Map<String, Object> context) {
return this;
}
/**
* {@inheritDoc}
*/
public IWizardStepDescriptor getPreviousStepDescriptor(Map<String, Object> context) {
return this;
}
}
