Results 1 to 5 of 5
Like Tree1Likes
  • 1 Post By pbrockway2

Thread: User-Controlled Tree Edges

  1. #1
    robbie.26 is offline Member
    Join Date
    Jun 2011
    Posts
    19
    Rep Power
    0

    Default User-Controlled Tree Edges

    I've devised a custom tree user interface using Swing and I'm at the point where I want to implement the connection lines or "edges" between nodes.
    As a test, I hard coded the tree's structure, defining the relationships of the nodes, and then on the parent JPanel that houses the nodes I drew the
    lines between the nodes in paintComponent(). This works as I expected but obviously doesn't allow the user to define the tree structure.

    So what I think I need to do is define a class called Connector that subclasses JPanel. This class will draw a line from its top-left corner to its
    bottom-right corner. Each node will need to have a collection of these Connector objects, and then update each Connector's bounds when the Node
    is moved or when the node's child is moved. This Connector class will implement MouseListener and MouseMotionListener so its "loose" end can be
    dragged and then the Connector's bounds will be updated.

    diagram:


    The black arrows would be the Connectors. If the tail/nose of the Connector is dragged and released on top of a node then that end of the Connector
    should be forever "parented" to the new node, even when the new node is moved/resized.

    When a node is clicked it is brought to the "front", meaning all other nodes are now below it in Z order. The Connectors of a selected node should
    also be brought to the front.

    -----------------------

    This approach seems awfully complicated and I'm very eager to hear a different approach and/or
    suggestions for my approach. Thanks.

  2. #2
    robbie.26 is offline Member
    Join Date
    Jun 2011
    Posts
    19
    Rep Power
    0

    Default

    Bump.

    Let me rephrase my question:
    If you were to build a schematic user interface that allowed the user to create, move, and connect nodes, how would you implement the connection lines between the nodes?

  3. #3
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I think I would just draw lines between the node views.

    -----

    Perhaps I'm wrong here - but others will chime in if I'm wrong (and there are *lots* of open source graphing applications to look at).

    I would start with my data structure. Not "hard code" it, but get it working rock solid. For the purposes of this illustration it could be a Graph which has a list of Node instances and methods to add/remove nodes and join/unjoin nodes from each other. (I'm not sure if the graph would have one big list of connetions or if each node would remember its own.) The nodes would have some "payload" of data.

    Then I would start with the GUI. I would want a NodeView which would wrap a Node. The NodeView would have a position (unlike the Node which is just data). And its major behavioural aspect would be that it would paint itself using the position and the "payload" as reported by the Node instance. (A fancy way of saying it would paint the string and the box in your illustration).

    Next a component (or panel) to hold all the NodeView instances. It would just be a list again of NodeView instances. (ArrayList etc are simple, so I start with them. If there were zillions of nodes being represented I might dream up more elaborate ways of storing them based on position so I can easily get at "visible" ones etc. But that would be for later.) Painting is delegated to the node veiws: but - and this is the point I started with - I would have all the node views draw their connections first, then their payloads, that way the lines would be "behind" the nodes.

    Finally I would add mouse listeners to my GraphView component (or container) and detect presses, drags etc. Given a mouse position for such an event I would go through the list of node views and decide which node view/connection line the mouse event occured on. Rectangles are easy, line segments take a little work: but its straight forward and there are library methods to help.

    -----

    In the above description I made the NodeView its own class, but left the connection lines as side effects of the painting behaviour of the Graph containing them. This was only because of the simplicity of these things: you could have a ConnectionView (eg to remember which nodes it was connecting and thereby facilitate responses to mouse clicks).

    A common idiom for gui-users is a little box near the bottom right corner with a cross in it. Clicking on this aqnd then another node is intended to "join" them. I think I might employ such a mechanism for allowing the user to join nodes.
    Fubarable likes this.

  4. #4
    robbie.26 is offline Member
    Join Date
    Jun 2011
    Posts
    19
    Rep Power
    0

    Default

    Hi pbrockway2, I appreciate your help.

    I already have the tree data structure built and running flawlessly. It has an ArrayList of Nodes. Each Node has
    an ArrayList for its parents, and an ArrayList for its children. A Node should handle its own connecting
    operation to other Nodes because each Node will have unique inputs.

    So what you're saying is to add a collection of lines to the Tree class, and in the tree classes'
    paintComponent() iterate through the collection and paint each line? I have two questions regaurding this approach.

    1) How would the lines update when a Node is moved? Because they would somehow need to be associated with a particular Node...
    2) Wouldn't it be inefficient to have to iterate through the collection of lines each time the mouse
    is clicked/dragged/etc?

    Edit:
    Right now the Nodes handle mouse input themselves. If I go with your approach ^ should I have the tree handle all the mouse
    input and have the tree move and select the nodes? Again this would require iterating through a collection each time the mouse is used.
    Last edited by robbie.26; 07-03-2011 at 04:35 AM.

  5. #5
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    1) How would the lines update when a Node is moved? Because they would somehow need to be associated with a particular Node...
    When a node is moved the tree view would be repainted. This would involve first repainting the connections and then the nodes. The visual appearance - as far as the user is concerned - would be that the connecting lines are somehow fixed to the nodes. It's an illusion of course what is really happening is that the connecting lines are just being repainted with their end points being determined by where their nodes happen to be at that moment.

    2) Wouldn't it be inefficient to have to iterate through the collection of lines each time the mouse
    is clicked/dragged/etc?
    Personally I wouldn't worry about efficiency until the thing was performing correctly. At that point I would know if there was a problem that needed to be addressed. And, if so, I could address it in a more precise way: is iterating through all the lines noticably less effecient than X. Where X is some other method I had dreamt up.

    -----

    Right now the Nodes handle mouse input themselves.
    It's up to you, but my instinct was to have both Node (which knew about parents, children and data payload) and NodeView (which was associated with a Node but which also knew about position). My thought was that position, combined with the Node properties, would be enough to handle painting.

    It's another question again whether the NodeView or the tree view handles mouse input. Either have the NodeView do this, ie make it a JComponent that has mouse listeners registered with it which tell the containing tree view to repaint after the relevant changes have been made. Or have the tree view register the mouse listeners (on itself perhaps) in which case it would have to figure out which nodes or connections were involved. Both ways seem doable, perhaps others have a feeling for one rather than the other, or something different again.[*]

    Again I'm not much worried by the need to iterate through the nodes to see if they (or one of their connections) lies at (or near) the location of the mouse event. If it proves a problem then that problem should be addressed. (I think I mentioned originally that more subtle structures than a simple list could greatly improve the speed of "hit detection" should that prove a problem. But their complexity would be pain that shouldn't be endured except for actual gain.)

    * Edit: I think I favour the tree view doing the mouse event processing. That's because the connecting lines don't belong to the "visual space" of any of the NodeViews.
    Last edited by pbrockway2; 07-03-2011 at 07:28 AM.

Similar Threads

  1. Multiple JSPs controlled by one servlet.
    By Mean KaNean in forum JavaServer Pages (JSP) and JSTL
    Replies: 7
    Last Post: 06-07-2011, 02:52 PM
  2. creating nodes and edges in java
    By ankit1801 in forum New To Java
    Replies: 4
    Last Post: 03-19-2011, 07:15 AM
  3. Replies: 1
    Last Post: 11-02-2009, 11:39 PM
  4. Replies: 0
    Last Post: 01-22-2008, 04:31 AM
  5. Rectangle with rounded edges??
    By orchid in forum Java 2D
    Replies: 1
    Last Post: 05-10-2007, 03:31 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •