2-APL UPC project.
1package blockworld;
2
3import java.awt.Color;
4import java.awt.Dimension;
5import java.awt.Graphics;
6import java.awt.Point;
7import java.awt.Image;
8import java.awt.image.ImageProducer;
9import java.net.URL;
10import java.net.MalformedURLException;
11import java.io.IOException;
12import java.awt.event.MouseEvent;
13import java.awt.event.MouseListener;
14import java.awt.event.MouseMotionListener;
15import java.util.HashMap;
16import java.util.Map;
17import java.util.Iterator;
18import java.util.Observable;
19import java.util.Observer;
20
21
22import javax.swing.JPanel;
23
24import blockworld.lib.ObsVectListener;
25import blockworld.lib.Signal;
26
27/// Grid view of agent enviroment ('world')
28class EnvView extends JPanel implements ObsVectListener, Observer {
29
30 Map imgMap = new HashMap();
31
32 // Changed SA:
33// String urlPath = "file:/";
34
35 Image imgStone = null;
36// Image imgAgent = null;
37// Image imgHolding = null;
38 Image imgBomb = null;
39 Image imgTrap = null;
40
41 // Changed SA:
42 Image[] imgAgents = new Image[10];
43 Image[] imgAgentsHolding = new Image[10];
44
45 private static final long serialVersionUID = -6981513623481400558L;
46
47 class MouseTool implements MouseListener, MouseMotionListener {
48 Env _env;
49
50 final int STATE_SELECT = 0;
51
52 final int STATE_REMOVE = 1;
53
54 final int STATE_ADDBOMB = 2;
55
56 final int STATE_ADDWALL = 3;
57
58 final int STATE_ADDTRAP = 4;
59
60 int _state = STATE_SELECT;
61
62 public MouseTool( Env env ) {
63 _env = env;
64 }
65
66 protected Point toEnv( MouseEvent e ) {
67 final double cw = getWidth() / _env.getWidth();
68 final double ch = getHeight() / _env.getHeight();
69 final int cx = (int) ((double) e.getX() / cw);
70 final int cy = (int) ((double) e.getY() / ch);
71 return new Point( cx, cy );
72 }
73
74 public void drag( MouseEvent e )
75 {
76 final Point p = toEnv( e );
77
78 // Changed SA: Java is the best option to keep things slow,
79 // to slow things down a bit more we accessively use exceptions.
80 // But we don't want to see them all the time!
81 try
82 {
83 // don't draw on agents
84 if( (_env.isAgent( p ) != null))
85 return;
86
87 switch( _state ) {
88 // add bombs, removing if needed
89 case STATE_ADDBOMB:
90 // Changed SA:
91 if( _env.isStone( p ) != null )
92 _env.removeStone( p );
93
94 if( _env.isTrap( p ) != null )
95 _env.removeTrap( p );
96
97 _env.addBomb( p );
98 break;
99
100 // add walls, removing if needed
101 case STATE_ADDWALL:
102 if( _env.isBomb( p ) != null )
103 _env.removeBomb( p );
104
105 if( _env.isTrap( p ) != null )
106 _env.removeTrap( p );
107
108 _env.addStone( p );
109 break;
110
111 // add traps, removing if needed
112 case STATE_ADDTRAP:
113 if( _env.isBomb( p ) != null )
114 _env.removeBomb( p );
115
116 // Changed SA:
117 if( _env.isStone( p ) != null )
118 _env.removeStone( p );
119
120 _env.addTrap( p );
121 break;
122
123 // remove all
124 case STATE_REMOVE:
125 // Changed SA:
126 if( _env.isStone( p ) != null)
127 _env.removeStone( p );
128
129 if( _env.isBomb( p ) != null )
130 _env.removeBomb( p );
131
132 if( _env.isTrap( p ) != null )
133 _env.removeTrap( p );
134 break;
135 }
136 }
137 catch (Exception error){ /* Ignore this*/}
138 }
139
140 // Changed SA:
141 public void start( MouseEvent e )
142 {
143 final Point p = toEnv( e );
144
145 try
146 {
147 if (_state == STATE_SELECT)
148 { // Try to select an agent
149 // if it's an agent, change selected agent
150 final Agent a = _env.isAgent(p);
151 if (a != null)
152 {
153 _selectedAgent = (a != _selectedAgent) ? a : null;
154 signalSelectionChanged.emit();
155 repaint();
156// _state = STATE_SELECT;
157 }
158 }
159 else
160 { // Place the selected object (or erase when chosen)
161 drag(e);
162 }
163
164
165/*
166 // if it's a stone, make it a bomb
167 if (_env.senseStone( p ) != null)
168 {
169 _env.removeStone( p );
170 _env.addBomb( p );
171 _state = STATE_ADDBOMB;
172 return;
173 }
174
175 // if it's a bomb, make it a trap
176 if( _env.senseBomb( p ) != null )
177 {
178 _env.removeBomb( p );
179 _env.addTrap( p );
180 _state = STATE_ADDTRAP;
181 return;
182 }
183
184 // if it's a trap, remove it
185 if( _env.senseTrap( p ) != null )
186 {
187 _env.removeTrap( p );
188 _state = STATE_REMOVE;
189 return;
190 }
191
192 // it's a empty spot, so add a stone
193 _env.addStone( p );
194 _state = STATE_ADDWALL;
195*/
196 }
197 catch( Exception error )
198 {
199 // ignore error
200 }
201 }
202
203 public void mouseClicked( MouseEvent arg0 ) {
204 }
205
206 public void mouseEntered( MouseEvent arg0 ) {
207 }
208
209 public void mouseExited( MouseEvent arg0 ) {
210 }
211
212 public void mousePressed( MouseEvent arg0 ) {
213 start( arg0 );
214 }
215
216 public void mouseReleased( MouseEvent arg0 ) {
217 }
218
219 public void mouseDragged( MouseEvent arg0 ) {
220 drag( arg0 );
221 }
222
223 public void mouseMoved( MouseEvent arg0 ) {
224 }
225 };
226
227 protected Env _env;
228
229 double _cw = 10;
230
231 double _ch = 10;
232
233 public Signal signalSelectionChanged = new Signal( "Selected agent changed" );
234
235 // Changed SA: We need something to indicate the window (static and env) that the agent has moved.
236 // We cannot use an agent for this because they are not created in the beginnning
237// public Signal signalRefresh = new Signal( "Refresh of screen" );
238
239 protected Agent _selectedAgent = null;
240
241 public MouseTool tool;
242
243 EnvView( Env env ) {
244 _env = env;
245
246 // Changed SA:
247 /*
248 try {
249 String rawUserDir = System.getProperty("user.dir");
250 String procUserDir = rawUserDir.replaceAll("\\\\","/");
251 int pathLen = procUserDir.length();
252 urlPath = urlPath + procUserDir + "/plugins/BlockWorld/";
253 System.out.println("Pictogramomslag: "+urlPath);
254 } catch(Exception xEx) {
255 xEx.printStackTrace();
256 }
257 */
258
259
260
261 try
262 {
263 // Changed SA:
264 imgStone = createImage((ImageProducer)(this.getClass().getResource("images/stone.gif")).getContent());
265 } catch(Exception xEx) {
266 xEx.printStackTrace();
267 }
268
269
270
271 try
272 {
273 // Changed SA:
274 imgAgents[0] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_army.gif")).getContent());
275 imgAgents[1] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_blue.gif")).getContent());
276 imgAgents[2] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_gray.gif")).getContent());
277 imgAgents[3] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_green.gif")).getContent());
278 imgAgents[4] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_orange.gif")).getContent());
279 imgAgents[5] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_pink.gif")).getContent());
280 imgAgents[6] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_purple.gif")).getContent());
281 imgAgents[7] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_red.gif")).getContent());
282 imgAgents[8] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_teal.gif")).getContent());
283 imgAgents[9] = createImage((ImageProducer)(this.getClass().getResource("images/agents/agent_yellow.gif")).getContent());
284 }
285 catch(Exception xEx)
286 {
287 xEx.printStackTrace();
288 }
289
290
291 try
292 {
293 // Changed SA:
294 imgAgentsHolding[0] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_army.gif")).getContent());
295 imgAgentsHolding[1] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_blue.gif")).getContent());
296 imgAgentsHolding[2] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_gray.gif")).getContent());
297 imgAgentsHolding[3] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_green.gif")).getContent());
298 imgAgentsHolding[4] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_orange.gif")).getContent());
299 imgAgentsHolding[5] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_pink.gif")).getContent());
300 imgAgentsHolding[6] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_purple.gif")).getContent());
301 imgAgentsHolding[7] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_red.gif")).getContent());
302 imgAgentsHolding[8] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_teal.gif")).getContent());
303 imgAgentsHolding[9] = createImage((ImageProducer)(this.getClass().getResource("images/agents/holding_yellow.gif")).getContent());
304 } catch(Exception xEx) {
305 xEx.printStackTrace();
306 }
307
308 try
309 {
310 // Changed SA:
311 imgBomb = createImage((ImageProducer)(this.getClass().getResource("images/bomb.gif")).getContent());
312 } catch(Exception xEx) {
313 xEx.printStackTrace();
314 }
315
316 try
317 {
318 // Changed SA:
319 imgTrap = createImage((ImageProducer)(this.getClass().getResource("images/trap.gif")).getContent());
320 } catch(Exception xEx) {
321 xEx.printStackTrace();
322 }
323
324 _env.addAgentListener( new ObsVectListener()
325 {
326 public void onAdd( int i, Object o )
327 {
328 final Agent a = (Agent) o;
329 a.signalDropBomb.addObserver( EnvView.this );
330 a.signalPickupBomb.addObserver( EnvView.this );
331 a.signalMove.addObserver( EnvView.this );
332 repaint();
333 }
334
335 public void onRemove( int i, Object o ) {
336 final Agent a = (Agent) o;
337 a.signalDropBomb.deleteObserver( EnvView.this );
338 a.signalPickupBomb.deleteObserver( EnvView.this );
339 a.signalMove.deleteObserver( EnvView.this );
340 repaint();
341 }
342 } );
343
344 // repaint on changes in stones, size,
345 _env.addStonesListener( this );
346 _env.addBombsListener( this );
347 _env.addTrapsListener( this );
348 _env.signalSenseRangeChanged.addObserver( this );
349 _env.signalSizeChanged.addObserver( this );
350 _env.signalTrapChanged.addObserver( this );
351
352 // track mouse events
353 tool = new MouseTool( _env );
354 addMouseListener( tool );
355 addMouseMotionListener( tool );
356
357 }
358
359
360 public Dimension getPreferredSize() {
361 return new Dimension( _env.getWidth() * (int) _cw, _env.getHeight()
362 * (int) _ch );
363 }
364
365 // / \todo fix size stuff, it's now done incorrectly (use 100 * 100 grid to
366 // / see result). this is because the way casting is done (doubles converted
367 // / to int before use, instead of afterwards)
368 protected void paintComponent( Graphics g ) {
369 super.paintComponent( g );
370
371 final double cw = getWidth() / _env.getWidth();
372 final double ch = getHeight() / _env.getHeight();
373
374 // clear
375 g.setColor( Color.white );
376 g.fillRect( 0, 0, getWidth(), getHeight() );
377
378 // draw grid contents + lines
379 for( double x = 0; x < _env.getWidth(); x++ )
380 for( double y = 0; y < _env.getHeight(); y++ ) {
381 final Point p = new Point( (int) x, (int) y );
382
383 // draw stone (blue square)
384 // Changed SA
385 if( _env.isStone( p ) != null ) {
386 if(imgStone == null) {
387 g.setColor( Color.blue );
388 g.fillRect( (int) (x * cw), (int) (y * ch), (int) cw,
389 (int) ch );
390 } else {
391 g.drawImage(imgStone, (int) (x * cw + 1), (int) (y * ch + 1), (int) cw - 1,
392 (int) ch - 1, this);
393 }
394 }
395
396 // draw bomb (red oval)
397 TypeObject bomb = null;
398 if( (bomb = _env.isBomb( p )) != null )
399 {
400 // Changed SA: there's only one type of bomb!
401 /*
402 if(!imgMap.containsKey("bomb_"+bomb.getType())) {
403 try {
404 imgMap.put(("bomb_"+bomb.getType()),createImage((ImageProducer)(
405 new URL(urlPath+"bomb_"+bomb.getType()+".gif")).getContent()));
406 System.out.println("Type ["+bomb.getType()+"] bomb icon found");
407 } catch(Exception xEx) {
408 xEx.printStackTrace();
409 imgMap.put(("bomb_"+bomb.getType()),null);
410 }
411 }
412 if(imgMap.get("bomb_"+bomb.getType()) != null) {
413 g.drawImage((Image) imgMap.get("bomb_"+bomb.getType()),
414 (int) (x * cw + 1), (int) (y * ch + 1), (int) cw - 1,
415 (int) ch - 1, this);
416 } else*/
417 if(imgBomb != null)
418 {
419 g.drawImage(imgBomb, (int)(x*cw + 1), (int)(y*ch + 1), (int)(cw-1), (int)(ch-1), this);
420 }
421 else
422 {
423 g.setColor(Color.red);
424 g.fillOval((int)(x*cw), (int)(y*ch), (int)cw, (int)ch);
425 }
426 }
427
428 // draw trap (orange square)
429 TypeObject trap = null;
430 if( (trap = _env.isTrap( p )) != null )
431 {
432 // Changed SA: there's only one type of trap!
433 /*
434 if(!imgMap.containsKey("trap_"+trap.getType())) {
435 try {
436 imgMap.put(("trap_"+trap.getType()),createImage((ImageProducer)(
437 new URL(urlPath+"trap_"+trap.getType()+".gif")).getContent()));
438 System.out.println("Type ["+trap.getType()+"] trap icon found");
439 } catch(Exception xEx) {
440 xEx.printStackTrace();
441 imgMap.put(("trap_"+trap.getType()),null);
442 }
443 }
444 if(imgMap.get("trap_"+trap.getType()) != null) {
445 g.drawImage((Image) imgMap.get("trap_"+trap.getType()),
446 (int) (x * cw + 1), (int) (y * ch + 1), (int) cw - 1,
447 (int) ch - 1, this);
448 } else*/
449 if(imgTrap != null)
450 {
451 g.drawImage(imgTrap, (int)(x*cw + 1), (int)(y*ch + 1), (int)(cw-1),(int)(ch-1), this);
452 }
453 else
454 {
455 g.setColor(Color.orange);
456 g.fillRect((int)(x*cw), (int)(y*ch), (int)cw, (int)ch);
457 }
458 }
459 // draw gridline
460 g.setColor( Color.gray );
461 g.drawRect( (int) (x * cw), (int) (y * ch), (int) cw, (int) ch );
462 }
463
464 Iterator a = _env.getBlockWorldAgents().iterator();
465 while( a.hasNext() ) {
466 final Agent agent = (Agent) a.next();
467
468 // skip agents not entered in the world
469 if( !agent.isEntered() )
470 continue;
471
472 // Changed SA: don't know what this is for, do know it's giving a lot of exceptions
473 // Seems like you can use a custom picture
474 /*if(!imgMap.containsKey("agent_"+agent.getName())) {
475 try {
476 imgMap.put(("agent_"+agent.getName()),createImage((ImageProducer)(
477 new URL(urlPath+"agent_"+agent.getName()+".gif")).getContent()));
478 System.out.println("Unloaded agent ["+agent.getName()+"] icon found");
479 } catch(Exception xEx) {
480 xEx.printStackTrace();
481 imgMap.put(("agent_"+agent.getName()),null);
482 }
483 }
484
485 if(!imgMap.containsKey("holding_"+agent.getName())) {
486 try {
487 imgMap.put(("holding_"+agent.getName()),createImage((ImageProducer)(
488 new URL(urlPath+"holding_"+agent.getName()+".gif")).getContent()));
489 System.out.println("Loaded agent ["+agent.getName()+"] icon found");
490 } catch(Exception xEx) {
491 xEx.printStackTrace();
492 imgMap.put(("holding_"+agent.getName()),null);
493 }
494 }*/
495
496 // draw agent position
497 final Point p = agent.getPosition();
498 final int x = (int) ((double) p.x * cw);
499 final int y = (int) ((double) p.y * ch);
500 if (agent.senseBomb() != null)
501 {
502 // Changed SA: there's only one type of agent holding a bomb!
503 /*
504 if(imgMap.get("holding_"+agent.getName()) != null) {
505 g.drawImage((Image) imgMap.get("holding_"+agent.getName()),
506 x + 1, y + 1, (int) cw - 1,(int) ch - 1, this);
507 } else*/
508 if(imgAgentsHolding[agent._colorID] != null)
509 {
510 g.drawImage(imgAgentsHolding[agent._colorID], x+1, y+1, (int)(cw-1), (int)(ch-1), this);
511 }
512 else
513 {
514 g.setColor((agent != _selectedAgent) ? Color.green : Color.green.darker());
515 g.fillRect(x+1, y+1, (int)(cw-1), (int)(ch-1));
516 g.setColor(Color.black );
517 g.drawRect(x+2, y+2, 3, 3);
518 }
519 }
520 else
521 {
522 // Changed SA: there are 10 agents to choose from!
523 /*
524 if(imgMap.get("agent_"+agent.getName()) != null) {
525 g.drawImage((Image) imgMap.get("agent_"+agent.getName()),
526 x + 1, y + 1, (int) cw - 1,(int) ch - 1, this);
527 }
528 else*/
529 if(imgAgents[agent._colorID] != null)
530 {
531 g.drawImage(imgAgents[agent._colorID], x+1, y+1, (int)(cw-1), (int)(ch-1), this);
532 }
533 else
534 {
535 g.setColor((agent != _selectedAgent) ? Color.green : Color.green.darker());
536 g.fillRect(x+1, y+1, (int)(cw-1), (int)(ch-1));
537 }
538 }
539
540 // draw sensing range
541 final int rw = (int) ((double) _env.getSenseRange() * cw);
542 final int rh = (int) ((double) _env.getSenseRange() * ch);
543 g.setColor( Color.blue );
544 g.drawOval( x - (rw), y - (rh), rw * 2, rh * 2 );
545 }
546 }
547
548 public void onRemove( int i, Object o ) {
549 repaint();
550 }
551
552 public void onAdd( int i, Object o ) {
553 repaint();
554 }
555
556 public void update( Observable o, Object arg ) {
557 repaint();
558 // Changed SA: we need some sort of event to indicate to our window we want
559 // it to update its screen
560 // signalRefresh.emit();
561 }
562
563 public Agent getSelectedAgent() {
564 return _selectedAgent;
565 }
566
567 public Env getEnv() {
568 return _env;
569 }
570
571}