Author: tchemit Date: 2009-03-16 18:44:15 +0000 (Mon, 16 Mar 2009) New Revision: 1268 Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html Removed: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java Log: wizard framework done Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -29,6 +29,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; +import java.util.NoSuchElementException; import java.util.Properties; import javax.swing.ImageIcon; import javax.swing.JComponent; @@ -413,6 +414,7 @@ public int size() { return tabs.getTabCount(); } + public TabbedPaneIterator<O> reverse() { setReverse(!reverse); return this; @@ -430,9 +432,9 @@ @Override public O next() { if (!hasNext()) { - throw new IllegalStateException("no next objet! for " + this); + throw new NoSuchElementException(); } - Component next = tabs.getComponent(index); + Component next = tabs.getComponentAt(index); O result = get(index, next); index += increment; return result; Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardModel.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -2,17 +2,21 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; -import java.util.List; /** * Un modèle de wizard. * - * @param <E> le type de l'énumération contenant les etapes. * + * <b>Note:</b> le type des étapes doit être uné énumération qui implante + * {@link WizardStep}. + * + * @param <E> le type des étapes. + * * @author tony * @since 1.3 + * @see WizardStep */ -public class WizardModel<E extends Enum<E>> { +public class WizardModel<E extends WizardStep> { public static final String STEPS_PROPERTY_NAME = "steps"; public static final String STEP_PROPERTY_NAME = "step"; @@ -26,7 +30,7 @@ /** * Toutes les étapes à passer */ - protected List<E> steps; + protected java.util.List<E> steps; /** * L'étape courante */ @@ -36,11 +40,20 @@ */ protected boolean validStep; /** + * drapeau lorsque le modele effectue des operations + * de transformation de modele mais que les écouteurs + * ne devraient pas tenir compte des modifications + */ + protected boolean valueAdjusting; + /** * pour propager les changements dans le modèle vers l'ui */ protected PropertyChangeSupport pcs; public WizardModel(Class<E> stepClass, E... steps) { + if (!Enum.class.isAssignableFrom(stepClass)) { + throw new IllegalArgumentException("stepClass must be an Enumeration but was " + stepClass.getName()); + } this.stepClass = stepClass; this.pcs = new PropertyChangeSupport(this); this.steps = new java.util.ArrayList<E>(); @@ -79,7 +92,7 @@ throw new NullPointerException("step can not be null"); } if (!steps.contains(e)) { - throw new IllegalStateException("step " + e + " is not in universe of steps (" + steps + ")"); + throw new IllegalStateException("step " + e.toString() + " is not in universe of steps (" + steps + ")"); } setStep(e); } @@ -98,6 +111,11 @@ } public E getPreviousStep() { + E e = getPreviousStep(step); + return e; + } + + public E getPreviousStep(E step) { int index = getStepIndex(step); if (index < 1) { // si pas de step ou sur premier step @@ -106,6 +124,15 @@ return steps.get(index - 1); } + public E getNextStep(E step) { + int index = getStepIndex(step); + if (index < 1) { + // si pas de step ou sur premier step + return null; + } + return steps.get(index - 1); + } + public E getNextStep() { int index = getStepIndex(step); if (index == -1 || index == steps.size() - 1) { @@ -115,10 +142,14 @@ return steps.get(index + 1); } - public List<E> getSteps() { + public java.util.List<E> getSteps() { return steps; } + public boolean isValueAdjusting() { + return valueAdjusting; + } + /** * Change l'univers des etapes. * @@ -127,13 +158,17 @@ * @param steps le nouvel univers des etapes */ public void setSteps(E... steps) { - List<E> oldValue = this.steps; + java.util.List<E> oldValue = this.steps; this.steps = java.util.Collections.unmodifiableList(java.util.Arrays.asList(steps)); firePropertyChange(STEPS_PROPERTY_NAME, oldValue, this.steps); // la propriete nextStep peut avoir changee firePropertyChange(NEXT_STEP_PROPERTY_NAME, null, getNextStep()); } + public void setValueAdjusting(boolean valueAdjusting) { + this.valueAdjusting = valueAdjusting; + } + public boolean validate(E s) { return step != null; } @@ -194,6 +229,10 @@ pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue); } + protected E[] updateStepUniverse() { + return null; + } + protected void updateUniverse() { } } Deleted: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperation.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -1,20 +0,0 @@ -package jaxx.runtime.swing.wizard; - -/** - * - * @param <Action> - * @author tony - * @since 1.3 - */ -public interface WizardOperation<Action extends WizardOperationAction> { - - String name(); - - int ordinal(); - - String getLabel(); - - String getDescription(); - - public Action newAction(); -} Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationAction.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -6,27 +6,31 @@ import org.apache.commons.logging.LogFactory; /** + * La classe de base a implanter pour definir l'action d'une operation + * dans un wizard. * * @author tony * @param <E> le type d'étapes - * @param <O> le type d'opérations * @param <M> le type de modèle * @since 1.3 */ -public abstract class WizardOperationAction<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>> extends SwingWorker<WizardOperationState, String> { +public abstract class WizardOperationAction<E extends WizardOperationStep, M extends WizardOperationModel<E>> extends SwingWorker<WizardOperationState, String> { /** to use log facility, just put in your code: log.info(\"...\"); */ private static final Log log = LogFactory.getLog(WizardOperationAction.class); - O operation; + E operation; WizardOperationState operationState; Exception error; - public WizardOperationAction(O operation) { + public WizardOperationAction(E operation) { super(); + if (!operation.isOperation()) { + throw new IllegalArgumentException("the step " + operation + " has no operation defined"); + } this.operation = operation; } - public O getOperation() { + public E getOperation() { return operation; } Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationActionThread.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -2,7 +2,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.util.Date; import javax.swing.SwingWorker.StateValue; import jaxx.runtime.JAXXContext; @@ -18,14 +17,13 @@ * Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link #setWaiting(boolean)} * * @param <E> le type des etapes - * @param <O> le type des operations * @param <M> le type de modele * @param <A> le type d'action d'operation * * @author tony * @since 1.3 */ -public abstract class WizardOperationActionThread<E extends Enum<E>, O extends Enum<O>, M extends WizardOperationModel<E, O>, A extends WizardOperationAction<E, O, M>> extends Thread implements PropertyChangeListener { +public abstract class WizardOperationActionThread<E extends WizardOperationStep, M extends WizardOperationModel<E>, A extends WizardOperationAction<E, M>> extends Thread implements PropertyChangeListener { /** to use log facility, just put in your code: log.info(\"...\"); */ private static final Log log = LogFactory.getLog(WizardOperationActionThread.class); @@ -33,8 +31,6 @@ * l'état du thread si annulé */ private boolean canceled; - /** suport of modification propagation */ - protected PropertyChangeSupport pcs; protected Class<M> modelClass; protected A currentAction; /** @@ -50,7 +46,6 @@ public WizardOperationActionThread(Class<M> modelClass) throws IllegalArgumentException { super(WizardOperationActionThread.class.getSimpleName() + " " + new Date()); this.modelClass = modelClass; - this.pcs = new PropertyChangeSupport(this); } public void cancel() { @@ -66,20 +61,25 @@ setWaiting(false); } - public void launchOperation(A action) { + @SuppressWarnings("unchecked") + public void launchOperation(E operation) { if (currentAction != null) { // on ne peut traiter qu'une seule opération à la fois throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done"); } - currentAction = action; + try { + currentAction = (A) operation.getActionClass().newInstance(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } // on libere le thread pour qu'il execute l'opération setWaiting(false); } @Override public void propertyChange(PropertyChangeEvent evt) { - log.info(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">"); + log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">"); if ("state".equals(evt.getPropertyName())) { //@SuppressWarnings("unchecked") //A action = (A) evt.getSource(); @@ -166,39 +166,6 @@ log.trace(this); } - // PropertyChanged support - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - pcs.removePropertyChangeListener(propertyName, listener); - } - - public synchronized boolean hasListeners(String propertyName) { - return pcs.hasListeners(propertyName); - } - - public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { - return pcs.getPropertyChangeListeners(propertyName); - } - - public synchronized PropertyChangeListener[] getPropertyChangeListeners() { - return pcs.getPropertyChangeListeners(); - } - - protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - pcs.firePropertyChange(propertyName, oldValue, newValue); - } - protected void setWaiting(boolean waiting) { if (waiting && !canceled) { Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationModel.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -2,16 +2,17 @@ import java.util.EnumMap; import java.util.EnumSet; +import java.util.Map; +import java.util.Set; /** * Un modèle de wizard avec des opérations. * * @param <E> le type des étapes. - * @param <O> le type des opérations. * @author tony * @since 1.3 */ -public class WizardOperationModel<E extends Enum<E>, O extends Enum<O>> extends WizardModel<E> { +public class WizardOperationModel<E extends WizardOperationStep> extends WizardModel<E> { public static final String OPERATIONS_PROPERTY_NAME = "operations"; public static final String OPERATION_STATE_PROPERTY_NAME = "operationState"; @@ -20,15 +21,15 @@ /** * le type d'une opération */ - protected Class<O> operationClass; +// protected Class<O> operationClass; /** * La liste des opérations à effectuer */ - protected EnumSet<O> operations; + protected Set<E> operations; /** * Pour conserver les états des opérations */ - protected EnumMap<O, WizardOperationState> operationStates; + protected Map<E, WizardOperationState> operationStates; /** * L'état générale du modèle */ @@ -38,16 +39,15 @@ */ protected boolean wasStarted; - public WizardOperationModel(Class<E> stepClass, Class<O> operationClass, E... steps) { + @SuppressWarnings("unchecked") + public <T extends Enum<T>> WizardOperationModel(Class<E> stepClass, E... steps) { super(stepClass, steps); - this.operationClass = operationClass; - this.operationStates = new EnumMap<O, WizardOperationState>(operationClass); + Class<T> k = (Class) stepClass; + this.operationStates = (Map) new EnumMap(k); + this.operations = (Set<E>) EnumSet.noneOf(k); } - public EnumSet<O> getOperations() { - if (operations == null) { - operations = EnumSet.noneOf(operationClass); - } + public Set<E> getOperations() { return operations; } @@ -60,43 +60,68 @@ } @SuppressWarnings("unchecked") - public O getOperation() { - return ((WizardOperationStep<O>) getStep()).getOperation(); + public E getOperation() { + return getStep() != null && getStep().isOperation() ? getStep() : null; } public WizardOperationState getOperationState() { - O operation = getOperation(); + E operation = getOperation(); return getOperationState(operation); } - public WizardOperationState getOperationState(O operation) { + public WizardOperationState getOperationState(E operation) { return operationStates.get(operation); } public void setOperationState(WizardOperationState operationState) { - O operation = getOperation(); + E operation = getOperation(); setOperationState(operation, operationState); } - public void setOperationState(O operation, WizardOperationState operationState) { + public void setOperationState(E operation, WizardOperationState operationState) { WizardOperationState oldValue = getOperationState(operation); this.operationStates.put(operation, operationState); - firePropertyChange(OPERATION_STATE_PROPERTY_NAME, oldValue, operationState); - //fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getOperationIndex(operation), oldValue, operationStates); + 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); - firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations); } public void cancel() { - for (O op : operations) { + for (E op : operations) { if (getOperationState(op) == WizardOperationState.PENDING) { // on annule l'opération à venir setOperationState(op, WizardOperationState.CANCELED); @@ -104,10 +129,8 @@ } } - public WizardOperationModel<E, O> addOperation(O operation) { - getOperations().add(operation); - // on force la propagation de la nouvelle liste - firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations); + public WizardOperationModel<E> addOperation(E operation) { + operations.add(operation); // mis a jour de l'univers des etapes et operations updateUniverse(); // validation @@ -115,16 +138,27 @@ return this; } - public void removeOperation(O operation) { - getOperations().remove(operation); - // on force la propagation de la nouvelle liste - firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations); + 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); + int index = 0; + for (E e : steps) { + fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e)); + } + firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState); + } + protected void setModelState(WizardOperationState modelState) { WizardOperationState oldValue = this.modelState; this.modelState = modelState; @@ -137,33 +171,33 @@ } } - protected void updateModelState(O operation, WizardOperationState operationState) { + protected void updateModelState(E operation, WizardOperationState operationState) { switch (operationState) { case RUNNING: - //le model est occupé + //le modele est occupé setModelState(WizardOperationState.RUNNING); break; case FAILED: - //le model est en attente - setModelState(WizardOperationState.PENDING); + //le modele est en erreur + setModelState(WizardOperationState.FAILED); break; case CANCELED: - //le model devient annulé + //le modele devient annulé setModelState(WizardOperationState.CANCELED); break; case PENDING: - //le model est en attente + //le modele est en attente setModelState(WizardOperationState.PENDING); break; case NEED_FIX: - //le model est en attente + //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 (O o : operations) { + for (E o : operations) { if (getOperationState(o) != WizardOperationState.SUCCESSED) { valid = false; break; @@ -178,9 +212,15 @@ } } - protected int getOperationIndex(O operation) { + @Override + protected void updateUniverse() { + E[] newSteps = updateStepUniverse(); + setSteps(newSteps); + } + + protected int getOperationIndex(E operation) { int index = 0; - for (O o : operations) { + for (E o : operations) { if (operation == o) { return index; } Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardOperationStep.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -2,19 +2,33 @@ /** * - * @param <Operation> + * Le contrat a implanter pour une etapes dans le modèle de wizard avec + * opérations. + * * @author tony * @since 1.3 */ -public interface WizardOperationStep<Operation extends Enum<Operation>> { +public interface WizardOperationStep extends WizardStep { - String name(); + /** + * @return le label de l'opération + */ + String getOperationLabel(); - int ordinal(); + /** + * @return la description de l'opération + */ + String getOperationDescription(); - String getLabel(); + /** + * @return le type de l'action associée à l'étape ou <code>null</code> si + * l'étape n'a pas d'opération associée. + */ + Class<? extends WizardOperationAction> getActionClass(); - String getDescription(); - - Operation getOperation(); + /** + * @return <code>true</code> si l'étape a une opération associée, + * <code>false</code> sinon. + */ + boolean isOperation(); } Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java (rev 0) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStep.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -0,0 +1,20 @@ +package jaxx.runtime.swing.wizard; + +import java.io.Serializable; + +/** + * le contrat d'une étape d'un wizard. + * + * @author tony + * @since 1.3 + */ +public interface WizardStep extends Serializable { + + String name(); + + int ordinal(); + + String getLabel(); + + String getDescription(); +} Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java (rev 0) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardStepUI.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -0,0 +1,14 @@ +package jaxx.runtime.swing.wizard; + +/** + * Le contrat d'une ui d'étape. + * + * @param <E> le type d'étape + * @param <M> le type de modèle + * @author tony + * @since 1.3 + */ +public interface WizardStepUI<E extends WizardStep, M extends WizardModel<E>> { + + E getStep(); +} Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUI.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -12,13 +12,27 @@ * @author tony * @since 1.3 */ -public interface WizardUI<E extends Enum<E>, M extends WizardModel<E>> { +public interface WizardUI<E extends WizardStep, M extends WizardModel<E>> { - public E getSelectedStep(); - M getModel(); + E getSelectedStep(); + + WizardStepUI<E, M> getSelectedStepUI(); + + WizardStepUI<E, M> getStepUI(E step); + + WizardStepUI<E, M> getStepUI(int stepIndex); + void start(); JTabbedPane getTabs(); + + void onStepsChanged(E[] steps); + + void onStepChanged(E newStep); + + void onModelStateChanged(WizardOperationState newState); + + void onOperationStateChanged(E step,WizardOperationState newState) ; } Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-15 11:23:33 UTC (rev 1267) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUILancher.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -8,7 +8,7 @@ /** * - * Une classe pour lancer une ui avec wizard. + * Une classe pour lancer une ui de wizard. * * @param <E> le type des etapes * @param <M> le type de modele @@ -16,11 +16,45 @@ * @author tony * @since 1.3 */ -public abstract class WizardUILancher<E extends Enum<E>, M extends WizardModel<E>, UI extends WizardUI<E, M>> { +public abstract class WizardUILancher<E extends WizardStep, M extends WizardModel<E>, UI extends WizardUI<E, M>> { protected UI ui; @SuppressWarnings("unchecked") + public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, M model) { + super(); + try { + // instanciate ui parent context + JAXXInitialContext uiContext = new JAXXInitialContext(); + uiContext.add(mainUI == null ? context : mainUI); + // parent context model + uiContext.add(model); + // apply action + uiContext.add("apply", new Runnable() { + + @Override + public void run() { + doAction(ui); + } + }); + // cancel action + uiContext.add("cancel", new Runnable() { + + @Override + public void run() { + doCancel(ui); + } + }); + + // instanciate ui + ui = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{JFrame.class, JAXXContext.class}); + + } catch (Exception ex) { + throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex); + } + } + + @SuppressWarnings("unchecked") public WizardUILancher(JAXXContext context, JFrame mainUI, Class<UI> uiClass, Class<M> modelClass) { super(); try { @@ -64,7 +98,7 @@ } public void dispose() { - ui = null; + // par defaut, on ne fait rien } public <T> T getContextValue(Class<T> clazz, String name) { Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java (rev 0) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/WizardUtil.java 2009-03-16 18:44:15 UTC (rev 1268) @@ -0,0 +1,93 @@ +package jaxx.runtime.swing.wizard; + +import java.beans.IndexedPropertyChangeEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Array; +import org.apache.commons.logging.Log; + +/** + * Classe de méthodes utiles sur les wizard. + * + * @author tony + * @since 1.3 + */ +public class WizardUtil { + + protected WizardUtil() { + } + + public static boolean acceptStates(WizardOperationState state, WizardOperationState... accepted) { + for (WizardOperationState s : accepted) { + if (s == state) { + return true; + } + } + return false; + } + + public static boolean rejectStates(WizardOperationState state, WizardOperationState... rejected) { + for (WizardOperationState s : rejected) { + if (s == state) { + return false; + } + } + return true; + } + + public static void addDebugLogListener(final Log log, WizardModel model) { + if (log.isDebugEnabled()) { + model.addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + log.debug(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">"); + } + }); + } + } + + public static void addTraceLogListener(final Log log,WizardModel model) { + if (log.isTraceEnabled()) { + model.addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">"); + } + }); + } + } + + public static <E extends WizardStep, M extends WizardModel<E>> void installWizardUIListeners(final WizardUI<E, M> ui) { + ui.getModel().addPropertyChangeListener(new PropertyChangeListener() { + + @Override + @SuppressWarnings("unchecked") + public void propertyChange(PropertyChangeEvent evt) { + String propertyName = evt.getPropertyName(); + if (WizardModel.STEPS_PROPERTY_NAME.equals(propertyName)) { + java.util.List<E> steps = (java.util.List<E>) evt.getNewValue(); + ui.onStepsChanged(steps.toArray((E[]) Array.newInstance(ui.getModel().stepClass, steps.size()))); + return; + } + if (WizardModel.STEP_PROPERTY_NAME.equals(propertyName)) { + ui.onStepChanged((E) evt.getNewValue()); + return; + } + if (WizardOperationModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) { + //TODO should be unicast : only for good stepUI ? + ui.onModelStateChanged((WizardOperationState) evt.getNewValue()); + return; + } + if (WizardOperationModel.OPERATION_STATE_PROPERTY_NAME.equals(propertyName)) { + IndexedPropertyChangeEvent e = (IndexedPropertyChangeEvent) evt; + int stepIndex = e.getIndex(); + E step = ui.getModel().getSteps().get(stepIndex); + ui.onOperationStateChanged(step, (WizardOperationState) evt.getNewValue()); + return; + } + } + }); + } +} Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html =================================================================== --- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html (rev 0) +++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/wizard/package.html 2009-03-16 18:44:15 UTC (rev 1268) @@ -0,0 +1,9 @@ +<html> + <body> + <h1>JAXX - Wizard framework</h1> + + This package contains all the classes of the wizard framework. + + TODO + </body> +</html> \ No newline at end of file