Lors de la création d'une interface utilisateur graphique dans Swing, je suis toujours confronté à un problème de conception qui met fin au piratage. Je voudrais connaître la bonne pratique à ce sujet.OO Conception avec UndoManager et Listeners sur un composant JComponent
Prenons un exemple simple.
J'ai un composant JComponent sur lequel j'aimerais implémenter des actions annuler/rétablir, et quelques actions qui ajoutent/suppriment d'autres composants. Donc, je voudrais commencer à écrire:
public class MyComponent extends JComponent {
private UndoManager undo = new UndoManager();
public void addComponent(JComponent comp) {
this.add(comp);//Add the component to the view
undo.addEdit(new ComponentAddedEdit(comp));//make this action undoable
fireComponentAdded(comp);//warn the listeners that the action occured
}
}
Puis commence le problème. Dans mon ComponentAddedEdit
je pense à quelque chose comme:
public class ComponentAddedEdit extends AbstractUndoableEdit {
private final JComponent comp;
public ComponentAddedEdit(JComponent comp) {this.comp = comp;}
@Override
public void undo() throws CannotUndoException {
MyComponent.this.removeComponent(comp);
}
@Override
public void redo() throws CannotRedoException {
MyComponent.this.addComponent(comp);
}
}
Bien sûr, cela ne fonctionne pas parce que l'action redo va créer une nouvelle Edit à UndoManager. Je dois donc créer une nouvelle méthode comme ça:
public void addComponentNoUndo() {
this.add(comp);//Add the component to the view
fireComponentAdded(comp);//warn the listeners that the action occured
}
En fin de compte, juste pour l'action « ajouter », je me retrouve avec 3 méthodes avec des noms similaires: add
, addComponent
et addComponentNoUndo
. Si j'ai plus d'actions, plus complexes, cela peut devenir très confus. Alors, comment ferais-tu ça?
Avez-vous pensé à utiliser un modèle memento? –
Je n'ai pas, mais maintenant que j'étudie cette option, je ne vois pas comment il pourrait résoudre le problème. Pourrais-tu me montrer comment tu écrirais le 'undo' avec un souvenir? IMO vous devez toujours être en mesure d'ajouter un composant sans déclencher une nouvelle modification, ce qui signifie que vous avez toujours besoin de la méthode 'addComponentNoUndo'. La seule différence est que cette méthode pourrait devenir privée. – Sharcoux