Holt59 3 years ago
parent
commit
eceaecd813
5 changed files with 412 additions and 202 deletions
  1. 42
    23
      .classpath
  2. 1
    0
      .gitignore
  3. 6
    0
      .project
  4. 207
    105
      src/main/org/insa/base/MainWindow.java
  5. 156
    74
      src/main/org/insa/drawing/Drawing.java

+ 42
- 23
.classpath View File

@@ -1,23 +1,42 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<classpath>
3
-	<classpathentry kind="src" path="src/main"/>
4
-	<classpathentry kind="src" path="src/test"/>
5
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
6
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
7
-	<classpathentry kind="lib" path="libs/piccolo2d-core-3.0.jar">
8
-		<attributes>
9
-			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-core-3.0-javadoc.jar!/"/>
10
-		</attributes>
11
-	</classpathentry>
12
-	<classpathentry kind="lib" path="libs/piccolo2d-extras-3.0.jar">
13
-		<attributes>
14
-			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-extras-3.0-javadoc.jar!/"/>
15
-		</attributes>
16
-	</classpathentry>
17
-	<classpathentry kind="lib" path="libs/piccolo2d-swt-3.0.jar">
18
-		<attributes>
19
-			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-swt-3.0-javadoc.jar!/"/>
20
-		</attributes>
21
-	</classpathentry>
22
-	<classpathentry kind="output" path="bin"/>
23
-</classpath>
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<classpath>
3
+	<classpathentry kind="src" output="target/classes" path="src/main">
4
+		<attributes>
5
+			<attribute name="optional" value="true"/>
6
+			<attribute name="maven.pomderived" value="true"/>
7
+		</attributes>
8
+	</classpathentry>
9
+	<classpathentry kind="src" output="target/test-classes" path="src/test">
10
+		<attributes>
11
+			<attribute name="optional" value="true"/>
12
+			<attribute name="maven.pomderived" value="true"/>
13
+		</attributes>
14
+	</classpathentry>
15
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
16
+		<attributes>
17
+			<attribute name="maven.pomderived" value="true"/>
18
+		</attributes>
19
+	</classpathentry>
20
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
21
+	<classpathentry kind="lib" path="libs/piccolo2d-core-3.0.jar">
22
+		<attributes>
23
+			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-core-3.0-javadoc.jar!/"/>
24
+		</attributes>
25
+	</classpathentry>
26
+	<classpathentry kind="lib" path="libs/piccolo2d-extras-3.0.jar">
27
+		<attributes>
28
+			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-extras-3.0-javadoc.jar!/"/>
29
+		</attributes>
30
+	</classpathentry>
31
+	<classpathentry kind="lib" path="libs/piccolo2d-swt-3.0.jar">
32
+		<attributes>
33
+			<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-swt-3.0-javadoc.jar!/"/>
34
+		</attributes>
35
+	</classpathentry>
36
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
37
+		<attributes>
38
+			<attribute name="maven.pomderived" value="true"/>
39
+		</attributes>
40
+	</classpathentry>
41
+	<classpathentry kind="output" path="target/classes"/>
42
+</classpath>

+ 1
- 0
.gitignore View File

@@ -1,2 +1,3 @@
1 1
 .DS_Store
2 2
 bin
3
+/target/

+ 6
- 0
.project View File

@@ -10,8 +10,14 @@
10 10
 			<arguments>
11 11
 			</arguments>
12 12
 		</buildCommand>
13
+		<buildCommand>
14
+			<name>org.eclipse.m2e.core.maven2Builder</name>
15
+			<arguments>
16
+			</arguments>
17
+		</buildCommand>
13 18
 	</buildSpec>
14 19
 	<natures>
20
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
15 21
 		<nature>org.eclipse.jdt.core.javanature</nature>
16 22
 	</natures>
17 23
 </projectDescription>

+ 207
- 105
src/main/org/insa/base/MainWindow.java View File

@@ -11,10 +11,12 @@ import java.io.File;
11 11
 import java.io.IOException;
12 12
 import java.io.OutputStream;
13 13
 import java.io.PrintStream;
14
+import java.lang.reflect.Constructor;
14 15
 import java.util.ArrayList;
15 16
 
16 17
 import javax.swing.BorderFactory;
17 18
 import javax.swing.BoxLayout;
19
+import javax.swing.JButton;
18 20
 import javax.swing.JFileChooser;
19 21
 import javax.swing.JFrame;
20 22
 import javax.swing.JLabel;
@@ -28,13 +30,21 @@ import javax.swing.JSplitPane;
28 30
 import javax.swing.JTextArea;
29 31
 import javax.swing.KeyStroke;
30 32
 import javax.swing.SwingConstants;
33
+import javax.swing.UIManager;
31 34
 import javax.swing.filechooser.FileNameExtensionFilter;
32 35
 
36
+import org.insa.algo.AbstractSolution;
37
+import org.insa.algo.shortestpath.BellmanFordAlgorithm;
38
+import org.insa.algo.shortestpath.ShortestPathAlgorithm;
39
+import org.insa.algo.shortestpath.ShortestPathGraphicObserver;
40
+import org.insa.algo.shortestpath.ShortestPathInstance;
41
+import org.insa.algo.shortestpath.ShortestPathInstance.Mode;
42
+import org.insa.algo.shortestpath.ShortestPathSolution;
33 43
 import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
34 44
 import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver;
35 45
 import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
36 46
 import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsInstance;
37
-import org.insa.drawing.DrawingVisible;
47
+import org.insa.drawing.Drawing;
38 48
 import org.insa.drawing.graph.BlackAndWhiteGraphPalette;
39 49
 import org.insa.drawing.graph.GraphDrawing;
40 50
 import org.insa.drawing.graph.PathDrawing;
@@ -48,71 +58,76 @@ import org.insa.graph.io.Openfile;
48 58
 import com.sun.glass.events.KeyEvent;
49 59
 
