Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am hoping to create a mind-mapping like application and it needs to have a central workspace that will hold the map. Users should be able to drag items (like rectangles, texts, etc.) from a container to the workspace. The important thing is when a user is dragging an element to the workspace, the element should move with the mouse, not just the text.

What I'm looking for is something like the web apps LucidChart, Cacoo, MindMeister, etc. So is this possible to do in Java without too much hassle? And if yes, what is the application design (algorithm)?

I have searched many resources but have only found ways to drag only the text, images or the like. Not the entire element itself. It would be even better if I could make it to drag an entire JButton, so the users can create a map of JButtons.

Sorry if this is not the place to post this (should I post it in StackOverflow or here?).

share|improve this question
    
FreeMind is an excellent floss mind-mapping app written in Java. So, yes it's possible :) Look at their code for inspiration... PS: I'm making this for Linux (Ubuntu). Since you'd be writing this in Java, that's largely irrelevant. –  Yannis Rizos Dec 21 '11 at 13:05
    
@YannisRizos Saw FreeMind. Yes it would be something like that but simpler. I'm looking for an algorithm and the best flow to develop it. And I added that "I'm making this for Linux" part because I thought that I would have to use native Windows libraries or something like that. :) –  Roshnal Dec 21 '11 at 13:10
    
Well answers on application design / workflow shouldn't be around implementation specifics anyway. I think the possibility of someone suggesting a native windows library (within a good answer) is extremely small. If you are looking for implementation specifics, ask that question on StackOverflow and just keep the application design / workflow aspects of it here. Of course feel free to add the ps. back to the question, if you disagree with my edit. –  Yannis Rizos Dec 21 '11 at 13:15
    
@YannisRizos So if I ask the same question on SO, I wouldn't be voted down right? And yeah I agree with you on that native-library thing. –  Roshnal Dec 21 '11 at 13:22
    
Well I can't really predict votes, but generally speaking the SO people prefer to see some code in questions. Typical questions there are of the "I tried this and that, it failed here and there, please help" style, where this and that are usually code samples. –  Yannis Rizos Dec 21 '11 at 13:25

1 Answer 1

up vote 1 down vote accepted

Here is a starting point/idea for the design:

// Your framework probably provides this
class Point {
     private int x, y; // x,y coordinates of top left of View
}


// Your framework probably provides something like this

/** Container class for all other types */
abstract class MindMapView {
    public MindMapView(int width, int height, Point position) {
          // Initialize fields
    }

    /** Top-Left */
    private Point mPosition;

    /** Width, Height */
    private int mWidth, mHeight; // Width and height of view

    /** Implement this to fulfill a request to draw the view on the screen */
    abstract void onDraw();

    /** Implement this to fulfill a request to move the view across the screen */
    abstract void onMove(Point delta);

    /** Implement this to fulfill a request to resize the view */
    abstract void onResize(int width, int height);

    /** 
        Implement this to fulfill a request to drag this view. Can be similar
        to onMove, except you will want to hook the point where the view is
        "dropped", which would be the last point in the drag.

        We'd consider a drag to be a left mouse click, mouse movement, and mouse 
        un-click.
      */
    abstract void onDrag(Point delta);


    /** Called by other classes that desire to draw this View */
    public final void draw() {
        onDraw();
    }

    /** Called by other classes that desire to move this view */
    public final void move(Point delta) {
        onMove(delta);
    }

    /** Called by other classes that desire to resize this view */
    public final void resize() {
        onResize();
    }

    public final void drag(Point delta) {
        onDrag(delta);
    }

    /** Implement this to 
    public Point getPosition() {
       return mPosition;
    }
}

You will hook your framework to funnel the various events into this view, but more than likely, your framework has a similar class ready for you.. Once you have that, you can extend it to make your other elements

Much like MindMapView, except it can contain other MindMapViews

 abstract class MindMapContainer extends MindMapView {


    private ArrayList<MindMapView> mViews;

    public ArrayList<MindMapView> getViews() {
        return mViews;
    }

    public MindMapThought(...) {
        super(...);
    }

    public void addView(MindMapView view) {
        mViews.add(view);
    }

    public void removeView(int index) {
        ...
    }


    // Subclasses must call super() if these are overridden!

    @Override
    protected void onMove(Point delta) {
        for (MindMapView view : mViews) {
            view.move(delta);
        }
    }


    // Do similar for the following
    implement onDraw();

    implement onResize(int width, int height);

    implement onDrag(Point delta);
 }

Once you have the base classes defined, you can LOOP over each sub-view to move it along with the others

public class MindMapThought extends MindMapView {
    /** Implement this to fulfill a request to draw the view on the screen */

    @Override
    protected void onDraw() {
        canvas.draw(...);
    }

    // Do similar for the following

    implement onMove(Point delta);

    implement onResize(int width, int height);

    implement onDrag(Point delta);
}

Finally, you can create something that moves as a group

public class MindMapThoughtContainer extends MindMapViewContainer {
    ...
}


MindMapThought thought1 = new MindMapThought();
MindMapThought thought2 = new MindMapThought();
MindMapThoughtContainer thoughts = new MindMapThoughtContainer();

thoughts.add(thought1);
thoughts.add(thought2);

Point delta = new Point(5,5);

// Move the thoughts container, its' onMove event will iterate its sub-views
// and move them along by the same delta
thoughts.move(delta);

You can have any number of concrete (actual implementations) types as long as they extend MindMapView so that they use the same interface.

As for the specifics of wiring up the design, consult your frameworks documentation.

share|improve this answer
    
That was really helpful! Thanks a lot.. :) Now got a good idea about the model.. –  Roshnal Dec 22 '11 at 15:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.