Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 68167
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T19:22:27+00:00 2026-05-10T19:22:27+00:00

I’m working on a small UML editor project, in Java, that I started a

  • 0

I’m working on a small UML editor project, in Java, that I started a couple of months ago. After a few weeks, I got a working copy for a UML class diagram editor.

But now, I’m redesigning it completely to support other types of diagrams, such a sequence, state, class, etc. This is done by implementing a graph construction framework (I’m greatly inspired by Cay Horstmann work on the subject with the Violet UML editor).

Redesign was going smoothly until one of my friends told me that I forgot to add a Do/Undo functionnality to the project, which, in my opinion, is vital.

Remembering object oriented design courses, I immediately thought of Memento and Command pattern.

Here’s the deal. I have a abstract class, AbstractDiagram, that contains two ArrayLists : one for storing nodes (called Elements in my project) and the other for storing Edges (called Links in my projects). The diagram will probably keep a stack of commands that can be Undoed/Redoed. Pretty standard.

How can I execute these commands in a efficient way? Say, for example, that I want to move a node (the node will be an interface type named INode, and there will be concrete nodes derived from it (ClassNode, InterfaceNode, NoteNode, etc.)).

The position information is held as an attribute in the node, so by modying that attribute in the node itself, the state is changed. When the display will be refreshed, the node will have moved. This is the Memento part of the pattern (I think), with the difference that the object is the state itself.

Moreover, if I keep a clone of the original node (before it moved), I can get back to its old version. The same technique applies for the information contained in the node (the class or interface name, the text for a note node, the attributes name, and so on).

The thing is, how do I replace, in the diagram, the node with its clone upon undo/redo operation? If I clone the original object that is referenced by the diagram (being in the node list), the clone isn’t reference in the diagram, and the only thing that points to is the Command itself! Shoud I include mechanisms in the diagram for finding a node according to an ID (for example) so I can replace, in the diagram, the node by its clone (and vice-versa) ? Is it up to the Memento and Command patterns to do that ? What about links? They should be movable too but I don’t want to create a command just for links (and one just for nodes), and I should be able to modify the right list (nodes or links) according to the type of the object the command is referring to.

How would you proceed? In short, I am having trouble representing the state of an object in a command/memento pattern so that it can be efficiently recovered and the original object restored in the diagram list, and depending on the object type (node or link).

Thanks a lot!

Guillaume.

P.S.: if I’m not clear, tell me and I will clarify my message (as always!).

Edit

Here’s my actual solution, that I started implementing before posting this question.

First, I have an AbstractCommand class defined as follow :

public abstract class AbstractCommand {     public boolean blnComplete;      public void setComplete(boolean complete) {         this.blnComplete = complete;     }      public boolean isComplete() {         return this.blnComplete;     }      public abstract void execute();     public abstract void unexecute(); } 

Then, each type of command is implemented using a concrete derivation of AbstractCommand.

So I have a command to move an object :

public class MoveCommand extends AbstractCommand {     Moveable movingObject;     Point2D startPos;     Point2D endPos;      public MoveCommand(Point2D start) {         this.startPos = start;     }      public void execute() {         if(this.movingObject != null && this.endPos != null)             this.movingObject.moveTo(this.endPos);     }      public void unexecute() {         if(this.movingObject != null && this.startPos != null)             this.movingObject.moveTo(this.startPos);     }      public void setStart(Point2D start) {         this.startPos = start;     }      public void setEnd(Point2D end) {         this.endPos = end;     } } 

I also have a MoveRemoveCommand (to… move or remove an object/node). If I use the ID of instanceof method, I don’t have to pass the diagram to the actual node or link so that it can remove itself from the diagram (which is a bad idea I think).

AbstractDiagram diagram; Addable obj; AddRemoveType type;

@SuppressWarnings('unused') private AddRemoveCommand() {}  public AddRemoveCommand(AbstractDiagram diagram, Addable obj, AddRemoveType type) {     this.diagram = diagram;     this.obj = obj;     this.type = type; }  public void execute() {     if(obj != null && diagram != null) {         switch(type) {             case ADD:                 this.obj.addToDiagram(diagram);                 break;             case REMOVE:                 this.obj.removeFromDiagram(diagram);                 break;         }     } }  public void unexecute() {     if(obj != null && diagram != null) {         switch(type) {             case ADD:                 this.obj.removeFromDiagram(diagram);                 break;             case REMOVE:                 this.obj.addToDiagram(diagram);                 break;         }     } } 

Finally, I have a ModificationCommand which is used to modify the info of a node or link (class name, etc.). This may be merged in the future with the MoveCommand. This class is empty for now. I will probably do the ID thing with a mechanism to determine if the modified object is a node or an edge (via instanceof or a special denotion in the ID).

Is this is a good solution?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T19:22:27+00:00Added an answer on May 10, 2026 at 7:22 pm

    I think you just need to decompose your problem into smaller ones.

    First problem: Q: How to represent the steps in your app with the memento/command pattern? First off, I have no idea exactly how your app works but hopefully you will see where I am going with this. Say I want to place a ClassNode on the diagram that with the following properties

    { width:100, height:50, position:(10,25), content:'Am I certain?', edge-connections:null} 

    That would be wrapped up as a command object. Say that goes to a DiagramController. Then the diagram controller’s responsibility can be to record that command (push onto a stack would be my bet) and pass the command to a DiagramBuilder for example. The DiagramBuilder would actually be responsible for updating the display.

    DiagramController {   public DiagramController(diagramBuilder:DiagramBuilder)   {     this._diagramBuilder = diagramBuilder;     this._commandStack = new Stack();   }    public void Add(node:ConditionalNode)   {     this._commandStack.push(node);     this._diagramBuilder.Draw(node);   }    public void Undo()   {     var node = this._commandStack.pop();     this._diagramBuilderUndraw(node);   } } 

    Some thing like that should do it and of course there will be plenty of details to sort out. By the way, the more properties your nodes have the more detailed Undraw is going to have to be.

    Using an id to link the command in your stack to the element drawn might be a good idea. That might look like this:

    DiagramController {   public DiagramController(diagramBuilder:DiagramBuilder)   {     this._diagramBuilder = diagramBuilder;     this._commandStack = new Stack();   }    public void Add(node:ConditionalNode)   {     string graphicalRefId = this._diagramBuilder.Draw(node);     var nodePair = new KeyValuePair<string, ConditionalNode> (graphicalRefId, node);     this._commandStack.push(nodePair);   }    public void Undo()   {     var nodePair = this._commandStack.pop();     this._diagramBuilderUndraw(nodePair.Key);   } }  

    At this point you don’t absolutely have to have the object since you have the ID but it will be helpful should you decide to also implement redo functionality. A good way to generate the id for your nodes would be to implement a hashcode method for them except for the fact that you wouldn’t be guaranteed not to duplicate your nodes in such a way that would cause the hash code to be identical.

    The next part of the problem is within your DiagramBuilder because you’re trying to figure out how the heck to deal with these commands. For that all I can say is to really just ensure you can create an inverse action for each type of component you can add. To handle the delinking you can look at the edge-connection property (links in your code I think) and notify each of the edge-connections that they are to disconnect from the specific node. I would assume that on disconnection they could redraw themselves appropriately.

    To kinda summarize, I would recommend not keeping a reference to your nodes in the stack but instead just a kind of token that represents a given node’s state at that point. This will allow you to represent the same node in your undo stack at multiple places without it referring to the same object.

    Post if you’ve got Q’s. This is a complex issue.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 106k
  • Answers 106k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer = compares numbers. eq? tests if the parameters represent the… May 11, 2026 at 8:58 pm
  • Editorial Team
    Editorial Team added an answer put a .htaccess file in your directory and deny access… May 11, 2026 at 8:58 pm
  • Editorial Team
    Editorial Team added an answer What you're looking for is an object-relational mapper (ORM). Django… May 11, 2026 at 8:58 pm

Related Questions

I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I am currently running into a problem where an element is coming back from
Seemingly simple, but I cannot find anything relevant on the web. What is the
Configuring TinyMCE to allow for tags, based on a customer requirement. My config is
Is it possible to replace javascript w/ HTML if JavaScript is not enabled on

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.