50 60
 public class MainWindow extends JFrame {
51
-	
61
+
52 62
 	public class JOutputStream extends OutputStream {
53
-	    private JTextArea textArea;
54
-
55
-	    public JOutputStream(JTextArea textArea) {
56
-	        this.textArea = textArea;
57
-	    }
58
-
59
-	    @Override
60
-	    public void write(int b) throws IOException {
61
-	        // redirects data to the text area
62
-	    		textArea.setText(textArea.getText() + String.valueOf((char)b));
63
-	        // scrolls the text area to the end of data
64
-	        textArea.setCaretPosition(textArea.getDocument().getLength());
65
-	        // keeps the textArea up to date
66
-	        textArea.update(textArea.getGraphics());
67
-	    }
63
+		private JTextArea textArea;
64
+
65
+		public JOutputStream(JTextArea textArea) {
66
+			this.textArea = textArea;
67
+		}
68
+
69
+		@Override
70
+		public void write(int b) throws IOException {
71
+			// redirects data to the text area
72
+			textArea.setText(textArea.getText() + String.valueOf((char)b));
73
+			// scrolls the text area to the end of data
74
+			textArea.setCaretPosition(textArea.getDocument().getLength());
75
+			// keeps the textArea up to date
76
+			textArea.update(textArea.getGraphics());
77
+		}
68 78
 	}
69 79
 
70 80
 	/**
71 81
 	 * 
72 82
 	 */
73 83
 	private static final long serialVersionUID = -527660583705140687L;
74
-	
84
+
75 85
 	/**
76 86
 	 * 
77 87
 	 */
78 88
 	private static final String WINDOW_TITLE = "BE Graphes INSA";
79
-	
89
+
80 90
 	/**
81 91
 	 * 
82 92
 	 */
83 93
 	private static final Dimension DEFAULT_DIMENSION = new Dimension(800, 600);
84
-	
94
+
85 95
 	// Current graph.
86 96
 	private Graph graph;
87
-	
97
+
88 98
 	// Current loaded path.
89 99
 	private Path currentPath;
90
-	
100
+
91 101
 	// List of item for the top menus.
92 102
 	private JMenuItem openMapItem;
93
-	
103
+
94 104
 	// List of items that cannot be used without a graph
95 105
 	private ArrayList<JMenuItem> graphItems = new ArrayList<JMenuItem>();
96
-	
106
+
97 107
 	// Label containing the map ID of the current graph.
98 108
 	private JLabel mapIdPanel;
99 109
 	
110
+	private JPanel threadPanel;
111
+
100 112
 	// Log stream and print stream
101 113
 	private JOutputStream logStream;
102 114
 	private PrintStream printStream;
103 115
 	
116
+	// Current running thread
117
+	private Thread currentThread;
118
+
104 119
 	/**
105 120
 	 * 
106 121
 	 */
107
-	private DrawingVisible drawing;
108
-	
122
+	private Drawing drawing;
123
+
109 124
 	public MainWindow() {
110 125
 		super(WINDOW_TITLE);
111 126
 		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
112 127
 		setLayout(new BorderLayout());
113 128
 		setSize(DEFAULT_DIMENSION);
114 129
 		setJMenuBar(createMenuBar());
115
-		
130
+
116 131
 		addWindowListener(new WindowAdapter() {
117 132
 			public void windowClosing(WindowEvent e) {
118 133
 				int confirmed = JOptionPane.showConfirmDialog(null, 
@@ -125,13 +140,13 @@ public class MainWindow extends JFrame {
125 140
 				}
126 141
 			}
127 142
 		});
128
-		
143
+
129 144
 		// Create graph area
130 145
 		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
131
-				
132
-		drawing = new DrawingVisible();
146
+
147
+		drawing = new Drawing();
133 148
 		drawing.setBackground(Color.WHITE);
134
-		
149
+
135 150
 		JTextArea infoPanel = new JTextArea();
136 151
 		infoPanel.setMinimumSize(new Dimension(200, 50));
137 152
 		// infoPanel.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.GRAY));
@@ -140,36 +155,70 @@ public class MainWindow extends JFrame {
140 155
 		infoPanel.setEditable(false);
141 156
 		this.logStream = new JOutputStream(infoPanel);
142 157
 		this.printStream = new PrintStream(this.logStream);
143
-		
144
-        sp.setResizeWeight(0.8);
145
-        // sp.setEnabled(false);
146
-        sp.setDividerSize(5);
147
-        
148
-        sp.setBackground(Color.WHITE);
158
+
159
+		sp.setResizeWeight(0.8);
160
+		// sp.setEnabled(false);
161
+		sp.setDividerSize(5);
162
+
163
+		sp.setBackground(Color.WHITE);
149 164
 		sp.add(drawing);
150 165
 		sp.add(new JScrollPane(infoPanel));		
151 166
 		this.add(sp, BorderLayout.CENTER);
152
-				
167
+
153 168
 		this.add(createStatusBar(), BorderLayout.SOUTH);
154 169
 	}
155 170
 	
171
+	private void launchThread(Runnable runnable) {
172
+		currentThread = new Thread(new Runnable() {
173
+			@Override
174
+			public void run() {
175
+				threadPanel.setVisible(true);
176
+				runnable.run();
177
+				threadPanel.setVisible(false);
178
+			}
179
+		});
180
+		currentThread.start();
181
+	}
182
+
183
+	private ShortestPathInstance getShortestPathParameters() {
184
+		// TODO: Select origin / end nodes.
185
+		return new ShortestPathInstance(
186
+			graph, graph.getNodes().get(2), graph.getNodes().get(139), Mode.TIME);
187
+	}
188
+	
189
+	private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {	
190
+		spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));
191
+		// algo.addObserver(new ShortestPathTextObserver(printStream));
192
+		launchThread(new Runnable() {
193
+			@Override
194
+			public void run() {
195
+				spAlgorithm.run();
196
+				AbstractSolution solution = spAlgorithm.getLastSolution();
197
+				if (solution != null && solution.isFeasible()) {
198
+					new PathDrawing(drawing).drawPath(((ShortestPathSolution)solution).getPath());
199
+				}
200
+			}
201
+		});
202
+	}
203
+	
204
+	@SuppressWarnings("restriction")
156 205
 	private JMenuBar createMenuBar() {
157 206
 
158 207
 		// Open Map item...
159 208
 		openMapItem = new JMenuItem("Open Map... ",
160
-		                         KeyEvent.VK_O);
209
+				KeyEvent.VK_O);
161 210
 		openMapItem.setAccelerator(KeyStroke.getKeyStroke(
162
-		        KeyEvent.VK_O, ActionEvent.ALT_MASK));
211
+				KeyEvent.VK_O, ActionEvent.ALT_MASK));
163 212
 		openMapItem.addActionListener(new ActionListener() {
164 213
 			@Override
165 214
 			public void actionPerformed(ActionEvent e) {
166 215
 				JFileChooser chooser = new JFileChooser();
167
-			    FileNameExtensionFilter filter = new FileNameExtensionFilter(
168
-			        "Map & compressed map files", "map", "map.gz");
169
-			    chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
170
-			    chooser.setFileFilter(filter);
171
-			    if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
172
-			    		BinaryGraphReader reader;
216
+				FileNameExtensionFilter filter = new FileNameExtensionFilter(
217
+						"Map & compressed map files", "map", "map.gz");
218
+				chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
219
+				chooser.setFileFilter(filter);
220
+				if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
221
+					BinaryGraphReader reader;
173 222
 					try {
174 223
 						reader = new BinaryGraphReader(
175 224
 								Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
@@ -177,38 +226,38 @@ public class MainWindow extends JFrame {
177 226
 						JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
178 227
 						return ;
179 228
 					}
180
-			    		try {
181
-			    			graph = reader.read();
182
-			    		}
183
-			    		catch (Exception exception) {
229
+					try {
230
+						graph = reader.read();
231
+					}
232
+					catch (Exception exception) {
184 233
 						JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file.");
185 234
 						return ;
186
-			    		}
187
-			    		drawing.clear();
188
-			    		new GraphDrawing(drawing).drawGraph(graph);
189
-			    		
190
-			    		for (JMenuItem item: graphItems) {
191
-			    			item.setEnabled(true);
192
-			    		}
193
-			    		mapIdPanel.setText("Map ID: 0x" + Integer.toHexString(graph.getMapId()));
194
-			    }
235
+					}
236
+					drawing.clear();
237
+					new GraphDrawing(drawing).drawGraph(graph);
238
+
239
+					for (JMenuItem item: graphItems) {
240
+						item.setEnabled(true);
241
+					}
242
+					mapIdPanel.setText("Map ID: 0x" + Integer.toHexString(graph.getMapId()));
243
+				}
195 244
 			}
196 245
 		});
197
-		
246
+
198 247
 		// Open Path item...
199 248
 		JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P);
200 249
 		openPathItem.setAccelerator(KeyStroke.getKeyStroke(
201
-		        KeyEvent.VK_P, ActionEvent.ALT_MASK));
250
+				KeyEvent.VK_P, ActionEvent.ALT_MASK));
202 251
 		openPathItem.addActionListener(new ActionListener() {
203 252
 			@Override
204 253
 			public void actionPerformed(ActionEvent e) {
205 254
 				JFileChooser chooser = new JFileChooser();
206
-			    FileNameExtensionFilter filter = new FileNameExtensionFilter(
207
-			        "Path & compressed path files", "path", "path.gz");
208
-			    chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
209
-			    chooser.setFileFilter(filter);
210
-			    if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
211
-			    		BinaryPathReader reader;
255
+				FileNameExtensionFilter filter = new FileNameExtensionFilter(
256
+						"Path & compressed path files", "path", "path.gz");
257
+				chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
258
+				chooser.setFileFilter(filter);
259
+				if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
260
+					BinaryPathReader reader;
212 261
 					try {
213 262
 						reader = new BinaryPathReader(
214 263
 								Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
@@ -216,23 +265,23 @@ public class MainWindow extends JFrame {
216 265
 						JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
217 266
 						return ;
218 267
 					}
219
-			    		try {
220
-			    			currentPath = reader.readPath(graph);
221
-			    		}
222
-			    		catch (MapMismatchException exception) {
223
-			    			JOptionPane.showMessageDialog(MainWindow.this, "The selected file does not contain a path for the current graph.");
224
-			    			return;
225
-			    		}
226
-			    		catch (Exception exception) {
268
+					try {
269
+						currentPath = reader.readPath(graph);
270
+					}
271
+					catch (MapMismatchException exception) {
272
+						JOptionPane.showMessageDialog(MainWindow.this, "The selected file does not contain a path for the current graph.");
273
+						return;
274
+					}
275
+					catch (Exception exception) {
227 276
 						JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file.");
228 277
 						return ;
229
-			    		}
230
-			    		new PathDrawing(drawing).drawPath(currentPath);
231
-			    }
278
+					}
279
+					new PathDrawing(drawing).drawPath(currentPath);
280
+				}
232 281
 			}
233 282
 		});
234 283
 		graphItems.add(openPathItem);
235
-		
284
+
236 285
 		// Close item
237 286
 		JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q);
238 287
 		closeItem.setAccelerator(KeyStroke.getKeyStroke(
@@ -250,7 +299,7 @@ public class MainWindow extends JFrame {
250 299
 		fileMenu.add(openPathItem);
251 300
 		fileMenu.addSeparator();
252 301
 		fileMenu.add(closeItem);
253
-		
302
+
254 303
 		// Second menu
255 304
 		JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R);
256 305
 		drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(
@@ -258,10 +307,14 @@ public class MainWindow extends JFrame {
258 307
 		drawGraphItem.addActionListener(new ActionListener() {		
259 308
 			@Override
260 309
 			public void actionPerformed(ActionEvent e) {
261
-				drawing.clear();
262
-				drawing.setAutoRepaint(true);
263
-				new GraphDrawing(drawing).drawGraph(graph);
264
-				drawing.setAutoRepaint(false);
310
+				launchThread(new Runnable() {
311
+					@Override
312
+					public void run() {
313
+						drawing.clear();
314
+						drawing.setAutoRepaint(true);
315
+						new GraphDrawing(drawing).drawGraph(graph);				
316
+					}
317
+				});
265 318
 			}
266 319
 		});
267 320
 		graphItems.add(drawGraphItem);
@@ -271,40 +324,58 @@ public class MainWindow extends JFrame {
271 324
 		drawGraphBWItem.addActionListener(new ActionListener() {		
272 325
 			@Override
273 326
 			public void actionPerformed(ActionEvent e) {
274
-				drawing.clear();
275
-				drawing.setAutoRepaint(true);
276
-				new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph);
277
-				drawing.setAutoRepaint(false);
327
+				launchThread(new Runnable() {
328
+					@Override
329
+					public void run() {
330
+						drawing.clear();
331
+						drawing.setAutoRepaint(true);
332
+						new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph);				
333
+					}
334
+				});
278 335
 			}
279 336
 		});
280 337
 		graphItems.add(drawGraphBWItem);
281
-		
338
+
282 339
 		JMenu graphMenu = new JMenu("Graph");
283 340
 		graphMenu.add(drawGraphItem);
284 341
 		graphMenu.add(drawGraphBWItem);
285
-		
342
+
286 343
 		// Algo menu
287 344
 		JMenu algoMenu = new JMenu("Algorithms");
288
-		
345
+
346
+		// Weakly connected components
289 347
 		JMenuItem wccItem = new JMenuItem("Weakly Connected Components");
290 348
 		wccItem.addActionListener(new ActionListener() {
291 349
 			@Override
292 350
 			public void actionPerformed(ActionEvent e) {
293
-
294 351
 				WeaklyConnectedComponentsInstance instance = new WeaklyConnectedComponentsInstance(graph);
295 352
 				WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(instance);
296 353
 				algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
297
-				
298
-				(new Thread(algo)).start();
354
+				// algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
355
+				launchThread(algo);
356
+			}
357
+		});
358
+
359
+		// Shortest path
360
+		JMenuItem bellmanItem = new JMenuItem("Shortest Path (Bellman-Ford)");
361
+		bellmanItem.addActionListener(new ActionListener() {
362
+			@Override
363
+			public void actionPerformed(ActionEvent e) {
364
+				launchShortestPathThread(new BellmanFordAlgorithm(getShortestPathParameters()));
299 365
 			}
300 366
 		});
301 367
 		graphItems.add(wccItem);
302
-		
368
+		graphItems.add(bellmanItem);
369
+
303 370
 		algoMenu.add(wccItem);
304
-		
371
+		algoMenu.addSeparator();
372
+		algoMenu.add(bellmanItem);
373
+		// algoMenu.add(djikstraItem);
374
+		// algoMenu.add(aStarItem);
375
+
305 376
 		// Create the menu bar.
306 377
 		JMenuBar menuBar = new JMenuBar();
307
-		
378
+
308 379
 		menuBar.add(fileMenu);
309 380
 		menuBar.add(graphMenu);
310 381
 		menuBar.add(algoMenu);
@@ -312,29 +383,60 @@ public class MainWindow extends JFrame {
312 383
 		for (JMenuItem item: graphItems) {
313 384
 			item.setEnabled(false);
314 385
 		}
315
-		
386
+
316 387
 		return menuBar;
317 388
 	}
318
-	
389
+
319 390
 	private JPanel createStatusBar() {
320 391
 		// create the status bar panel and shove it down the bottom of the frame
321 392
 		JPanel statusPanel = new JPanel();
322 393
 		statusPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY));
323
-		statusPanel.setPreferredSize(new Dimension(getWidth(), 20));
324
-		statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
325
-		
394
+		statusPanel.setPreferredSize(new Dimension(getWidth(), 34));
395
+		statusPanel.setLayout(new BorderLayout());
396
+
326 397
 		mapIdPanel = new JLabel();
327 398
 		mapIdPanel.setHorizontalAlignment(SwingConstants.LEFT);
328
-		statusPanel.add(mapIdPanel);
399
+		statusPanel.add(mapIdPanel, BorderLayout.WEST);
400
+		
401
+		JLabel threadInfo = new JLabel("Thread running... ");
402
+		JButton threadButton = new JButton("Stop");
403
+		threadButton.addActionListener(new ActionListener() {
404
+			@SuppressWarnings("deprecation")
405
+			@Override
406
+			public void actionPerformed(ActionEvent e) {
407
+				if (currentThread != null && currentThread.isAlive()) {
408
+					int confirmed = JOptionPane.showConfirmDialog(null, 
409
+							"Are you sure you want to kill the running thread?", "Kill Confirmation",
410
+							JOptionPane.YES_NO_OPTION);
411
+					if (confirmed == JOptionPane.YES_OPTION) {
412
+						currentThread.stop();
413
+						currentThread = null;
414
+						threadPanel.setVisible(false);
415
+					}
416
+				}
417
+			}
418
+		});
419
+		threadPanel = new JPanel();
420
+		threadPanel.add(threadInfo);
421
+		threadPanel.add(threadButton);
422
+		// threadPanel.setVisible(false);
423
+		statusPanel.add(threadPanel, BorderLayout.EAST);
329 424
 
330 425
 		return statusPanel;
331 426
 	}
332
-	
427
+
333 428
 	public static void main(final String[] args) {
429
+
430
+		// Try to set system look and feel.
431
+		try {
432
+			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) ;
433
+		} 
434
+		catch (Exception e) { }
435
+
334 436
 		MainWindow w = new MainWindow();
335 437
 		w.setExtendedState(JFrame.MAXIMIZED_BOTH);
336 438
 		w.setVisible(true);
337 439
 	}
338
-	
440
+
339 441
 
340 442
 }

+ 156
- 74
src/main/org/insa/drawing/Drawing.java View File

@@ -1,88 +1,170 @@
1
-package org.insa.drawing ;
1
+package org.insa.drawing;
2
+
3
+import java.awt.BasicStroke;
4
+import java.awt.Color;
5
+import java.awt.Graphics;
6
+import java.awt.Graphics2D;
7
+import java.awt.Image;
8
+import java.awt.image.*;
9
+
10
+import javax.swing.JPanel;
2 11
 
3 12
 /**
4
- *   Classe abstraite pour dessiner a l'ecran.
5
- *   Deux implementations : une sous-classe DessinVisible qui dessine vraiment a l'ecran
6
- *   et une sous-classe DessinInvisible qui ne dessine rien (pour ne pas ralentir les tests avec l'affichage).
13
+ *   Cette implementation de la classe Dessin produit vraiment un affichage
14
+ *   (au contraire de la classe DessinInvisible).
7 15
  */
8 16
 
9
-import java.awt.* ;
17
+public class Drawing extends JPanel {
10 18
 
11
-public interface Drawing {
12
-	
13 19
 	/**
14
-	 * Enable auto-repaint mode - When this mode is enable, call to 
15
-	 * drawing function will automatically repaint the drawing, which
16
-	 * may be very slow in some case.
17
-	 * 
18
-	 * @param autoRepaint Use true to enable auto-repaint, false to disable.
19 20
 	 * 
20 21
 	 */
21
-	public void setAutoRepaint(boolean autoRepaint);
22
+	private static final long serialVersionUID = 96779785877771827L;
23
+	
24
+	private final Graphics2D gr;
25
+
26
+	private float long1;
27
+	private float long2;
28
+	private float lat1;
29
+	private float lat2;
30
+	
31
+	// Width and height of the image
32
+	private final int width, height;
33
+
34
+	private boolean bb_is_set ;
22 35
 	
36
+	private Image image;
37
+	private ZoomAndPanListener zoomAndPanListener;
38
+	
39
+	public boolean autoRepaint = true;
40
+
23 41
 	/**
24
-	 * Repaint the drawing.
25
-	 * 
42
+	 *  Cree et affiche une nouvelle fenetre de dessin.
26 43
 	 */
27
-	public void repaint();
44
+	public Drawing() {
45
+		
46
+		this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
47
+		this.addMouseListener(zoomAndPanListener);
48
+		this.addMouseMotionListener(zoomAndPanListener);
49
+		this.addMouseWheelListener(zoomAndPanListener);
50
+		
51
+		this.width = 2000;
52
+		this.height = 1600;
53
+		
54
+		BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
55
+		
56
+		this.image = img;
57
+		this.gr = img.createGraphics();
58
+		
59
+		this.zoomAndPanListener.setCoordTransform(this.gr.getTransform());
60
+		
61
+		this.bb_is_set = false;
62
+
63
+
64
+		this.long1 = 0.0f;
65
+		this.long2 = this.width;
66
+		this.lat1  = 0.0f;
67
+		this.lat2  = this.height;
68
+
69
+		this.clear();
70
+		this.repaint();
71
+
72
+	}
73
+
74
+	@Override
75
+	public void paintComponent(Graphics g1) {
76
+		Graphics2D g = (Graphics2D)g1;
77
+		g.clearRect(0, 0, getWidth(), getHeight());
78
+		g.setTransform(zoomAndPanListener.getCoordTransform());
79
+		g.drawImage(image, 0, 0, this);
80
+	}
81
+	
82
+	public void setAutoRepaint(boolean autoRepaint) {
83
+		this.autoRepaint = autoRepaint;
84
+	}
28 85
 	
29
-    /**
30
-     * Set the pencil width.
31
-     * 
32
-     * @param width Width for the pencil.
33
-     * 
34
-     */
35
-    public void setWidth(int width);
36
-    
37
-    /**
38
-     * Set the pencil color.
39
-     * 
40
-     * @param color Color for the pencil.
41
-     * 
42
-     */
43
-    public void setColor(Color col);
44
-    
45
-    /**
46
-     * Clear the drawing.
47
-     */
48
-	public void clear();
49
-
50
-    /**
51
-     *  Indique les bornes de la fenetre graphique.
52
-     *  Le calcul des coordonnees en pixel se fera automatiquement
53
-     *  a l'appel des methodes drawLine et autres.
54
-     *
55
-     *  @param long1 longitude du bord gauche
56
-     *  @param long2 longitude du bord droit
57
-     *  @param lat1 latitude du bord bas
58
-     *  @param lat2 latitude du bord haut
59
-     *  
60
-     */
61
-    public void setBB(double long1, double long2, double lat1, double lat2);
62
-
63
-    /**
64
-     *  Trace un segment.
65
-     *  @param long1 longitude du premier point
66
-     *  @param lat1 latitude du premier point
67
-     *  @param long2 longitude du second point
68
-     *  @param lat2 latitude du second point
69
-     */
70
-    public void drawLine(float long1, float lat1, float long2, float lat2);
71
-
72
-    /**
73
-     *  Trace un point.
74
-     *  @param lon longitude du point
75
-     *  @param lat latitude du point
76
-     *  @param width grosseur du point
77
-     */
78
-    public void drawPoint(float lon, float lat, int width);
79
-
80
-    /**
81
-     *  Ecrit du texte a la position indiquee.
82
-     *  @param lon longitude du point ou positionner le texte.
83
-     *  @param lat latitude du point ou positionner le texte.
84
-     *  @param txt le texte a ecrire.
85
-     */
86
-    public void putText(float lon, float lat, String txt);
86
+	protected void doAutoPaint() {
87
+		if (autoRepaint) {
88
+			this.repaint();
89
+		}
90
+	}
91
+	
92
+	public void setWidth(int width) {
93
+		this.gr.setStroke(new BasicStroke(width));
94
+	}
95
+
96
+	public void setColor(Color col) {
97
+		this.gr.setColor(col);
98
+	}
99
+
100
+	public void clear() {
101
+		this.gr.setColor(Color.WHITE);
102
+		this.gr.fillRect(0, 0, this.width, this.height);
103
+	}
104
+
105
+	public void setBB(double long1, double long2, double lat1, double lat2) {	
106
+
107
+		if (long1 > long2 || lat1 > lat2) {
108
+			throw new Error("DessinVisible.setBB : mauvaises coordonnees.");
109
+		}
110
+		
111
+		this.long1 = (float)long1;
112
+		this.long2 = (float)long2;
113
+		this.lat1= (float)lat1;
114
+		this.lat2 = (float)lat2;
115
+		
116
+		this.bb_is_set = true;
117
+		
118
+		double scale = 1 / Math.max(this.width / (double)this.getWidth(),  this.height / (double)this.getHeight());
119
+		
120
+		this.zoomAndPanListener.getCoordTransform().setToIdentity();
121
+		this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2, 
122
+				(this.getHeight() - this.height * scale) / 2);
123
+		this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
124
+		this.zoomAndPanListener.setZoomLevel(0);
125
+		this.repaint();
126
+		
127
+	}
128
+
129
+	private int projx(float lon) {
130
+		return (int)(width * (lon - this.long1) / (this.long2 - this.long1)) ;
131
+	}
132
+
133
+	private int projy(float lat) {
134
+		return (int)(height * (1 - (lat - this.lat1) / (this.lat2 - this.lat1))) ;
135
+	}
136
+
137
+	private void checkBB() {
138
+		if (!this.bb_is_set) {
139
+			throw new Error("Classe DessinVisible : vous devez invoquer la methode setBB avant de dessiner.") ;
140
+		}
141
+	}
142
+
143
+	public void drawLine(float long1, float lat1, float long2, float lat2) {
144
+		this.checkBB() ;
145
+		int x1 = this.projx(long1) ;
146
+		int x2 = this.projx(long2) ;
147
+		int y1 = this.projy(lat1) ;
148
+		int y2 = this.projy(lat2) ;
149
+
150
+		gr.drawLine(x1, y1, x2, y2) ;
151
+		this.doAutoPaint();
152
+	}
153
+
154
+	public void drawPoint(float lon, float lat, int width) {
155
+		this.checkBB() ;
156
+		int x = this.projx(lon) - width / 2 ;
157
+		int y = this.projy(lat) - width / 2 ;
158
+		gr.fillOval (x, y, width, width) ;
159
+		this.doAutoPaint();
160
+	}
161
+
162
+	public void putText(float lon, float lat, String txt) {
163
+		this.checkBB() ;
164
+		int x = this.projx(lon) ;
165
+		int y = this.projy(lat) ;
166
+		gr.drawString (txt, x, y) ;
167
+		this.doAutoPaint();	
168
+	}
87 169
 
88 170
 }

Loading…
Cancel
Save