Gef faq 5: Automatic Layout

Source: Internet
Author: User

With the Automatic Layout function, we can display files that do not contain graphical information in a graphical manner. A typical example is to reverse engineer a set of Java interfaces as a class diagram, the coordinates of each element in the graph must be automatically generated. The directedgraphlayout class is provided in GEF to implement the Automatic Layout function. The following describes howProgram.

The visit () method provided by directedgraphlayout accepts an org. Eclipse. draw2d. graph. directedgraph instance, which traverses all nodes and edges of the directed graph and follows its ownAlgorithmCalculate the new location after each node layout. Therefore, the elements on the canvas are divided into two steps: 1. Construct a directed graph; 2. Apply the layout information to the elements.

Based on gefpractice, an automatic layout button is added to the main toolbar. When you press it, the image in the editor is automatically laid out, and the previous layout is restored when you press it again. To complete step 1, we need to add the following two methods in diagrampart:

/**
* Convert an element (nodepart) to a node to a directed graph.
* @ Param Graph
* @ Param Map
  */
Public   Void Contributenodestograph (directedgraph graph, map ){
For ( Int I =   0 ; I < Getchildren (). Size (); I ++ ){
Nodepart Node = (Nodepart) getchildren (). Get (I );
Org. Eclipse. draw2d. graph. node n =   New Org. Eclipse. draw2d. graph. node (node );
N. Width = Node. getfigure (). getpreferredsize (). width;
N. Height = Node. getfigure (). getpreferredsize (). height;
N. setpadding ( New Insets ( 10 , 8 , 10 , 12 ));
Map. Put (node, N );
Graph. nodes. Add (N );
}
}

/**
* Converts a connection part to an edge and adds it to a directed graph.
* @ Param Graph
* @ Param Map
  */
Public   Void Contributeedgestograph (directedgraph graph, map ){
For ( Int I =   0 ; I < Getchildren (). Size (); I ++ ){
Nodepart Node = (Nodepart) children. Get (I );
List outgoing = Node. getsourceconnections ();
For ( Int J =   0 ; J < Outgoing. Size (); j ++ ){
Connectionpart Conn = (Connectionpart) Outgoing. Get (j );
Node Source = (Node) map. Get (conn. getsource ());
Node target = (Node) map. Get (conn. gettarget ());
Edge e =   New Edge (Conn, source, target );
E. Weight =   2 ;
Graph. edges. Add (E );
Map. Put (Conn, e );
}
}
}

To implement step 2, add the following method in diagrampart:

/**
* Use the node location information in the digraph after the layout to reposition the elements on the canvas.
* @ Param Graph
* @ Param Map
  */
Protected   Void Applygraphresults (directedgraph graph, map ){
For ( Int I =   0 ; I < Getchildren (). Size (); I ++ ){
Nodepart Node = (Nodepart) getchildren (). Get (I );
Node n = (Node) map. Get (node );
Node. getfigure (). setbounds ( New Rectangle (N. X, N. Y, N. Width, N. Height ));
}
}

To minimizeCodeNote: The above method simply moves the image without changing the node attribute value in the model. In most cases, it is more appropriate to use a compoundcommand to modify the model, in this way, you can not only cancel the Automatic Layout operation (UNDO), but also view the format before closing the file when you re-open the file. Note that directedgraphlayout does not guarantee that the results of each layout are identical.

Because layoutmanager is used in draw2d to manage the layout, and directedgraphlayout is only a packaging of the layout algorithm, we need to create a layout class. Graphlayoutmanager calls the methods we have added above to generate a directed graph (the partstonodes variable maintains the ing between the editor elements and the directed graph elements), and uses directedgraphlayout to layout the directed graph, then, apply the result to the element in the editor. As follows:

Class Graphlayoutmanager Extends Abstractlayout {

PrivateDiagrampart digoal;

Graphlayoutmanager (diagrampart dimo ){
This. Digoal=Digoal;
}

Protected Dimension calculatepreferredsize (ifigure container, Int Whint, Int Hhint ){
Container. Validate ();
List children = Container. getchildren ();
Rectangle result =   New Rectangle (). setlocation (container. getclientarea (). getlocation ());
For ( Int I =   0 ; I < Children. Size (); I ++ )
Result. Union (ifigure) children. Get (I). getbounds ());
Result. Resize (container. getinsets (). getwidth (), container. getinsets (). getheight ());
Return Result. getsize ();
}

Public   Void Layout (ifigure container ){
Directedgraph =   New Directedgraph ();
Map partstonodes =   New Hashmap ();
Digoal. contributenodestograph (graph, partstonodes );
Digoal. contributeedgestograph (graph, partstonodes );
New Directedgraphlayout (). Visit (graph );
Digoal. applygraphresults (graph, partstonodes );
}

}

When you press the Automatic Layout button, you only need to set the layout manager of the graph corresponding to diagrampart to graphlayoutmanager to achieve automatic layout.


Results of Automatic Layout

Click here to download the project. This project is modified from gefpractice in the GEF application instance, and the extension of the target file is changed to. gefpracticeal. Note the following points:

1. directedgraphlayout can only layout connected Directed Graphs. Otherwise, an exception "graph is not fully connected" will occur. Refer to eclipse.org.ArticleNodejoiningdirectedgraphlayout used in building a database schema dimo-editor can solve this problem;

2. If you want to automatically layout Directed Graphs with nested relationships, use subgraph and compounddirectedgraphlayout;

3. This version of gefpractice does not process the connection line after automatic layout, so the connection line may pass through the element, you can refer to the flow example provided by GEF to solve this problem and the previous problem.

Update (): If digoal is placed in scrollpane, modify the applygraphresults () method and add the container as the parameter so that the entire digoal can be correctly rolled.

Protected   Void Applygraphresults (directedgraph graph, map, ifigure container ){
For (Iterator =   This . Nodeparts. iterator (); iterator. hasnext ();){
Nodepart Element = (Nodepart) iterator. Next ();
Node n = (Node) map. Get (element );
Rectangle containerbounds = Container. getbounds ();
Rectangle elementbounds = New Rectangle (N. X, N. Y, N. Width, N. Height );
Element. getfigure (). setbounds (elementbounds. Translate (containerbounds. getlocation ()));
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.