jaxx.runtime.swing.wizard.WizardOperationModel Maven / Gradle / Ivy
/*
* *##%
* JAXX Runtime
* Copyright (C) 2008 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* ##%*
*/
package jaxx.runtime.swing.wizard;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.SwingWorker.StateValue;
/**
* Un modèle de wizard avec des opérations.
*
* @param le type des étapes.
* @author tony
* @since 1.3
*/
public class WizardOperationModel extends WizardModel {
public static final String OPERATIONS_PROPERTY_NAME = "operations";
public static final String OPERATION_STATE_PROPERTY_NAME = "operationState";
public static final String MODEL_STATE_PROPERTY_NAME = "modelState";
public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted";
/**
* La liste des opérations à effectuer
*/
protected Set operations;
/**
* Pour conserver les états des opérations
*/
protected Map operationStates;
protected Map operationActions;
/**
* L'état générale du modèle
*/
protected WizardOperationState modelState;
/**
* un drapeau pour savoir siune opération a été lancée
*/
protected boolean wasStarted;
@SuppressWarnings("unchecked")
public > WizardOperationModel(Class stepClass, E... steps) {
super(stepClass, steps);
Class k = (Class) stepClass;
this.operationStates = (Map) new EnumMap(k);
this.operations = (Set) EnumSet.noneOf(k);
this.operationActions = (Map) new EnumMap(k);
}
public Set getOperations() {
return operations;
}
public WizardOperationState getModelState() {
return modelState;
}
public boolean isWasStarted() {
return wasStarted;
}
@SuppressWarnings("unchecked")
public E getOperation() {
return getStep() != null && getStep().isOperation() ? getStep() : null;
}
public WizardOperationState getOperationState() {
E operation = getOperation();
return getOperationState(operation);
}
public WizardOperationState getOperationState(E operation) {
return operationStates.get(operation);
}
public WizardOperationAction getOperationAction(E operation) {
WizardOperationAction action = operationActions.get(operation);
if (action == null) {
try {
action = operation.getActionClass().newInstance();
operationActions.put(operation, action);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
return action;
}
public void setOperationState(WizardOperationState operationState) {
E operation = getOperation();
setOperationState(operation, operationState);
}
public void setOperationState(E operation, WizardOperationState operationState) {
WizardOperationState oldValue = getOperationState(operation);
this.operationStates.put(operation, operationState);
fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getSteps().indexOf(operation), oldValue, operationState);
updateModelState(operation, operationState);
validate();
}
public boolean[] getAccessibleSteps() {
boolean[] result = new boolean[getSteps().size()];
int index = getSteps().indexOf(getStep());
if (index != -1) {
for (int i = 0, j = steps.size(); i < j; i++) {
if (i <= index) {
// tous les onglets inferieur ou egal au courant sont accessibles
result[i] = true;
continue;
}
// les onglets au dela de l'onglet sélectionné sont accessibles
// uniquement si l'onglet precedent est accessible, valide et son etat est a SUCCESSED
E previousStep = steps.get(i - 1);
result[i] = modelState == WizardOperationState.SUCCESSED ||
(result[i - 1] &&
validate(previousStep) &&
(!previousStep.isOperation() || getOperationState(previousStep) == WizardOperationState.SUCCESSED));
}
}
//System.out.println("accessibles steps -------- " + java.util.Arrays.toString(result));
return result;
}
@Override
public void start() {
super.start();
updateUniverse();
//setSteps(steps.toArray((E[]) Array.newInstance(stepClass, steps.size())));
// le modèle n'est pas démarré
setModelState(WizardOperationState.PENDING);
}
public void cancel() {
for (E op : operations) {
if (getOperationState(op) == WizardOperationState.PENDING) {
// on annule l'opération à venir
setOperationState(op, WizardOperationState.CANCELED);
}
}
setModelState(WizardOperationState.CANCELED);
if (getStep() != null && getStep().isOperation()) {
WizardOperationAction action = getOperationAction(getStep());
if (action != null) {
if (!action.isCancelled() && !action.isDone() && action.getState() == StateValue.STARTED) {
System.out.println("cancel action " + action);
// on annule l'action
action.cancel(true);
}
}
}
}
public WizardOperationModel addOperation(E operation) {
operations.add(operation);
// mis a jour de l'univers des etapes et operations
updateUniverse();
// validation
validate();
return this;
}
public void removeOperation(E operation) {
operations.remove(operation);
// mis a jour de l'univers des etapes et operations
updateUniverse();
// validation
validate();
}
@Override
public void setSteps(E... steps) {
super.setSteps(steps);
// on force la propagation de la nouvelle liste
firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
updateOperationStates(Arrays.asList(steps));
}
public void updateOperationStates(List steps) {
int index = 0;
for (E e : steps) {
fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e));
}
firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState);
}
public WizardOperationAction reloadOperation(E operation) {
operationActions.remove(operation);
WizardOperationAction newOp = getOperationAction(operation);
return newOp;
}
protected void setModelState(WizardOperationState modelState) {
WizardOperationState oldValue = this.modelState;
this.modelState = modelState;
firePropertyChange(MODEL_STATE_PROPERTY_NAME, oldValue, modelState);
if (!wasStarted) {
if ((oldValue == null || oldValue == WizardOperationState.PENDING) && modelState == WizardOperationState.RUNNING) {
this.wasStarted = true;
firePropertyChange(WAS_STARTED_PROPERTY_NAME, false, true);
}
}
}
protected void updateModelState(E operation, WizardOperationState operationState) {
switch (operationState) {
case RUNNING:
//le modele est occupé
setModelState(WizardOperationState.RUNNING);
break;
case FAILED:
//le modele est en erreur
setModelState(WizardOperationState.FAILED);
break;
case CANCELED:
//le modele devient annulé
setModelState(WizardOperationState.CANCELED);
return;
case PENDING:
//le modele est en attente
setModelState(WizardOperationState.PENDING);
break;
case NEED_FIX:
//le modele est en attente
setModelState(WizardOperationState.PENDING);
break;
case SUCCESSED:
// on regarde si on peut passer le model a l'état success
boolean valid = true;
for (E o : operations) {
if (getOperationState(o) != WizardOperationState.SUCCESSED) {
valid = false;
break;
}
}
if (valid) {
setModelState(WizardOperationState.SUCCESSED);
} else {
setModelState(WizardOperationState.PENDING);
}
break;
}
updateOperationStates(steps);
}
@Override
protected void updateUniverse() {
E[] newSteps = updateStepUniverse();
setSteps(newSteps);
}
protected int getOperationIndex(E operation) {
int index = 0;
for (E o : operations) {
if (operation == o) {
return index;
}
index++;
}
return -1;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy