Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/javathis/mapeditor/PagedMap.java


1   /**
2    * JTMapEditor - The Pure Java Map Editor
3    * Copyright(c) 2002 by Rodney S. Foley
4    * <pre>
5    * This library is free software; you can redistribute it and/or modify it under
6    * the terms of the GNU Lesser General Public License as published by the Free
7    * Software Foundation; either version 2.1 of the License, or (at your option)
8    * any later version.
9    *
10   * This library is distributed in the hope that it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
13   * more details.
14   *
15   * You should have received a copy of the GNU Library General Public License
16   * along with this library; if not, write to:
17   *
18   * Free Software Foundation, Inc.
19   * 59 Temple Place, Suite 330
20   * Boston, MA  02111-1307, USA
21   *
22   * or download it from:  http://www.fsf.org/licenses/licenses.html#LGPL
23   * </pre>
24   */
25  package com.javathis.mapeditor;
26  
27  import com.javathis.utilities.pagedArray.*;
28  import com.javathis.utilities.ui.*;
29  import java.awt.*;
30  import java.awt.event.*;
31  import java.awt.font.*;
32  import java.awt.geom.*;
33  import java.awt.image.*;
34  import java.io.*;
35  import java.text.*;
36  import java.util.*;
37  import javax.swing.*;
38  import javax.swing.border.*;
39  import javax.swing.event.*;
40  
41  /**
42   * The map panel that contains the canvas that the map is created on.  Uses a
43   * <code>JTPagedArray</code> to store the map data set.
44   */
45  public class PagedMap extends JPanel implements ComponentListener, AdjustmentListener, MouseWheelListener
46  {
47      private int tileSize;
48      private int mapWidth;
49      private int mapHeight;
50      private int lastMapWidth;
51      private int lastMapHeight;
52      private int defaultTileIndex;
53      private int viewTileOriginX;
54      private int viewTileOriginY;
55      private int adjustedViewWidth   = -1;
56      private int adjustedViewHeight  = -1;
57  
58      private boolean createBuffer            = true;
59      private boolean showGrid                = false;
60      private boolean showTraverseRating      = false;
61      private boolean clearMapView            = false;
62      private boolean mapUpdating             = false;
63      private boolean viewTileOriginChanged   = false;
64      private boolean isNewMap                = false;
65      private boolean isDirty                 = false;
66  
67  
68      private MapCanvas       mapCanvas = new MapCanvas();
69      private TileSet         tileSet;
70      private JTPagedArray    mapTiles;
71      private Graphics2D      bsG2D;
72      private BufferStrategy  bStrategy;
73  
74      private Vector stateChangeListeners = new Vector();
75  
76      private JPanel      horizontalScrollPanel   = new JPanel();
77      private JLabel      cornerSpacer            = new JLabel();
78      private JScrollBar  verticalScrollBar       = new JScrollBar(JScrollBar.VERTICAL);
79      private JScrollBar  horizontalScrollBar     = new JScrollBar(JScrollBar.HORIZONTAL);
80  
81      private JTStatusBar statusBar;
82      private EditFrame   editFrame;
83  
84      public PagedMap(TileSet tileSet, int mapWidth, int mapHeight, int tileSize, int defaultTileIndex, EditFrame editFrame)
85      {
86          this.tileSet            = tileSet;
87          this.mapWidth           = mapWidth;
88          this.mapHeight          = mapHeight;
89          this.tileSize           = tileSize;
90          this.defaultTileIndex   = defaultTileIndex;
91          this.viewTileOriginX    = 0;
92          this.viewTileOriginY    = 0;
93          this.editFrame          = editFrame;
94          this.statusBar          = editFrame.getStatusBar();
95          this.lastMapWidth       = this.mapWidth;
96          this.lastMapHeight      = this.mapHeight;
97  
98          this.verticalScrollBar.setMinimum(0);
99          this.verticalScrollBar.setMaximum((int)this.mapHeight-1);
100         this.horizontalScrollBar.setMinimum(0);
101         this.horizontalScrollBar.setMaximum((int)this.mapWidth-1);
102 
103         guiInit();
104         registerEvents();
105         initMap();
106 
107         clearMapView = true;
108         repaint();
109 
110         fireStateChanged();
111     }
112 
113     public void addChangeListener(ChangeListener listener)
114     {
115         stateChangeListeners.add(listener);
116     }
117 
118     public void removeChangeListener(ChangeListener listener)
119     {
120         stateChangeListeners.remove(listener);
121     }
122 
123     public void addMouseListener(MouseListener listener)
124     {
125         mapCanvas.addMouseListener(listener);
126     }
127 
128     public void removeMouseListener(MouseListener listener)
129     {
130         mapCanvas.removeMouseListener(listener);
131     }
132 
133     public void addMouseMotionListener(MouseMotionListener listener)
134     {
135         mapCanvas.addMouseMotionListener(listener);
136     }
137 
138     public void removeMouseMotionListener(MouseMotionListener listener)
139     {
140         mapCanvas.removeMouseMotionListener(listener);
141     }
142 
143     public void addKeyListener(KeyListener listener)
144     {
145         mapCanvas.addKeyListener(listener);
146     }
147 
148     public void removeKeyListener(KeyListener listener)
149     {
150         mapCanvas.removeKeyListener(listener);
151     }
152 
153     public void addComponentListener(ComponentListener listener)
154     {
155         mapCanvas.addComponentListener(listener);
156     }
157 
158     public void removeComponentListener(ComponentListener listener)
159     {
160         mapCanvas.removeComponentListener(listener);
161     }
162 
163     public int getMapWidth()
164     {
165         return mapWidth;
166     }
167 
168     public int getMapHeight()
169     {
170         return mapHeight;
171     }
172 
173     public int getViewWidth()
174     {
175         if (adjustedViewWidth < 0)
176             adjustedViewWidth = (getWidth()/tileSize)*tileSize;
177 
178         return adjustedViewWidth;
179     }
180 
181     public int getViewHeight()
182     {
183         if (adjustedViewHeight < 0)
184             adjustedViewHeight = (getHeight()/tileSize)*tileSize;
185 
186         return adjustedViewHeight;
187     }
188 
189     public int getViewTileOriginX()
190     {
191         return viewTileOriginX;
192     }
193 
194     public int getViewTileOriginY()
195     {
196         return viewTileOriginY;
197     }
198 
199     public void setViewTileOrigin(int x, int y)
200     {
201         viewTileOriginX = x;
202         viewTileOriginY = y;
203         viewTileOriginChanged = true;
204         fireStateChanged();
205     }
206 
207     public boolean isDirty()
208     {
209         return isDirty;
210     }
211 
212     public void setTile(Tile tile, int x, int y)
213     {
214         if (tile != null && 0 <= viewTileOriginX + x && viewTileOriginX + x < (mapWidth * mapHeight)/mapHeight && 0 <= viewTileOriginY + y && viewTileOriginY + y < (mapWidth * mapHeight)/mapWidth)
215         {
216             long index = ((long)viewTileOriginY + (long)y) * (long)mapWidth + ((long)viewTileOriginX + (long)x);
217             PagedTile currentTile = new PagedTile();
218 
219             currentTile.setColumn(viewTileOriginX + x);
220             currentTile.setRow(viewTileOriginY + y);
221             currentTile.setTileSetIndex(tile.getTileSetIndex());
222             currentTile.setTraverseRating(tile.getTraverseRating());
223             currentTile.setValid(true);
224 
225             mapTiles.setPagedElementAt(index, currentTile);
226 
227             isDirty = true;
228 
229             repaint();
230             fireStateChanged();
231         }
232     }
233 
234     public void setTile(PagedTile tile, int x, int y)
235     {
236         if (tile != null && 0 <= viewTileOriginX + x && viewTileOriginX + x < (mapWidth * mapHeight)/mapHeight && 0 <= viewTileOriginY + y && viewTileOriginY + y < (mapWidth * mapHeight)/mapWidth)
237         {
238             long index = ((long)viewTileOriginY + (long)y) * (long)mapWidth + ((long)viewTileOriginX + (long)x);
239 
240             mapTiles.setPagedElementAt(index, tile);
241             isDirty = true;
242 
243             fireStateChanged();
244         }
245     }
246 
247     public PagedTile getTile(int x, int y)
248     {
249         PagedTile currentTile = null;
250 
251         if (!mapUpdating && 0 <= viewTileOriginX + x && viewTileOriginX + x < (mapWidth * mapHeight)/mapHeight && 0 <= viewTileOriginY + y && viewTileOriginY + y < (mapWidth * mapHeight)/mapWidth)
252         {
253             currentTile = new PagedTile();
254 
255             long index = ((long)viewTileOriginY + (long)y) * (long)mapWidth + ((long)viewTileOriginX + (long)x);
256             mapTiles.getPagedElementAt(index, currentTile);
257 
258             if (!currentTile.isValid())
259             {
260                 currentTile.setColumn(viewTileOriginX + x);
261                 currentTile.setRow(viewTileOriginY + y);
262                 currentTile.setTileSetIndex(defaultTileIndex);
263                 currentTile.setTraverseRating(tileSet.getTile(defaultTileIndex).getTraverseRating());
264                 currentTile.setValid(true);
265 
266                 mapTiles.setPagedElementAt(index, currentTile);
267             }
268         }
269 
270          return currentTile;
271     }
272 
273     public void resetBuffer()
274     {
275             bStrategy = mapCanvas.getBufferStrategy();
276             bsG2D = (Graphics2D)bStrategy.getDrawGraphics();
277 
278             bsG2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
279             bsG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
280             bsG2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
281     }
282 
283     public void showGrid(boolean showGrid)
284     {
285         this.showGrid = showGrid;
286         mapCanvas.repaint();
287 
288         fireStateChanged();
289     }
290 
291     public boolean showGrid()
292     {
293         return showGrid;
294     }
295 
296     public void showTraverseRating(boolean showTraverseRating)
297     {
298         this.showTraverseRating = showTraverseRating;
299         mapCanvas.repaint();
300 
301         fireStateChanged();
302     }
303 
304     public boolean showTaverseRating()
305     {
306         return showTraverseRating;
307     }
308 
309     public void componentResized(ComponentEvent event)
310     {
311         adjustedViewWidth = (getWidth()/tileSize)*tileSize;
312         adjustedViewHeight = (getHeight()/tileSize)*tileSize;
313 
314         verticalScrollBar.setValues(0, adjustedViewHeight/tileSize, 0, (int)mapHeight-1);
315         horizontalScrollBar.setValues(0, adjustedViewWidth/tileSize , 0, (int)mapWidth-1);
316     }
317 
318     public void componentMoved(ComponentEvent event) {}
319 
320     public void componentShown(ComponentEvent event)
321     {
322         adjustedViewWidth = (getWidth()/tileSize)*tileSize;
323         adjustedViewHeight = (getHeight()/tileSize)*tileSize;
324 
325         verticalScrollBar.setValues(0, adjustedViewHeight/tileSize, 0, (int)mapHeight-1);
326         horizontalScrollBar.setValues(0, adjustedViewWidth/tileSize , 0, (int)mapWidth-1);
327     }
328 
329     public void componentHidden(ComponentEvent event) {}
330 
331     public void adjustmentValueChanged(AdjustmentEvent event)
332     {
333         switch (((JScrollBar)event.getSource()).getOrientation())
334         {
335             case JScrollBar.VERTICAL:
336                 setViewTileOrigin(viewTileOriginX, event.getValue());
337                 break;
338             case JScrollBar.HORIZONTAL:
339                 setViewTileOrigin(event.getValue(), viewTileOriginY);
340                 break;
341         }
342 
343         repaint();
344     }
345 
346     public void mouseWheelMoved(MouseWheelEvent event)
347     {
348         verticalScrollBar.setValue(verticalScrollBar.getValue() + event.getUnitsToScroll());
349     }
350 
351     protected void toFile(final File outputFile) throws IOException, FileNotFoundException
352     {
353         synchronized(editFrame.getMutex())
354         {
355             editFrame.setBusy(true);
356 
357             statusBar.setProgressVisible(true);
358             statusBar.setProgressMin(0);
359             statusBar.setProgressMax((int)(mapWidth*mapHeight+11));
360             statusBar.setProgressValue(0);
361 
362             try
363             {
364                 RandomAccessFile raFileOut = new RandomAccessFile(outputFile, "rw");
365                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
366                 raFileOut.writeInt(tileSize);
367                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
368                 raFileOut.writeInt(mapWidth);
369                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
370                 raFileOut.writeInt(mapHeight);
371                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
372                 raFileOut.writeInt(defaultTileIndex);
373                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
374                 raFileOut.writeInt(viewTileOriginX);
375                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
376                 raFileOut.writeInt(viewTileOriginY);
377                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
378                 raFileOut.writeBoolean(showGrid);
379                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
380 
381                 PagedTile currentTile = new PagedTile();
382                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
383                 final int DEFAULT_TRAVERSE_RATING = tileSet.getTile(defaultTileIndex).getTraverseRating();
384                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
385 
386                 for (int x = 0; x < mapWidth; x++)
387                     for (int y = 0; y < mapHeight; y++)
388                     {
389                         long index = (long)y * (long)mapWidth + (long)x;
390 
391                         mapTiles.getPagedElementAt(index, currentTile);
392 
393                         if (!currentTile.isValid())
394                         {
395                             raFileOut.writeInt(x);
396                             raFileOut.writeInt(y);
397                             raFileOut.writeInt(defaultTileIndex);
398                             raFileOut.writeInt(DEFAULT_TRAVERSE_RATING);
399                         }
400                         else
401                         {
402                             raFileOut.writeInt(currentTile.getColumn());
403                             raFileOut.writeInt(currentTile.getRow());
404                             raFileOut.writeInt(currentTile.getTileSetIndex());
405                             raFileOut.writeInt(currentTile.getTraverseRating());
406                         }
407 
408                         statusBar.setProgressValue(statusBar.getProgressValue() + 1);
409                     }
410 
411                 raFileOut.close();
412                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
413             }
414             catch (Exception e)
415             {
416                 e.printStackTrace();
417                 JOptionPane.showMessageDialog(editFrame, e.getMessage(), e.getClass().toString(), JOptionPane.ERROR_MESSAGE);
418             }
419 
420             statusBar.setProgressVisible(false);
421             editFrame.getMutex().notifyAll();
422 
423             editFrame.setBusy(true);
424         }
425 
426     }
427 
428     protected void paintComponent(Graphics g)
429     {
430         if (getWidth() > 0 && getHeight() > 0)
431             mapCanvas.update(g);
432     }
433 
434     /**
435      * Sends a ChangeEvent, whose source is this Map, to each ChangeListener.
436      */
437     protected void fireStateChanged()
438     {
439         if (stateChangeListeners != null && 0 < stateChangeListeners.size())
440             for (int i = 0; i < stateChangeListeners.size(); i++)
441                 ((ChangeListener)stateChangeListeners.get(i)).stateChanged(new ChangeEvent(this));
442     }
443 
444     protected void newMap(final int mapWidth, final int mapHeight)
445     {
446         synchronized(editFrame.getMutex())
447         {
448             editFrame.setBusy(true);
449             mapUpdating = true;
450 
451             this.tileSet            = MapEditor.DEFAULT_TILE_SET;
452             this.mapWidth           = mapWidth;
453             this.mapHeight          = mapHeight;
454             this.tileSize           = tileSet.getTileWidth();
455             this.defaultTileIndex   = tileSet.getDefaultTileIndex();
456             this.viewTileOriginX    = 0;
457             this.viewTileOriginY    = 0;
458             this.editFrame          = editFrame;
459             this.statusBar          = editFrame.getStatusBar();
460             this.lastMapWidth       = this.mapWidth;
461             this.lastMapHeight      = this.mapHeight;
462 
463             this.verticalScrollBar.setMinimum(0);
464             this.verticalScrollBar.setMaximum((int)this.mapHeight-1);
465             this.horizontalScrollBar.setMinimum(0);
466             this.horizontalScrollBar.setMaximum((int)this.mapWidth-1);
467 
468             guiInit();
469             registerEvents();
470             initMap();
471 
472             clearMapView = true;
473             repaint();
474 
475             fireStateChanged();
476 
477             this.lastMapWidth   = this.mapWidth;
478             this.lastMapHeight  = this.mapHeight;
479             this.mapWidth       = mapWidth;
480             this.mapHeight      = mapHeight;
481             this.viewTileOriginX = 0;
482             this.viewTileOriginY = 0;
483 
484             this.verticalScrollBar.setMinimum(0);
485             this.verticalScrollBar.setMaximum((int)mapHeight-1);
486 
487             this.horizontalScrollBar.setMinimum(0);
488             this.horizontalScrollBar.setMaximum((int)mapWidth-1);
489 
490             this.initMap();
491             this.clearMapView = true;
492             mapUpdating = false;
493 
494             editFrame.getMutex().notifyAll();
495 
496             editFrame.setBusy(false);
497             this.repaint();
498             fireStateChanged();
499 
500         }
501     }
502 
503     protected void newMap(final File inputFile, final TileSet tileSet) throws IOException, FileNotFoundException
504     {
505         synchronized(editFrame.getMutex())
506         {
507             editFrame.setBusy(true);
508             mapUpdating = true;
509 
510             statusBar.setProgressVisible(true);
511             statusBar.setProgressMin(0);
512             statusBar.setProgressMax((int)(mapWidth*mapHeight+16));
513             statusBar.setProgressValue(0);
514 
515             try
516             {
517                 PagedMap.this.tileSet = tileSet;
518                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
519                 PagedMap.this.lastMapWidth   = PagedMap.this.mapWidth;
520                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
521                 PagedMap.this.lastMapHeight  = PagedMap.this.mapHeight;
522                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
523 
524                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
525 
526                 RandomAccessFile raFileIn = new RandomAccessFile(inputFile, "r");
527                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
528 
529                 PagedMap.this.tileSize = raFileIn.readInt();
530                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
531                 PagedMap.this.mapWidth = raFileIn.readInt();
532                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
533                 PagedMap.this.mapHeight = raFileIn.readInt();
534                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
535                 PagedMap.this.defaultTileIndex = raFileIn.readInt();
536                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
537                 PagedMap.this.viewTileOriginX = raFileIn.readInt();
538                 PagedMap.this.viewTileOriginX = raFileIn.readInt();
539                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
540                 PagedMap.this.showGrid = raFileIn.readBoolean();
541                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
542                 PagedMap.this.initMap();
543                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
544 
545                 PagedMap.this.guiInit();
546                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
547                 PagedMap.this.registerEvents();
548                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
549 
550                 PagedTile currentTile = new PagedTile();
551                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
552 
553                 for (long x = 0; x < mapWidth; x++)
554                     for (long y = 0; y < mapHeight; y++)
555                     {
556                         long index = (long)y * (long)mapWidth + (long)x;
557 
558                         currentTile.setColumn(raFileIn.readInt());
559                         currentTile.setRow(raFileIn.readInt());
560                         currentTile.setTileSetIndex(raFileIn.readInt());
561                         currentTile.setTraverseRating(raFileIn.readInt());
562                         currentTile.setValid(true);
563 
564                         if (currentTile.getTileSetIndex() != defaultTileIndex)
565                             SwingUtilities.invokeAndWait(new  TileLoader(index, currentTile));
566 
567                         statusBar.setProgressValue(statusBar.getProgressValue() + 1);
568                     }
569 
570                 raFileIn.close();
571                 statusBar.setProgressValue(statusBar.getProgressValue() + 1);
572                 mapUpdating = false;
573             }
574             catch (Exception e)
575             {
576                 e.printStackTrace();
577                 JOptionPane.showMessageDialog(editFrame, e.getMessage(), e.getClass().toString(), JOptionPane.ERROR_MESSAGE);
578                 mapUpdating = false;
579             }
580 
581             statusBar.setProgressVisible(false);
582             editFrame.getMutex().notifyAll();
583 
584             editFrame.setBusy(false);
585             PagedMap.this.repaint();
586             fireStateChanged();
587         }
588     }
589 
590     protected void newMap(final TileSet tileSet, final int mapWidth, final int mapHeight, final int tileSize, final int defaultTileIndex) throws IOException, FileNotFoundException
591     {
592         synchronized(editFrame.getMutex())
593         {
594             editFrame.setBusy(true);
595             mapUpdating = true;
596 
597             this.tileSet            = tileSet;
598             this.mapWidth           = mapWidth;
599             this.mapHeight          = mapHeight;
600             this.tileSize           = tileSize;
601             this.defaultTileIndex   = defaultTileIndex;
602             this.viewTileOriginX    = 0;
603             this.viewTileOriginY    = 0;
604             this.editFrame          = editFrame;
605             this.statusBar          = editFrame.getStatusBar();
606             this.lastMapWidth       = this.mapWidth;
607             this.lastMapHeight      = this.mapHeight;
608 
609             this.verticalScrollBar.setMinimum(0);
610             this.verticalScrollBar.setMaximum((int)this.mapHeight-1);
611             this.horizontalScrollBar.setMinimum(0);
612             this.horizontalScrollBar.setMaximum((int)this.mapWidth-1);
613 
614             initMap();
615             guiInit();
616 
617             PagedTile currentTile = new PagedTile();
618 
619             clearMapView = true;
620             mapUpdating = false;
621 
622             editFrame.getMutex().notifyAll();
623 
624             editFrame.setBusy(false);
625             this.repaint();
626             fireStateChanged();
627         }
628     }
629 
630     private void guiInit()
631     {
632         cornerSpacer.setPreferredSize(new Dimension(15, 15));
633         cornerSpacer.setBorder(new SoftBevelBorder(SoftBevelBorder.LOWERED));
634         horizontalScrollPanel.setLayout(new BorderLayout());;
635         horizontalScrollPanel.add(horizontalScrollBar, BorderLayout.CENTER);
636         horizontalScrollPanel.add(cornerSpacer, BorderLayout.EAST);
637 
638         this.setLayout(new BorderLayout());
639         this.add(mapCanvas, BorderLayout.CENTER);
640         this.add(verticalScrollBar, BorderLayout.EAST);
641         this.add(horizontalScrollPanel, BorderLayout.SOUTH);
642 
643         verticalScrollBar.setMinimum(0);
644         verticalScrollBar.setMaximum((int)mapHeight-1);
645 
646         horizontalScrollBar.setMinimum(0);
647         horizontalScrollBar.setMaximum((int)mapWidth-1);
648     }
649 
650     private void registerEvents()
651     {
652         verticalScrollBar.addAdjustmentListener(this);
653         horizontalScrollBar.addAdjustmentListener(this);
654         addComponentListener(this);
655 
656         mapCanvas.addMouseWheelListener(this);
657     }
658 
659     private void initMap()
660     {
661         mapTiles = new JTPagedArray((long)mapWidth * (long)mapHeight, PagedTile.getPagedTileDetails());
662         CacheDetails cacheDetails = mapTiles.getCacheDetails();
663         cacheDetails.setMaxCacheSize(3072);
664         cacheDetails.setMaxPageSize(307);
665 
666         statusBar.setInfoTwoText("("+mapWidth+", "+mapHeight+")");
667     }
668 
669     protected class MapCanvas extends Canvas
670     {
671         public void paint(Graphics g)
672         {
673             updateMapView((Graphics2D)g);
674         }
675 
676         public void update(Graphics g)
677         {
678             updateMapView((Graphics2D)g);
679         }
680 
681         private void updateMapView(Graphics2D g2D)
682         {
683             if (createBuffer)
684             {
685                 createBufferStrategy(2);
686                 resetBuffer();
687 
688                 createBuffer = false;
689             }
690 
691             if (clearMapView)
692             {
693                 bsG2D.clearRect(0, 0, (int)PagedMap.this.lastMapWidth*tileSize, (int)PagedMap.this.lastMapHeight*tileSize);
694                 clearMapView = false;
695             }
696 
697             if (!mapUpdating)
698             {
699                 PagedTile currentTile = new PagedTile();
700                 final int DEFAULT_TRAVERSE_RATING = tileSet.getTile(defaultTileIndex).getTraverseRating();
701                 int TEXT_OFFSET_X = 5;
702                 int TEXT_OFFSET_Y = 10;
703 
704                 for (int x = viewTileOriginX, posX = 0; posX < adjustedViewWidth && x < mapWidth; x++, posX+=tileSize)
705                     for (int y = viewTileOriginY, posY = 0; posY < adjustedViewHeight && y < mapHeight; y++, posY+=tileSize)
706                     {
707                         long index = (long)y * (long)mapWidth + (long)x;
708 
709                         mapTiles.loadPage(index, (adjustedViewWidth*adjustedViewHeight)/tileSize);
710 
711                         mapTiles.getPagedElementAt(index, currentTile);
712 
713                         if (!currentTile.isValid())
714                         {
715                             currentTile.setColumn(x);
716                             currentTile.setRow(y);
717                             currentTile.setTileSetIndex(defaultTileIndex);
718                             currentTile.setTraverseRating(DEFAULT_TRAVERSE_RATING);
719                             currentTile.setValid(true);
720 
721                             mapTiles.setPagedElementAt(index, currentTile);
722                         }
723 
724                         bsG2D.drawImage(PagedMap.this.tileSet.getImage(currentTile.getTileSetIndex()), (int)posX, (int)posY, this);
725 
726                         if (showTraverseRating)
727                         {
728                             AttributedString aString = new AttributedString(" " + currentTile.getTraverseRating() + " ");
729                             aString.addAttribute(TextAttribute.FOREGROUND, Color.BLUE);
730                             aString.addAttribute(TextAttribute.BACKGROUND, Color.LIGHT_GRAY);
731                             aString.addAttribute(TextAttribute.WIDTH, TextAttribute.WIDTH_EXTENDED);
732                             aString.addAttribute(TextAttribute.SIZE, new Float(9.0));
733 
734                             bsG2D.drawString(aString.getIterator(), posX+TEXT_OFFSET_X, posY+TEXT_OFFSET_Y);
735                         }
736 
737                         if (showGrid)
738                         {
739                             bsG2D.draw(new Rectangle2D.Double(posX, posY, tileSize, tileSize));
740                             bsG2D.setColor(Color.GREEN);
741                         }
742                     }
743             }
744 
745             bStrategy.show();
746         }
747     }
748 
749     private class TileLoader implements Runnable
750     {
751         private PagedTile currentTile;
752         private long index;
753 
754         public TileLoader(long index, PagedTile currentTile)
755         {
756             this.currentTile = currentTile;
757             this.index = index;
758         }
759 
760         public void run()
761         {
762             mapTiles.setPagedElementAt(index, currentTile);
763         }
764     }
765 }