iconofthestoneage-doodl 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/lib/app/selfrunning.rb +185 -0
  2. data/lib/app/simple_app.rb +49 -0
  3. data/lib/app/simple_controller.rb +584 -0
  4. data/lib/app/simple_model.rb +292 -0
  5. data/lib/app/simple_view.rb +148 -0
  6. data/lib/breadth_first_search.rb +69 -0
  7. data/lib/connected_components.rb +29 -0
  8. data/lib/depth_first_search.rb +73 -0
  9. data/lib/edge.rb +57 -0
  10. data/lib/graph.rb +365 -0
  11. data/lib/graph_canvas.rb +187 -0
  12. data/lib/graph_generator.rb +121 -0
  13. data/lib/jruby/renderer.rb +413 -0
  14. data/lib/layout/collapse_layout.rb +23 -0
  15. data/lib/layout/fr_layout.rb +105 -0
  16. data/lib/layout/isom_layout.rb +77 -0
  17. data/lib/layout/kk_layout.rb +203 -0
  18. data/lib/layout/layout.rb +240 -0
  19. data/lib/layout/morph_layout.rb +65 -0
  20. data/lib/node.rb +57 -0
  21. data/lib/shortest_path/all_pair.rb +35 -0
  22. data/lib/shortest_path/bellman_ford.rb +60 -0
  23. data/lib/shortest_path/dijkstra.rb +74 -0
  24. data/lib/shortest_path/floyd_warshall.rb +68 -0
  25. data/lib/shortest_path/johnson_all_pair.rb +64 -0
  26. data/lib/shortest_path/single_source.rb +32 -0
  27. data/spec/breadth_first_search_spec.rb +145 -0
  28. data/spec/connected_components_spec.rb +50 -0
  29. data/spec/depth_first_search_spec.rb +89 -0
  30. data/spec/edge_spec.rb +58 -0
  31. data/spec/graph_generator_spec.rb +277 -0
  32. data/spec/graph_spec.rb +269 -0
  33. data/spec/jruby/renderer_spec.rb +214 -0
  34. data/spec/layout/layout_spec.rb +146 -0
  35. data/spec/node_spec.rb +179 -0
  36. data/spec/rspec_helper.rb +9 -0
  37. data/spec/rspec_suite.rb +12 -0
  38. data/spec/shortest_path/bellman_ford_spec.rb +101 -0
  39. data/spec/shortest_path/dijkstra_spec.rb +133 -0
  40. data/spec/shortest_path/floyd_warshall_spec.rb +84 -0
  41. data/spec/shortest_path/johnson_all_pair_spec.rb +90 -0
  42. metadata +43 -2
@@ -0,0 +1,185 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require "java"
4
+
5
+ require "logger"
6
+
7
+ require "graph"
8
+ require "jruby/renderer"
9
+ require "layout/layout"
10
+ require "layout/fr_layout"
11
+ require "layout/isom_layout"
12
+ require "layout/kk_layout"
13
+ require "shortest_path/dijkstra"
14
+
15
+ include Doodl
16
+
17
+ include_class 'javax.swing.JFrame'
18
+ include_class 'javax.swing.JLabel'
19
+ include_class 'java.awt.Dimension'
20
+ include_class 'java.awt.Color'
21
+ include_class 'java.awt.geom.Rectangle2D'
22
+
23
+ $LOG = Logger.new(STDOUT)
24
+ $LOG.sev_threshold = Logger::INFO
25
+
26
+ class Runner
27
+ def initialize(renderer)
28
+ @renderer = renderer
29
+ end
30
+ def update(observable)
31
+ @renderer.update_layout(observable)
32
+ end
33
+ end
34
+
35
+ frame = JFrame.new("Doodl: Graph Drawing with Ruby")
36
+
37
+ renderer = PluggableRenderer.new
38
+ renderer.paint_iterations = false
39
+ renderer.setPreferredSize(Dimension.new(800, 600))
40
+
41
+ label = JLabel.new("Doodl Graph Drawing!")
42
+ label.setOpaque(true)
43
+ label.setBackground(java.awt.Color::BLACK)
44
+ label.setForeground(java.awt.Color::WHITE)
45
+ label.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10))
46
+
47
+ frame.getContentPane().add(renderer, java.awt.BorderLayout::CENTER)
48
+ frame.getContentPane().add(label, java.awt.BorderLayout::SOUTH)
49
+ frame.pack
50
+ frame.setVisible(true)
51
+
52
+ graph = UndirectedGraph.new
53
+ graph.gen_random_graph(7, 10)
54
+
55
+ runner = Runner.new(renderer)
56
+
57
+
58
+
59
+ layouts = [RandomLayout, CircleLayout, FRLayout, ISOMLayout, KKLayout]
60
+
61
+ layouts.each do |lc|
62
+ l = lc.new(renderer)
63
+ l.graph = graph
64
+ l.add_observer(runner)
65
+ l.layout
66
+ label.setText("Undirected Graph - Layout: #{l.class}")
67
+ sleep(1)
68
+ end
69
+
70
+ graph.gen_ring_graph(10)
71
+ layout = ISOMLayout.new(renderer)
72
+ layout.graph = graph
73
+ layout.add_observer(runner)
74
+ layout.layout
75
+ label.setText("Graph Generator: Ring")
76
+ sleep(1)
77
+
78
+ graph.gen_linear_graph(5)
79
+ layout.layout
80
+ label.setText("Graph Generator: Linear")
81
+ sleep(1)
82
+
83
+ graph.gen_connected_graph(6)
84
+ layout.layout
85
+ label.setText("Graph Generator: Connected")
86
+ sleep(1)
87
+
88
+ graph.gen_mesh_graph(3)
89
+ layout.layout
90
+ label.setText("Graph Generator: Mesh")
91
+ sleep(1)
92
+
93
+ graph.gen_binary_tree(2)
94
+ layout.layout
95
+ label.setText("Graph Generator: Binary Tree")
96
+ sleep(1)
97
+
98
+ layout = FRLayout.new(renderer)
99
+ layout.add_observer(runner)
100
+ graph = DirectedGraph.new
101
+
102
+ graph.gen_random_graph(5, 10)
103
+ layout.graph = graph
104
+ layout.layout
105
+ label.setText("A Directed Graph")
106
+ sleep(1)
107
+
108
+ renderer.node_stroke_color_function { java.awt.Color::BLUE }
109
+ renderer.repaint
110
+ label.setText("Customize PluggableRenderer (node_stroke_color)")
111
+ sleep(1)
112
+ renderer.node_stroke_color_function { |g,l,n| if n.out_degree > 2 then Color::BLUE else Color::WHITE end}
113
+ renderer.repaint
114
+ sleep(1)
115
+ label.setText("You can define a function that defines the stoke color (e.g. if out_degree >2 then blue else white)")
116
+ renderer.node_shape_function { |g, l, n| Rectangle2D::Double.new(l[n].x-10, l[n].y-10, 20, 20) }
117
+ renderer.repaint
118
+ sleep(1)
119
+ label.setText("Customize PluggableRenderer (node_shape)")
120
+ label.setText("Zoom in and out")
121
+ 10.times do
122
+ renderer.zoom(0.9)
123
+ sleep(0.5)
124
+ end
125
+ label.setText("Zoom absolute (e.g. 100%)")
126
+ renderer.zoom_absolute(1.0)
127
+ sleep(1)
128
+ label.setText("Center on a node")
129
+ graph.nodes.each do |node|
130
+ renderer.node_stroke_color_function { |g,l,n| if node == n then Color::BLUE else Color::WHITE end }
131
+ renderer.center_on_node(node)
132
+ sleep(0.5)
133
+ end
134
+ renderer.node_stroke_color_function { |g,l,n| if n.out_degree > 2 then Color::BLUE else Color::WHITE end}
135
+
136
+ begin
137
+ renderer.set_defaults
138
+ graph.gen_binary_tree(3)
139
+
140
+ source = graph.nodes[1]
141
+ target = graph.nodes.last
142
+
143
+ stdata = graph.attach_node_data(:start)
144
+ stdata[source] = true
145
+ endata = graph.attach_node_data(:end)
146
+ endata[target] = true
147
+
148
+ dsp = DijkstraShortestPath.new(graph, source)
149
+ npath = dsp.node_path_to(target)
150
+ epath = dsp.edge_path_to(target)
151
+
152
+ edata = graph.attach_edge_data(:path)
153
+ epath.each do |e|
154
+ edata[e] = true
155
+ end
156
+ ndata = graph.attach_node_data(:path)
157
+ npath.each do |n|
158
+ ndata[n] = true
159
+ end
160
+
161
+ renderer.edge_stroke_function do |g, l, e|
162
+ if g.edge_data(:path) and g.edge_data(:path)[e]
163
+ BasicStroke.new(4)
164
+ else
165
+ BasicStroke.new(2)
166
+ end
167
+ end
168
+ renderer.node_stroke_color_function do |g, l, n|
169
+ if g.node_data(:start) and g.node_data(:start)[n]
170
+ Color::GREEN
171
+ elsif g.node_data(:end) and g.node_data(:end)[n]
172
+ Color::YELLOW
173
+ elsif g.node_data(:path) and g.node_data(:path)[n]
174
+ Color::BLUE
175
+ else
176
+ Color::WHITE
177
+ end
178
+ end
179
+
180
+ layout = KKLayout.new(renderer)
181
+ layout.add_observer(runner)
182
+ layout.layout(graph)
183
+ label.setText("You can use the PluggabeRender features to highlight a shortest path!")
184
+ end
185
+
@@ -0,0 +1,49 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
2
+
3
+ require 'java'
4
+
5
+ require 'logger'
6
+
7
+ require 'renderer'
8
+
9
+ require 'app/simple_controller'
10
+ require 'app/simple_view'
11
+ require 'app/simple_model'
12
+
13
+
14
+ require "layout/layout"
15
+
16
+ include Doodl
17
+
18
+ $LOG = Logger.new(STDOUT)
19
+ $LOG.sev_threshold = Logger::INFO
20
+ @view = SimpleView.new
21
+ @model = SimpleModel.new
22
+ controller = SimpleController.new
23
+
24
+ #setup view
25
+ @canvas = PluggableRenderer.new
26
+ @canvas.setPreferredSize(java.awt.Dimension.new(800, 600))
27
+
28
+
29
+ frame = javax.swing.JFrame.new("Graph Doodl App")
30
+ frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE);
31
+ frame.getContentPane().add(@canvas)
32
+ frame.pack
33
+ frame.setVisible(true)
34
+
35
+ @view.canvas = @canvas
36
+ @view.frame = frame
37
+
38
+ #setup model
39
+
40
+ #setup controller
41
+
42
+ #glueing
43
+ controller.view = @view
44
+ @model.view = @view
45
+ @model.add_observer(@view)
46
+ controller.model = @model
47
+
48
+ @model.set_random_layout
49
+ #model.new_connected_graph(5)
@@ -0,0 +1,584 @@
1
+ require 'java'
2
+
3
+ include_class 'java.awt.event.KeyListener'
4
+ include_class 'java.awt.event.KeyEvent'
5
+ include_class 'java.awt.event.MouseListener'
6
+ include_class 'java.awt.event.MouseMotionListener'
7
+ include_class 'java.awt.event.ActionListener'
8
+
9
+ module AppActionListener
10
+ include ActionListener
11
+
12
+ def actionPerformed(event)
13
+ end
14
+ end
15
+
16
+ module AppMouseListener
17
+ include MouseListener
18
+
19
+ def mouseEntered(event)
20
+ end
21
+
22
+ def mouseExited(event)
23
+ end
24
+
25
+ def mousePressed(event)
26
+ end
27
+
28
+ def mouseReleased(event)
29
+ end
30
+
31
+ def mouseClicked(event)
32
+ end
33
+ end
34
+
35
+ module AppMouseMotionListener
36
+ include MouseMotionListener
37
+
38
+ def mouseDragged(event)
39
+ end
40
+
41
+ def mouseMoved(event)
42
+ end
43
+ end
44
+
45
+ module AppKeyListener
46
+ include KeyListener
47
+
48
+ def keyPressed(event)
49
+ end
50
+
51
+ def keyReleased(event)
52
+ end
53
+
54
+ def keyTyped(event)
55
+ end
56
+ end
57
+
58
+ class SimpleController
59
+
60
+ attr_reader :view, :model
61
+
62
+ def view=(view)
63
+ @view = view
64
+ @view.add_key_listener(MainKeyListener.new(self))
65
+ end
66
+
67
+ def model=(model)
68
+ @model = model
69
+ end
70
+
71
+ def add_node
72
+ @view.add_mouse_listener(AddNodeMouseListener.new(self))
73
+ end
74
+
75
+ def del_node
76
+ @view.add_mouse_listener(DelNodeMouseListener.new(self))
77
+ end
78
+
79
+ def add_edge
80
+ @view.add_mouse_listener(AddEdgeMouseListener.new(self))
81
+ end
82
+
83
+ def del_edge
84
+ @view.add_mouse_listener(DelEdgeMouseListener.new(self))
85
+ end
86
+
87
+ def move_node
88
+ listener = MoveNodeMouseListener.new(self)
89
+ @view.add_mouse_motion_listener(listener)
90
+ @view.add_mouse_listener(listener)
91
+ end
92
+
93
+ def choose_layout
94
+ @view.add_info_panel("Select Layout. Enter Type [Random, Circle, FR, ISOM]")
95
+ @view.add_text_field(LayoutActionListener.new(self))
96
+ end
97
+
98
+ def choose_generator
99
+ @view.add_info_panel("Generate Graph. Enter Generation Mode [Random <s>, Linear <s>, Ring <s>, Mesh <r>, Connected <s>]")
100
+ @view.add_text_field(GenerateGraphActionListener.new(self))
101
+ end
102
+
103
+ def choose_graph_type
104
+ @view.add_info_panel("Choose graph type: [directed, undirected]")
105
+ @view.add_text_field(GraphTypeActionListener.new(self))
106
+ end
107
+
108
+ def do_layout
109
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
110
+ end
111
+
112
+ def new_graph
113
+ @model.new_empty_graph
114
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
115
+ end
116
+
117
+ def new_layout
118
+ end
119
+
120
+ def generate_graph
121
+ end
122
+
123
+ def select_node
124
+
125
+ end
126
+
127
+ def set_random_layout
128
+ @model.set_random_layout
129
+ @model.layout.layout
130
+ end
131
+
132
+ def set_circle_layout
133
+ @model.set_circle_layout
134
+ @model.layout.layout
135
+ end
136
+
137
+ def set_fr_layout
138
+ @model.set_fr_layout
139
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
140
+ end
141
+
142
+ def set_isom_layout
143
+ @model.set_isom_layout
144
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
145
+ end
146
+
147
+ def set_kk_layout
148
+ @model.set_kk_layout
149
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
150
+ end
151
+
152
+ def set_morph_layout(target_layout_class)
153
+ @model.set_morph_layout(target_layout_class)
154
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
155
+ end
156
+
157
+ def set_collapse_layout
158
+ @model.set_collapse_layout
159
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
160
+ end
161
+
162
+ def set_random(size)
163
+ @model.new_random_graph(size)
164
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
165
+ end
166
+
167
+ def set_ring(size)
168
+ @model.new_ring_graph(size)
169
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
170
+ end
171
+
172
+ def set_bintree(size)
173
+ @model.new_binary_tree(size)
174
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
175
+ end
176
+
177
+ def set_connected(size)
178
+ @model.new_connected_graph(size)
179
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
180
+ end
181
+
182
+ def set_linear(size)
183
+ @model.new_linear_graph(size)
184
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
185
+ end
186
+
187
+ def set_mesh(rows)
188
+ @model.new_mesh_graph(rows)
189
+ java.lang.Thread.new(java.lang.Runnable.impl { @model.layout.layout }).start
190
+ end
191
+
192
+ def print_info
193
+ puts @controller.model.layout
194
+ puts @controller.model.graph
195
+ end
196
+
197
+ def shortest_path
198
+ @view.add_mouse_listener(ShortestPathMouseListener.new(self))
199
+ end
200
+
201
+ def shortest_tree
202
+ @view.add_mouse_listener(ShortestTreeMouseListener.new(self))
203
+ end
204
+
205
+ def count_nodes
206
+ @model.count_nodes
207
+ end
208
+
209
+ def toggle_paint_iterations
210
+ @view.toggle_paint_iterations
211
+ $LOG.info "PluggableRenderer: paint_iterations? #{@view.canvas.paint_iterations?}"
212
+ end
213
+
214
+ def rotate_layout_right
215
+ @model.rotate_layout(2)
216
+ end
217
+
218
+ def rotate_layout_left
219
+ @model.rotate_layout(-2)
220
+ end
221
+
222
+ def move_layout_left
223
+ @model.move_layout(-5, 0)
224
+ end
225
+
226
+ def move_layout_right
227
+ @model.move_layout(5, 0)
228
+ end
229
+
230
+ def move_layout_up
231
+ @model.move_layout(0, -5)
232
+ end
233
+
234
+ def move_layout_down
235
+ @model.move_layout(0, 5)
236
+ end
237
+
238
+ def center_x
239
+ @model.center_x
240
+ end
241
+
242
+ def center_y
243
+ @model.center_y
244
+ end
245
+
246
+ end
247
+
248
+ class MainKeyListener
249
+ include AppKeyListener
250
+
251
+ def initialize(controller)
252
+ @controller = controller
253
+ end
254
+
255
+ def keyPressed(event)
256
+ case event.getKeyCode
257
+ when KeyEvent::VK_RIGHT
258
+ if event.isShiftDown
259
+ @controller.rotate_layout_right
260
+ else
261
+ @controller.move_layout_right
262
+ end
263
+ when KeyEvent::VK_LEFT
264
+ if event.isShiftDown
265
+ @controller.rotate_layout_left
266
+ else
267
+ @controller.move_layout_left
268
+ end
269
+ when KeyEvent::VK_UP
270
+ @controller.move_layout_up
271
+ when KeyEvent::VK_DOWN
272
+ @controller.move_layout_down
273
+ end
274
+ end
275
+
276
+ def keyTyped(event)
277
+ case event.key_char.chr
278
+ when 'a'
279
+ @controller.add_node
280
+ when 'c'
281
+ @controller.count_nodes
282
+ when 'd'
283
+ @controller.del_node
284
+ when 'u'
285
+ @controller.del_edge
286
+ when 'e'
287
+ @controller.add_edge
288
+ when 'n'
289
+ @controller.new_graph
290
+ when 'g'
291
+ @controller.choose_generator
292
+ when 'l'
293
+ @controller.choose_layout
294
+ when 'r'
295
+ @controller.do_layout
296
+ when 'i'
297
+ @controller.toggle_paint_iterations
298
+ when 's'
299
+ @controller.select_nodes
300
+ when 'm'
301
+ @controller.move_node
302
+ when 'p'
303
+ @controller.shortest_path
304
+ when 't'
305
+ @controller.shortest_tree
306
+ when 't'
307
+ @controller.choose_graph_type
308
+ when 'x'
309
+ @controller.center_x
310
+ when 'y'
311
+ @controller.center_y
312
+ end
313
+ end
314
+ end
315
+
316
+ class AddNodeMouseListener
317
+ include AppMouseListener
318
+
319
+ def initialize(controller)
320
+ @controller = controller
321
+ end
322
+
323
+ def mousePressed(event)
324
+ @node = @controller.model.add_node_at(event.x, event.y)
325
+ @controller.model.click(@node)
326
+ end
327
+
328
+ def mouseReleased(event)
329
+ @controller.model.unclick(@node) if @node
330
+ @controller.view.remove_mouse_listener(self)
331
+ end
332
+ end
333
+
334
+ class AddEdgeMouseListener
335
+ include AppMouseListener
336
+
337
+ def initialize(controller)
338
+ @controller = controller
339
+ end
340
+
341
+ def mousePressed(event)
342
+ if (!@first)
343
+ @first = @controller.model.get_nearest_node(event.x, event.y)
344
+ @controller.model.click(@first)
345
+ else
346
+ @second = @controller.model.get_nearest_node(event.x, event.y)
347
+ @controller.model.click(@second)
348
+ @edge = @controller.model.add_edge(@first, @second)
349
+ @controller.model.click_edge(@edge)
350
+ end
351
+ end
352
+
353
+ def mouseReleased(event)
354
+ @controller.model.unclick(@first) if @first
355
+ @controller.model.unclick_edge(@edge) if @edge
356
+ if @second
357
+ @controller.view.remove_mouse_listener(self)
358
+ @controller.model.unclick(@second) if @second
359
+ end
360
+ end
361
+ end
362
+
363
+ class DelEdgeMouseListener
364
+ include AppMouseListener
365
+
366
+ def initialize(controller)
367
+ @controller = controller
368
+ end
369
+
370
+ def mousePressed(event)
371
+ if (!@first)
372
+ @first = @controller.model.get_nearest_node(event.x, event.y)
373
+ @controller.model.click(@first)
374
+ else
375
+ @second = @controller.model.get_nearest_node(event.x, event.y)
376
+ @controller.model.click(@second)
377
+ @controller.model.click(@first)
378
+ @edge = @controller.model.get_edge(@first, @second)
379
+ @controller.model.click_edge(@edge) if @edge
380
+ end
381
+ end
382
+
383
+ def mouseReleased(event)
384
+ @controller.model.unclick(@first) if @first
385
+ if @second
386
+ @controller.view.remove_mouse_listener(self)
387
+ @controller.model.unclick(@second)
388
+ @controller.model.unclick_edge(@edge) if @edge
389
+ @controller.model.del_edge(@edge) if @edge
390
+ end
391
+ end
392
+ end
393
+
394
+ class MoveNodeMouseListener
395
+ include AppMouseMotionListener
396
+ include AppMouseListener
397
+
398
+ def initialize(controller)
399
+ @controller = controller
400
+ end
401
+
402
+ def mousePressed(event)
403
+ node = @controller.model.get_nearest_node(event.x, event.y)
404
+ @controller.model.click(node)
405
+ end
406
+
407
+ def mouseDragged(event)
408
+ if (!@node)
409
+ @node = @controller.model.get_nearest_node(event.x, event.y)
410
+ location = @controller.model.layout[@node]
411
+ @delta_x = location.x - event.x
412
+ @delta_y = location.y - event.y
413
+ end
414
+ @controller.model.set_location(@node, (event.x + @delta_x), (event.y + @delta_y))
415
+
416
+ end
417
+
418
+ def mouseReleased(event)
419
+ @controller.model.unclick(@node)
420
+ @controller.view.remove_mouse_listener(self)
421
+ @controller.view.remove_mouse_motion_listener(self)
422
+ end
423
+ end
424
+
425
+ class DelNodeMouseListener
426
+ include AppMouseListener
427
+
428
+ def initialize(controller)
429
+ @controller = controller
430
+ end
431
+
432
+ def mousePressed(event)
433
+ @node = @controller.model.get_nearest_node(event.x, event.y)
434
+ @controller.model.click(@node)
435
+ end
436
+
437
+ def mouseReleased(event)
438
+ if @node
439
+ @controller.model.unclick(@node)
440
+ @controller.model.del_node(@node)
441
+ end
442
+ @controller.view.remove_mouse_listener(self)
443
+ end
444
+
445
+ end
446
+
447
+ class ShortestTreeMouseListener
448
+ include AppMouseListener
449
+
450
+ def initialize(controller)
451
+ @controller = controller
452
+ end
453
+
454
+ def mousePressed(event)
455
+ @node = @controller.model.get_nearest_node(event.x, event.y)
456
+ @controller.model.click(@node)
457
+ end
458
+
459
+ def mouseReleased(event)
460
+ if @node
461
+ @controller.model.unclick(@node)
462
+ @controller.model.dspt(@node)
463
+ end
464
+ @controller.view.remove_mouse_listener(self)
465
+ end
466
+
467
+ end
468
+
469
+ class ShortestPathMouseListener
470
+ include AppMouseListener
471
+
472
+ def initialize(controller)
473
+ @controller = controller
474
+ end
475
+
476
+ def mousePressed(event)
477
+ if (!@first)
478
+ @first = @controller.model.get_nearest_node(event.x, event.y)
479
+ @controller.model.click(@first)
480
+ else
481
+ @second = @controller.model.get_nearest_node(event.x, event.y)
482
+ @controller.model.click(@second)
483
+ @controller.model.click(@first)
484
+ end
485
+ end
486
+
487
+ def mouseReleased(event)
488
+ if @first
489
+ @controller.model.unclick(@first)
490
+ if @second
491
+ @controller.model.unclick(@second)
492
+ @controller.view.remove_mouse_listener(self)
493
+ @controller.model.dsp(@first, @second)
494
+ end
495
+ end
496
+ end
497
+
498
+ end
499
+
500
+ class LayoutActionListener
501
+ def initialize(controller)
502
+ @controller = controller
503
+ end
504
+
505
+ def actionPerformed(event)
506
+ return_value = event.getSource.getText
507
+ a = return_value.split
508
+ case a[0].downcase
509
+ when 'random'
510
+ @controller.set_random_layout
511
+ when 'circle'
512
+ @controller.set_circle_layout
513
+ when 'fr'
514
+ @controller.set_fr_layout
515
+ when 'isom'
516
+ @controller.set_isom_layout
517
+ when 'kk'
518
+ @controller.set_kk_layout
519
+ when 'collapse'
520
+ @controller.set_collapse_layout
521
+ when 'morph'
522
+ @controller.set_morph_layout(a[1])
523
+ else
524
+ puts "Wrong Argument"
525
+ end
526
+ @controller.view.remove_text_field
527
+ @controller.view.remove_info_panel
528
+ end
529
+ end
530
+
531
+ class GenerateGraphActionListener
532
+ def initialize(controller)
533
+ @controller = controller
534
+ end
535
+
536
+ def actionPerformed(event)
537
+ return_value = event.source.getText
538
+ a = return_value.split
539
+ if a.size == 2 and a[1].to_i != 0
540
+ case a[0].downcase
541
+ when "random"
542
+ @controller.set_random(a[1].to_i)
543
+ when "bintree"
544
+ @controller.set_bintree(a[1].to_i)
545
+ when "ring"
546
+ @controller.set_ring(a[1].to_i)
547
+ when "connected"
548
+ @controller.set_connected(a[1].to_i)
549
+ when "mesh"
550
+ @controller.set_mesh(a[1].to_i)
551
+ when "linear"
552
+ @controller.set_linear(a[1].to_i)
553
+ else
554
+ puts "No Generator #{a[0]}"
555
+ end
556
+ else
557
+ puts "Wrong Syntax"
558
+ end
559
+ @controller.view.remove_text_field
560
+ @controller.view.remove_info_panel
561
+ end
562
+
563
+ end
564
+
565
+ class GraphTypeActionListener
566
+ def initialize(controller)
567
+ @controller = controller
568
+ end
569
+
570
+ def actionPerformed(event)
571
+ return_value = event.getSource.getText
572
+ case return_value.downcase
573
+ when 'directed'
574
+ @controller.model.set_directed
575
+ when 'undirected'
576
+ @controller.model.set_undirected
577
+ else
578
+ puts "Wrong Argument"
579
+ end
580
+ @controller.view.remove_text_field
581
+ @controller.view.remove_info_panel
582
+ end
583
+ end
584
+