Show last authors
author | version | line-number | content |
---|---|---|---|
1 | This exercise will introduce the usage of the Eclipse Plugin Development Environment for developing new layout algorithms to be used in Eclipse diagram editors. Replace each <login> by your own login name (e.g. msp), and each <Login> by your login name with capitalized first letter (e.g. Msp). For any questions contact msp. | ||
2 | |||
3 | 1. [[Install and set up Eclipse>>url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/wiki/Eclipse||style="" shape="rect" class="wiki"]] | ||
4 | 1. [[Check out>>url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/wiki/Subversion||style="" shape="rect" class="wiki"]] the following KIELER plugins:\\ | ||
5 | 1*. de.cau.cs.kieler.core | ||
6 | 1*. de.cau.cs.kieler.core.kgraph | ||
7 | 1*. de.cau.cs.kieler.core.kgraph.edit | ||
8 | 1*. de.cau.cs.kieler.core.ui | ||
9 | 1*. de.cau.cs.kieler.keg | ||
10 | 1*. de.cau.cs.kieler.keg.diagram | ||
11 | 1*. de.cau.cs.kieler.kiml.layout | ||
12 | 1*. de.cau.cs.kieler.kiml.ui | ||
13 | 1*. de.cau.cs.kieler.kiml.viewer | ||
14 | 1*. de.cau.cs.kieler.klay.layered | ||
15 | 1. Create a new plugin\\ | ||
16 | 11. //File -> New -> Other... -> Plug-in Development -> Plug-in Project// | ||
17 | 11. Project name: de.cau.cs.rtprak.<login>.exercise1 | ||
18 | 11. //Next// -> set version to //0.1.0.qualifier//, provider to //Christian-Albrechts-Universität zu Kiel//, and execution environment to //J2SE-1.5// (do this for all plugins that you create!) | ||
19 | 11. The checkboxes in the //Options// group can be deactivated -> //Finish// | ||
20 | 1. [[Check in>>url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/wiki/Subversion||style="" shape="rect" class="wiki"]] the new plugin project into [[https:~~/~~/rtsys.informatik.uni-kiel.de/svn/teaching/prak/10ss-layout/exercises/>>url:https://rtsys.informatik.uni-kiel.de/svn/teaching/prak/10ss-layout/exercises/||shape="rect"]]<login>/ | ||
21 | 1. Activate Checkstyle: right-click the project -> //Properties -> Checkstyle -> Checkstyle active for this project// | ||
22 | 1. Open the file META-INF/MANIFEST.MF -> //Dependencies// tab\\ | ||
23 | 1*. Add the plugins de.cau.cs.kieler.core and de.cau.cs.kieler.kiml.layout to the list of dependencies, then save the file | ||
24 | 1. Create a //layout provider// class with the //New -> Class// wizard\\ | ||
25 | 1*. Package: de.cau.cs.rtprak.<login>.exercise1 | ||
26 | 1*. Name: <Login>LayoutProvider | ||
27 | 1*. Superclass: de.cau.cs.kieler.kiml.AbstractLayoutProvider | ||
28 | 1. ((( | ||
29 | Implement the [[(% class="icon" %) (%%)layout provider>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/kiml/layout/AbstractLayoutProvider.html||style="" shape="rect" class="ext-link"]] class | ||
30 | 1. You should now see a checkstyle warning for the doLayout method\\ | ||
31 | 1*. Add the keyword final to each method argument to eliminate the warning | ||
32 | 1. Add the following constant to the class:(% class="code" %) | ||
33 | ((( | ||
34 | (% class="cm" style="color: rgb(153,153,136);" %)/~*~* default value for spacing between nodes. */(% class="kd" %)privatestaticfinal(% class="kt" style="color: rgb(68,85,136);" %)float(% class="o" %)=(% class="mf" style="color: rgb(0,153,153);" %)15.0f(% class="o" %); | ||
35 | |||
36 | {{{ | ||
37 | DEFAULT_SPACING | ||
38 | }}} | ||
39 | ))) | ||
40 | 1. Write the following lines at the beginning of the doLayout method (see [[(% class="icon" %) (%%)IKielerProgressMonitor>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/core/alg/IKielerProgressMonitor.html||style="" shape="rect" class="ext-link"]] and [[(% class="icon" %) (%%)KimlLayoutUtil>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/kiml/layout/util/KimlLayoutUtil.html||style="" shape="rect" class="ext-link"]]):(% class="code" %) | ||
41 | ((( | ||
42 | (% class="o" %).(% class="na" style="color: rgb(0,128,128);" %)begin(% class="o" %)((% class="s" style="color: rgb(187,136,68);" %)"<Login> Layouter"(% class="o" %),(% class="mi" style="color: rgb(0,153,153);" %)1(% class="o" %));=.(% class="na" style="color: rgb(0,128,128);" %)getData(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)class(% class="o" %));(% class="kt" style="color: rgb(68,85,136);" %)float(% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getProperty(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)SPACING(% class="o" %));(% class="k" %)if(% class="o" %)(<(% class="mi" style="color: rgb(0,153,153);" %)0(% class="o" %)){=;}(% class="kt" style="color: rgb(68,85,136);" %)float(% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getProperty(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)BORDER_SPACING(% class="o" %));(% class="k" %)if(% class="o" %)(<(% class="mi" style="color: rgb(0,153,153);" %)0(% class="o" %)){=;} | ||
43 | |||
44 | {{{ progressMonitor | ||
45 | KShapeLayout parentLayout layoutNodeKShapeLayout | ||
46 | objectSpacing parentLayoutLayoutOptions | ||
47 | objectSpacing | ||
48 | objectSpacing DEFAULT_SPACING | ||
49 | |||
50 | borderSpacing parentLayoutLayoutOptions | ||
51 | borderSpacing | ||
52 | borderSpacing DEFAULT_SPACING | ||
53 | |||
54 | }}} | ||
55 | ))) | ||
56 | 1. Write the following line at the end of the doLayout method:(% class="code" %) | ||
57 | ((( | ||
58 | (% class="o" %).(% class="na" style="color: rgb(0,128,128);" %)done(% class="o" %)(); | ||
59 | |||
60 | {{{ progressMonitor | ||
61 | }}} | ||
62 | ))) | ||
63 | 1. ((( | ||
64 | Implement the rest of the layouter such that the nodes of the input graph are all put in a row | ||
65 | * See the [[(% class="icon" %) (%%)KGraph>>url:https://rtsys.informatik.uni-kiel.de/trac/kieler/wiki/KGraph||style="" shape="rect" class="ext-link"]] and [[(% class="icon" %) (%%)KLayoutData>>url:https://rtsys.informatik.uni-kiel.de/trac/kieler/wiki/KLayoutData||style="" shape="rect" class="ext-link"]] data structures: the input is a [[(% class="icon" %) (%%)KNode>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/core/kgraph/KNode.html||style="" shape="rect" class="ext-link"]] and holds the nodes of the graph in its list of children | ||
66 | * Iterate over the nodes in the [[(% class="icon" %) (%%)getChildren()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/core/kgraph/KNode.html#getChildren()||style="" shape="rect" class="ext-link"]] list of the layoutNode input | ||
67 | * Retrieve the size of a node using the following code:(% class="code" %) | ||
68 | ((( | ||
69 | (% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getData(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)class(% class="o" %));(% class="kt" style="color: rgb(68,85,136);" %)float(% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getWidth(% class="o" %)();(% class="kt" style="color: rgb(68,85,136);" %)float(% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getHeight(% class="o" %)(); | ||
70 | |||
71 | {{{ KShapeLayout nodeLayout nodeKShapeLayout | ||
72 | width nodeLayout | ||
73 | height nodeLayout | ||
74 | }}} | ||
75 | ))) | ||
76 | * Set the position (x, y) of a node's upper left corner using the following code:(% class="code" %) | ||
77 | ((( | ||
78 | (% class="o" %).(% class="na" style="color: rgb(0,128,128);" %)setXpos(% class="o" %)();.(% class="na" style="color: rgb(0,128,128);" %)setYpos(% class="o" %)(); | ||
79 | |||
80 | {{{ nodeLayoutx | ||
81 | nodeLayouty | ||
82 | }}} | ||
83 | ))) | ||
84 | * objectSpacing shall be the spacing to be left between each pair of nodes | ||
85 | * borderSpacing shall be the spacing to be left to the borders of the drawing: the first node's coordinates shall be (borderSpacing, borderSpacing) | ||
86 | * At the end of the method, set the width and height of parentLayout so that it is large enough to hold the whole drawing, including borders | ||
87 | * Edges may be ignored for now | ||
88 | ))) | ||
89 | ))) | ||
90 | 1. Open the file META-INF/MANIFEST.MF -> //Extensions// tab\\ | ||
91 | 11. Add an extension for de.cau.cs.kieler.kiml.layout.layoutProviders | ||
92 | 11. Right-click the extension -> //New// -> //layoutProvider// | ||
93 | 11. Set //name// to //<Login> Test Layouter//, //class// to de.cau.cs.rtprak.<login>.exercise1.<Login>LayoutProvider | ||
94 | 11. Right-click the new //layoutProvider// -> //New// -> //knownOption//, set //option// to de.cau.cs.kieler.layout.options.minSpacing | ||
95 | 11. Add another //knownOption//, set to de.cau.cs.kieler.layout.options.borderSpacing | ||
96 | 1. //Run// -> //Run Configurations...// -> right-click //Eclipse Application// -> //New//\\ | ||
97 | 11. Name: //Layout// | ||
98 | 11. For testing the layouter, a new workspace location will be created; you may configure its destination in //Workspace Data// -> //Location// | ||
99 | 11. Add the program arguments -debug -consoleLog in the //Arguments// tab | ||
100 | 11. Go to //Plug-ins// tab, select //Launch with: plug-ins selected below only// | ||
101 | 11. //Deselect All//, activate //Workspace// checkbox, //Add Required Plug-ins//, //Apply//, //Run// | ||
102 | 1. Test the layouter in the new Eclipse instance:\\ | ||
103 | 11. //New// -> //Project...// -> //General// -> //Project//, name //test// | ||
104 | 11. Right-click test project -> //New// -> //Other...// -> //Graphs Diagram// | ||
105 | 11. Create a graph using the palette on the right | ||
106 | 11. //Window// -> //Show View// -> //Other...// -> //KIELER// -> //Layout// | ||
107 | 11. While the graph diagram is open, set //Layout Provider or Type// in the //Layout// view to //<Login> Test Layouter// | ||
108 | 11. Open the additional views //Layout Graph// and //Layout Time// | ||
109 | 11. Trigger layout with //KIELER// -> //Layout// or Ctrl+R L (first Ctrl+R, then L) or the button in the toolbar | ||
110 | 11. See the direct input and output of your algorithm in the //Layout Graph// view: //Pre-Layout// is the input, //Post-Layout// is the output | ||
111 | 11. See the execution time analysis in the //Layout Time// view | ||
112 | 1. ((( | ||
113 | Implement another class //EdgeRouter// with superclass de.cau.cs.kieler.core.alg.AbstractAlgorithm | ||
114 | 1. Add the following method:(% class="code" %) | ||
115 | ((( | ||
116 | (% class="cm" style="color: rgb(153,153,136);" %)/~*~* * Route the edges that are connected with the children of the given node. * * @param parentNode the parent node of the input graph */(% class="kd" %)public(% class="kt" style="color: rgb(68,85,136);" %)void(% class="nf" style="color: rgb(153,0,0);" %)routeEdges(% class="o" %)((% class="kd" %)final(% class="o" %)){().(% class="na" style="color: rgb(0,128,128);" %)begin(% class="o" %)((% class="s" style="color: rgb(187,136,68);" %)"Edge Routing"(% class="o" %),(% class="mi" style="color: rgb(0,153,153);" %)1(% class="o" %));().(% class="na" style="color: rgb(0,128,128);" %)done(% class="o" %)();} | ||
117 | |||
118 | {{{ | ||
119 | KNode parentNode | ||
120 | getMonitor | ||
121 | |||
122 | getMonitor | ||
123 | |||
124 | }}} | ||
125 | ))) | ||
126 | 1. Add the following code to the end of the doLayout method in your layout provider:(% class="code" %) | ||
127 | ((( | ||
128 | (% class="o" %)=(% class="k" %)new(% class="o" %)();.(% class="na" style="color: rgb(0,128,128);" %)reset(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)subTask(% class="o" %)((% class="mi" style="color: rgb(0,153,153);" %)1(% class="o" %)));.(% class="na" style="color: rgb(0,128,128);" %)routeEdges(% class="o" %)(); | ||
129 | |||
130 | {{{ EdgeRouter edgeRouter EdgeRouter | ||
131 | edgeRouterprogressMonitor | ||
132 | edgeRouterlayoutNode | ||
133 | }}} | ||
134 | ))) | ||
135 | 1. ((( | ||
136 | Implement the routeEdges method: | ||
137 | * Each edge shall be drawn with three line segments: one vertical segment starting below the source node, one horizonzal segment, and another vertical segment ending below the target node. | ||
138 | * The horizontal segments of two different edges shall not have the same y-coordinate; for consecutive edges, the distance between their horizontal segments shall equal objectSpacing | ||
139 | * See the attached image [[test-drawing.png>>url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/attachment/wiki/Exercises/Introduction/test-drawing.png||style="" title="Attachment 'test-drawing.png' in Exercises/Introduction" shape="rect" class="attachment"]](% class="noprint" %) [[~[~[image:url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/chrome/common/download.png~]~]>>url:http://trac.rtsys.informatik.uni-kiel.de/trac/10ss-layout/raw-attachment/wiki/Exercises/Introduction/test-drawing.png||style="" title="Download" shape="rect" class="trac-rawlink"]](%%) for an example | ||
140 | * Find the edges using [[(% class="icon" %) (%%)getOutgoingEdges()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/core/kgraph/KNode.html#getOutgoingEdges()||style="" shape="rect" class="ext-link"]] or [[(% class="icon" %) (%%)getIncomingEdges()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/core/kgraph/KNode.html#getIncomingEdges()||style="" shape="rect" class="ext-link"]] on a node | ||
141 | * Get the edge layout of an edge to set bend points using this code:(% class="code" %) | ||
142 | ((( | ||
143 | (% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)getData(% class="o" %)(.(% class="na" style="color: rgb(0,128,128);" %)class(% class="o" %)); | ||
144 | |||
145 | {{{ KEdgeLayout edgeLayout edgeKEdgeLayout | ||
146 | }}} | ||
147 | ))) | ||
148 | * Create a bend point using this code:(% class="code" %) | ||
149 | ((( | ||
150 | (% class="o" %)=.(% class="na" style="color: rgb(0,128,128);" %)eINSTANCE(% class="o" %).(% class="na" style="color: rgb(0,128,128);" %)createKPoint(% class="o" %)(); | ||
151 | |||
152 | {{{ KPoint point KLayoutDataFactory | ||
153 | }}} | ||
154 | ))) | ||
155 | * Use the [[(% class="icon" %) (%%)getBendPoints()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/kiml/layout/klayoutdata/KEdgeLayout.html#getBendPoints()||style="" shape="rect" class="ext-link"]] list on the edgeLayout to add bend points (clear the list first to remove points from the previous layout) | ||
156 | * Set the values of the points returned by [[(% class="icon" %) (%%)getSourcePoint()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/kiml/layout/klayoutdata/KEdgeLayout.html#getSourcePoint()||style="" shape="rect" class="ext-link"]] and [[(% class="icon" %) (%%)getTargetPoint()>>url:http://rtsys.informatik.uni-kiel.de/~~kieler/doc/de/cau/cs/kieler/kiml/layout/klayoutdata/KEdgeLayout.html#getTargetPoint()||style="" shape="rect" class="ext-link"]] according to the positions where the edge leaves its source node and reches its target node | ||
157 | ))) | ||
158 | ))) | ||
159 | 1. Use your previous run configuration to test the edge router. |