Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / impl / DefaultMapContextDrawer.java @ 38210

History | View | Annotate | Download (20.4 KB)

1
package org.gvsig.fmap.mapcontext.impl;
2

    
3
import java.awt.Graphics2D;
4
import java.awt.image.BufferedImage;
5
import java.util.ArrayList;
6
import java.util.Iterator;
7
import java.util.List;
8
import java.util.NoSuchElementException;
9

    
10
import org.gvsig.compat.CompatLocator;
11
import org.gvsig.compat.print.PrintAttributes;
12
import org.gvsig.fmap.dal.exception.ReadException;
13
import org.gvsig.fmap.mapcontext.MapContext;
14
import org.gvsig.fmap.mapcontext.MapContextDrawer;
15
import org.gvsig.fmap.mapcontext.ViewPort;
16
import org.gvsig.fmap.mapcontext.layers.FLayer;
17
import org.gvsig.fmap.mapcontext.layers.FLayers;
18
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
19
import org.gvsig.fmap.mapcontext.layers.LayersIterator;
20
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
21
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
22
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
23
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
24
import org.gvsig.tools.task.Cancellable;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27

    
28
public class DefaultMapContextDrawer implements MapContextDrawer {
29

    
30
        private static final Logger LOG = LoggerFactory
31
                        .getLogger(DefaultMapContextDrawer.class);
32

    
33
        private MapContext mapContext = null;
34
        private ViewPort viewPort = null;
35
        private CachedImage cachedImage = null;
36
        private DrawList previousDrawList = null;
37

    
38
        protected void checkInitialized() {
39
                if (mapContext == null || viewPort == null) {
40
                        throw new IllegalStateException(
41
                                        "MapContext and ViewPort must be set");
42
                }
43
        }
44

    
45
        public void draw(FLayers root, BufferedImage image, Graphics2D g,
46
                        Cancellable cancel, double scale) throws ReadException {
47

    
48
                this.checkInitialized();
49

    
50
                // With viewport changes all layers must be redrawn, discard cache
51
                if (cachedImage != null && cachedImage.hasChangedViewPortDrawVersion()) {
52
                        cachedImage = null;
53
                }
54

    
55
                if (isValidFullCachedImage()) {
56
                        g.drawImage(cachedImage.getFullDrawnImage(), 0, 0, null);
57
                        LOG.debug("Drawn full image from the cache, all layers cached");
58
                        return;
59
                }
60

    
61
                DrawList drawList = this.createDrawList(root, cancel, scale);
62
                if (drawList == null || drawList.size() == 0) {
63
                        return;
64
                }
65

    
66
                if (cancel.isCanceled()) {
67
                        cachedImage = null;
68
                        return;
69
                }
70

    
71
                int firstLayerToDraw;
72
                int lastLayerToDraw;
73
                if (isValidPartialCachedImage(drawList)) {
74
                        firstLayerToDraw = 0;
75
                        lastLayerToDraw = cachedImage.getLastDrawnLayerPosition();
76
                        g.drawImage(cachedImage.getPartialDrawnImage(), 0, 0, null);
77
                        cachedImage.updateVersions(mapContext, viewPort);
78
                        LOG.debug("Reused image of cached layers from 0 to {}",
79
                                        new Integer(lastLayerToDraw));
80
                } else {
81
                        if (cachedImage == null) {
82
                                cachedImage = new CachedImage();
83
                                // Draw all layers
84
                                firstLayerToDraw = 0;
85
                                lastLayerToDraw = drawList.getLayerCount() - 1;
86
                        } else {
87
                                // Draw the first group of layers without changes to be cached
88
                                // next time
89
                                firstLayerToDraw = 0;
90
                                int firstChangedLayer = drawList.getFirstChangedLayer();
91
                                // If negative nothing has changed, so draw all the layers
92
                                lastLayerToDraw = firstChangedLayer < 0 ? drawList
93
                                                .getLayerCount() - 1 : firstChangedLayer - 1;
94
                        }
95
                        drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
96
                                        cancel, scale);
97
                        cachedImage.setPartialDrawnImage(image, mapContext, viewPort,
98
                                        lastLayerToDraw);
99
                }
100

    
101
                if (cancel.isCanceled()) {
102
                        cachedImage = null;
103
                        return;
104
                }
105

    
106
                // Draw the second group of layers not cached
107
                firstLayerToDraw = lastLayerToDraw + 1;
108
                lastLayerToDraw = drawList.getLayerCount() - 1;
109
                drawList.drawLayers(image, g, firstLayerToDraw, lastLayerToDraw,
110
                                cancel, scale);
111
                cachedImage.setFullDrawnImage(image);
112

    
113
                this.previousDrawList = drawList;
114
        }
115

    
116
        private boolean isValidPartialCachedImage(DrawList drawList) {
117
                return cachedImage != null
118
                                && cachedImage.isValidPartialDrawnImage(mapContext, drawList);
119
        }
120

    
121
        private boolean isValidFullCachedImage() {
122
                return cachedImage != null
123
                                && cachedImage.isValidFullDrawnImage(mapContext);
124
        }
125

    
126
        private void print(Object layerOrComposed, Graphics2D g,
127
                        Cancellable cancel, double scale, PrintAttributes properties)
128
                        throws ReadException {
129
                ILabelable labelable = null;
130
                ILabelable tmp = null;
131
                if (layerOrComposed instanceof ILabelable) {
132

    
133
                        tmp = (ILabelable) layerOrComposed;
134

    
135
                        if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
136
                                        && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
137
                                labelable = tmp;
138
                        }
139
                }
140

    
141
                if (layerOrComposed instanceof FLayer) {
142
                        FLayer layer = (FLayer) layerOrComposed;
143
                        layer.print(g, viewPort, cancel, scale, properties);
144
                } else {
145
                        ComposedLayer composed = (ComposedLayer) layerOrComposed;
146
                        composed.print(g, viewPort, cancel, scale, properties);
147
                }
148
                if (labelable != null) {
149
                        labelable.printLabels(g, viewPort, cancel, scale, properties);
150
                }
151

    
152
        }
153

    
154
        public void setMapContext(MapContext mapContext) {
155
                if (this.mapContext == mapContext) {
156
                        return;
157
                }
158
                this.clean();
159
                this.mapContext = mapContext;
160

    
161
        }
162

    
163
        public void setViewPort(ViewPort viewPort) {
164
                if (this.viewPort == viewPort) {
165
                        return;
166
                }
167
                this.clean();
168
                this.viewPort = viewPort;
169

    
170
        }
171

    
172
        protected void clean() {
173
                this.cachedImage = null;
174
        }
175

    
176
        public class CachedImage {
177
                private BufferedImage partialDrawnImage;
178
                private BufferedImage fullDrawnImage;
179
                private long lastMapContextVersion;
180
                private long lastViewPortVersion;
181
                private int lastDrawnLayerPosition;
182

    
183
                public void setPartialDrawnImage(BufferedImage partialDrawnImage,
184
                                MapContext mapContext, ViewPort viewPort,
185
                                int lastDrawnLayerPosition) {
186
                        this.partialDrawnImage = CompatLocator.getGraphicsUtils()
187
                                        .copyBufferedImage(partialDrawnImage);
188
                        this.lastDrawnLayerPosition = lastDrawnLayerPosition;
189
                        updateVersions(mapContext, viewPort);
190
                }
191
                
192
                public void updateVersions(MapContext mapContext, ViewPort viewPort) {
193
                        this.lastMapContextVersion = mapContext.getDrawVersion();
194
                        this.lastViewPortVersion = viewPort.getDrawVersion();                        
195
                }
196

    
197
                public void setFullDrawnImage(BufferedImage fullDrawnImage) {
198
                        this.fullDrawnImage = CompatLocator.getGraphicsUtils()
199
                                        .copyBufferedImage(fullDrawnImage);
200
                }
201

    
202
                public BufferedImage getPartialDrawnImage() {
203
                        return partialDrawnImage;
204
                }
205

    
206
                public BufferedImage getFullDrawnImage() {
207
                        return fullDrawnImage;
208
                }
209

    
210
                public long getMapContextVersion() {
211
                        return lastMapContextVersion;
212
                }
213

    
214
                public int getLastDrawnLayerPosition() {
215
                        return this.lastDrawnLayerPosition;
216
                }
217

    
218
                public boolean isValidFullDrawnImage(MapContext context) {
219
                        // If the MapContext version has not changed, there are not any
220
                        // changes that require redrawing any of the layers.
221
                        return fullDrawnImage != null && !hasChangedMapContextDrawVersion();
222
                }
223

    
224
                public boolean hasChangedMapContextDrawVersion() {
225
                        // This change detects changes in layers and the viewport also
226
                        return mapContext.getDrawVersion() != this.lastMapContextVersion;
227
                }
228

    
229
                public boolean hasChangedViewPortDrawVersion() {
230
                        // This change detects changes in the viewport
231
                        return viewPort.getDrawVersion() != this.lastViewPortVersion;
232
                }
233

    
234
                public boolean isValidPartialDrawnImage(MapContext context,
235
                                DrawList drawList) {
236
                        if (!hasChangedMapContextDrawVersion()) {
237
                                // Nothing has changed
238
                                return true;
239
                        }
240

    
241
                        if (partialDrawnImage == null || hasChangedViewPortDrawVersion()) {
242
                                // No image available or changes in view port
243
                                return false;
244
                        }
245

    
246
                        if (drawList.size() < lastDrawnLayerPosition + 1) {
247
                                // New list has fewer layers than before
248
                                return false;
249
                        }
250

    
251
                        // There is any change in the layers drawn in the partial drawn
252
                        // image?
253
                        return drawList.getFirstChangedLayer() > lastDrawnLayerPosition;
254
                }
255
        }
256

    
257
        public class DrawList {
258
                private List layers = new ArrayList();
259
                private List all = new ArrayList();
260
                private List versions = new ArrayList();
261
                private DrawList previosList = null;
262
                private int firstLayerChanged = -1;
263

    
264
                public DrawList() {
265
                }
266

    
267
                public DrawList(DrawList previousList) {
268
                        if (previousList != null) {
269
                                this.firstLayerChanged = previousList.getLayerCount();
270
                                this.previosList = previousList;
271
                        }
272
                }
273

    
274
                public int getLayerCount() {
275
                        return this.layers.size();
276
                }
277

    
278
                private boolean hasChanged(FLayer layer, int pos) {
279
                        FLayer previous = (FLayer) this.previosList.layers.get(pos);
280
                        // String previousName = previous.getName();
281
                        // String layerName = layer.getName();
282
                        if (previous != layer) {
283
                                return true;
284
                        }
285
                        long previousVersion = ((Long) this.previosList.versions.get(pos))
286
                                        .longValue();
287
                        long layerVersion = layer.getDrawVersion();
288

    
289
                        return previousVersion != layerVersion;
290
                }
291

    
292
                public void add(Object obj) {
293
                        if (obj instanceof FLayer) {
294
                                FLayer layer = (FLayer) obj;
295
                                int curIndex = this.layers.size();
296
                                if (this.firstLayerChanged >= curIndex) {
297
                                        if (this.previosList.getLayerCount() > curIndex) {
298
                                                if (this.hasChanged(layer, curIndex)) {
299
                                                        this.firstLayerChanged = curIndex;
300
                                                }
301
                                        } else if (this.previosList.getLayerCount() == curIndex) {
302
                                                this.firstLayerChanged = curIndex;
303
                                        }
304
                                }
305
                                this.layers.add(layer);
306
                                this.versions.add(new Long(layer.getDrawVersion()));
307
                        } else if (!(obj instanceof LayersGroupEvent)) {
308
                                throw new UnsupportedOperationException();
309
                        }
310

    
311
                        this.all.add(obj);
312
                }
313

    
314
                public int size() {
315
                        return this.all.size();
316
                }
317

    
318
                public int getFirstChangedLayer() {
319
                        if (this.firstLayerChanged > this.layers.size()) {
320
                                this.firstLayerChanged = this.layers.size();
321
                        }
322
                        return this.firstLayerChanged;
323
                }
324

    
325
                public FLayer getLayer(int pos) {
326
                        return (FLayer) this.layers.get(pos);
327
                }
328

    
329
                public Object get(int pos) {
330
                        return this.all.get(pos);
331
                }
332

    
333
                public void drawLayers(BufferedImage image, Graphics2D g,
334
                                int firstLayerToDraw, int lastLayerToDraw, Cancellable cancel,
335
                                double scale) throws ReadException {
336

    
337
                        if (firstLayerToDraw > lastLayerToDraw) {
338
                                LOG.debug("Nothing to draw");
339
                                return;
340
                        }
341

    
342
                        // Find the real layer positions excluding LayersGroupEvents
343
                        FLayer firstLayer = (FLayer) layers.get(firstLayerToDraw);
344
                        int firstLayerPos = all.indexOf(firstLayer);
345
                        // Look if it belongs to a group and start it
346
                        if (firstLayerPos > 0) {
347
                                for (int i = firstLayerPos - 1; i > 0; i++) {
348
                                        Object group = all.get(i);
349
                                        if (group instanceof LayersGroupEvent) {
350
                                                LayersGroupEvent event = (LayersGroupEvent) group;
351
                                                if (event.type == LayersGroupEvent.IN_Event) {
352
                                                        event.group.beginDraw(g, viewPort);
353
                                                }
354
                                                break;
355
                                        }
356
                                }
357
                        }
358
                        FLayer lastLayer = (FLayer) layers.get(lastLayerToDraw);
359
                        int lastLayerPos = all.indexOf(lastLayer);
360

    
361
                        LOG.debug("Drawing from layer {} in position (layers: {}, all: {})"
362
                                        + " to layer {} in position (layers: {}, all: {})",
363
                                        new Object[] { firstLayer, new Integer(firstLayerToDraw),
364
                                                        new Integer(firstLayerPos), lastLayer,
365
                                                        new Integer(lastLayerToDraw),
366
                                                        new Integer(lastLayerPos) });
367

    
368
                        ComposedLayer composed = null;
369
                        for (int pos = firstLayerPos; pos <= lastLayerPos; pos++) {
370
                                if (cancel.isCanceled()) {
371
                                        return;
372
                                }
373

    
374
                                Object layerOrGroup = get(pos);
375

    
376
                                // Group drawing events management
377
                                if (layerOrGroup instanceof LayersGroupEvent) {
378
                                        LayersGroupEvent event = (LayersGroupEvent) layerOrGroup;
379
                                        if (event.type == LayersGroupEvent.IN_Event) {
380
                                                event.group.beginDraw(g, viewPort);
381
                                        } else {
382
                                                event.group.endDraw(g, viewPort);
383
                                        }
384
                                } else {
385
                                        FLayer layer = (FLayer) layerOrGroup;
386
                                        if (composed != null && composed.canAdd(layer)) {
387
                                                // Previous or current layer could be composed
388
                                                // Add current layer
389
                                                addToComposedLayer(composed, layer);
390
                                        } else {
391
                                                if (composed != null) {
392
                                                        // Current layer can't be composed on the previous
393
                                                        // composedlayer. Draw previous composed
394
                                                        LOG.debug("Drawing composed layer {} ", composed);
395
                                                        draw(composed, image, g, cancel, scale);
396
                                                        composed = null;
397
                                                }
398

    
399
                                                // Try if the current layer can be composed
400
                                                // Create new composed or draw current layer
401
                                                composed = layer.newComposedLayer();
402
                                                if (composed == null) {
403
                                                        LOG.debug("Drawing layer {} ", layer);
404
                                                        draw(layer, image, g, cancel, scale);
405
                                                } else {
406
                                                        addToComposedLayer(composed, layer);
407
                                                }
408
                                        }
409
                                }
410
                        }
411
                        if (composed != null) {
412
                                // Draw the pending composed
413
                                draw(composed, image, g, cancel, scale);
414
                        }
415

    
416
                        // Check if the last layer is the last of a group and close it
417
                        for (int i = lastLayerPos + 1; i < all.size(); i++) {
418
                                Object group = all.get(i);
419
                                if (group instanceof LayersGroupEvent) {
420
                                        LayersGroupEvent event = (LayersGroupEvent) group;
421
                                        if (event.type == LayersGroupEvent.OUT_Event) {
422
                                                event.group.endDraw(g, viewPort);
423
                                        }
424
                                        break;
425
                                }
426
                        }
427
                }
428

    
429
                private void addToComposedLayer(ComposedLayer composed, FLayer layer)
430
                                throws ReadException {
431
                        try {
432
                                LOG.debug("Adding layer {} to composed layer ", layer, composed);
433
                                composed.add(layer);
434
                        } catch (Exception e) {
435
                                throw new ReadException("DefalutMapContexDrawer exception", e);
436
                        }
437
                }
438

    
439
                private void draw(Object layerOrComposed, BufferedImage image,
440
                                Graphics2D g, Cancellable cancel, double scale)
441
                                throws ReadException {
442
                        ILabelable labelable = null;
443
                        ILabelable tmp = null;
444
                        if (layerOrComposed instanceof ILabelable) {
445

    
446
                                tmp = (ILabelable) layerOrComposed;
447

    
448
                                if (tmp.isLabeled() && tmp.getLabelingStrategy() != null
449
                                                && tmp.getLabelingStrategy().shouldDrawLabels(scale)) {
450
                                        labelable = tmp;
451
                                }
452
                        }
453
                                
454
                        if (layerOrComposed instanceof FLayer) {
455
                                int beforeDrawEventType;
456
                                int afterDrawEventType;
457
                                if (layerOrComposed instanceof GraphicLayer) {
458
                                        beforeDrawEventType = LayerDrawEvent.GRAPHICLAYER_BEFORE_DRAW;
459
                                        afterDrawEventType = LayerDrawEvent.GRAPHICLAYER_AFTER_DRAW;
460
                                } else {
461
                                        beforeDrawEventType = LayerDrawEvent.LAYER_BEFORE_DRAW;
462
                                        afterDrawEventType = LayerDrawEvent.LAYER_AFTER_DRAW;
463
                                }
464
                                FLayer layer = (FLayer) layerOrComposed;
465
                                drawLayer(layer, image, g, cancel, scale, beforeDrawEventType,
466
                                                afterDrawEventType);
467
                        } else {
468
                                ComposedLayer composed = (ComposedLayer) layerOrComposed;
469
                                composed.draw(image, g, viewPort, cancel, scale);
470
                        }
471
                        if (labelable != null) {
472
                                labelable.drawLabels(image, g, viewPort, cancel, scale,
473
                                                MapContext.getScreenDPI());
474
                        }
475

    
476
                }
477

    
478
                protected void drawLayer(FLayer layer, BufferedImage image,
479
                                Graphics2D g, Cancellable cancel, double scale,
480
                                int beforeDrawEventType, int afterDrawEventType)
481
                                throws ReadException {
482
                        LayerDrawEvent event = new LayerDrawEvent(layer, g, viewPort, beforeDrawEventType);
483
                        mapContext.fireLayerDrawingEvent(event);
484
                        layer.draw(image, g, viewPort, cancel, scale);
485
                        event = new LayerDrawEvent(layer, g, viewPort, afterDrawEventType);
486
                        mapContext.fireLayerDrawingEvent(event);
487
                }
488

    
489
        }
490

    
491
        private class SimpleLayerIterator extends LayersIterator {
492

    
493
                public SimpleLayerIterator(FLayer layer) {
494
                        this.appendLayer(layer);
495
                }
496

    
497
                public boolean evaluate(FLayer layer) {
498
                        if (layer instanceof FLayers) {
499
                                return false;
500
                        }
501
                        return layer.isAvailable() && layer.isVisible();
502
                }
503

    
504
        }
505

    
506
        public void dispose() {
507
                this.mapContext = null;
508
                this.viewPort = null;
509
                this.cachedImage = null;
510
                this.previousDrawList = null;
511
        }
512

    
513
        public void print(FLayers root, Graphics2D g, Cancellable cancel,
514
                        double scale, PrintAttributes properties) throws ReadException {
515
                this.checkInitialized();
516

    
517
                List printList = this.createPrintList(root, cancel);
518
                if (cancel.isCanceled()) {
519
                        return;
520
                }
521

    
522
                ComposedLayer composed = null;
523
                int pos;
524
                FLayer layer;
525
                int layerPos = -1;
526
                Object obj;
527
                LayersGroupEvent event;
528
                for (pos = 0; pos < printList.size(); pos++) {
529
                        if (cancel.isCanceled()) {
530
                                return;
531
                        }
532

    
533
                        obj = printList.get(pos);
534
                        if (obj instanceof LayersGroupEvent) {
535
                                event = (LayersGroupEvent) obj;
536
                                if (event.type == LayersGroupEvent.IN_Event) {
537
                                        // System.out.println("=======Empiza a pintar grupo de capas "+
538
                                        // ((FLayers)event.group).getName() +"============");
539
                                        event.group.beginDraw(g, viewPort);
540
                                } else {
541
                                        event.group.endDraw(g, viewPort);
542
                                        // System.out.println("=======Fin a pintar grupo de capas "+
543
                                        // ((FLayers)event.group).getName() +"============");
544

    
545
                                }
546
                                continue;
547
                        }
548
                        layerPos++;
549

    
550
                        layer = (FLayer) obj;
551

    
552
                        // *** Pintado de capa/composicion de capa ***
553
                        if (composed == null) {
554
                                composed = layer.newComposedLayer();
555
                                if (composed != null) {
556
                                        try {
557
                                                composed.add(layer);
558
                                                // System.out.println("=======Imprimiendo composicion de pintado "+
559
                                                // (layerPos-1)+" ============");
560
                                                continue;
561
                                        } catch (Exception e) {
562
                                                throw new ReadException(
563
                                                                "DefaultMapContexDrawer exception", e);
564
                                        }
565
                                }
566
                        } else {
567
                                if (composed.canAdd(layer)) {
568
                                        try {
569
                                                composed.add(layer);
570
                                                // System.out.println("=== a?adiendo a composicion de pintado "+
571
                                                // layerPos+ " "+layer.getName());
572
                                                continue;
573
                                        } catch (Exception e) {
574
                                                throw new ReadException(
575
                                                                "DefaultMapContexDrawer exception", e);
576
                                        }
577
                                } else {
578
                                        // System.out.println("=======Imprimiendo composicion de pintado "+
579
                                        // (layerPos-1)+" ============");
580
                                        this.print(composed, g, cancel, scale, properties);
581
                                        // composed.print( g, viewPort, cancel, scale,properties);
582
                                        composed = layer.newComposedLayer();
583
                                        if (composed != null) {
584
                                                try {
585
                                                        composed.add(layer);
586
                                                        // System.out.println("=== a?adiendo a composicion de pintado "+
587
                                                        // layerPos+ " "+layer.getName());
588
                                                        continue;
589
                                                } catch (Exception e) {
590
                                                        throw new ReadException(
591
                                                                        "DefaultMapContexDrawer exception", e);
592
                                                }
593
                                        }
594
                                }
595
                        }
596
                        // System.out.println("=== imprimiendo "+ layerPos+
597
                        // " "+layer.getName());
598
                        this.print(layer, g, cancel, scale, properties);
599
                        // layer.print(g, viewPort, cancel, scale,properties);
600
                        // *** Pintado de capa/composicion de capa ***
601
                        if (composed != null) {
602
                                // si la composicion no se ha pintado la pintamos
603
                                // System.out.println("=======Imprimiendo composicion de pintado "+
604
                                // (layerPos-1)+" (ultimo) ============");
605
                                this.print(composed, g, cancel, scale, properties);
606
                                // composed.print(g, viewPort, cancel, scale, properties);
607
                                composed = null;
608
                        }
609
                }
610

    
611
        }
612

    
613
        private DrawList createDrawList(FLayers root, Cancellable cancel,
614
                        double scale) {
615
                DrawList result = new DrawList(this.previousDrawList);
616
                Iterator iter = new MyLayerIterator((FLayer) root, scale);
617
                while (iter.hasNext()) {
618
                        if (cancel.isCanceled()) {
619
                                return null;
620
                        }
621
                        result.add(iter.next());
622
                }
623
                if (cancel.isCanceled()) {
624
                        return null;
625
                }
626
                // Take into account also the Graphic layer
627
                result.add(mapContext.getGraphicsLayer());
628
                return result;
629
        }
630

    
631
        private List createPrintList(FLayers root, Cancellable cancel) {
632
                List result = new ArrayList();
633
                Iterator iter = new SimpleLayerIterator((FLayer) root);
634
                while (iter.hasNext()) {
635
                        if (cancel.isCanceled()) {
636
                                return null;
637
                        }
638
                        result.add(iter.next());
639
                }
640
                return result;
641
        }
642

    
643
        private class MyLayerIterator implements Iterator {
644
                List layersList = new ArrayList();
645
                int index = 0;
646
                double scale = 0;
647

    
648
                public MyLayerIterator(FLayer layer, double scale) {
649
                        this.scale = scale;
650
                        this.appendLayer(layer);
651
                }
652

    
653
                protected void appendLayer(FLayer layer) {
654
                        if (layer instanceof LayerCollection) {
655
                                appendLayers((LayerCollection) layer);
656
                        } else if (this.evaluate(layer)) {
657
                                layersList.add(layer);
658
                        }
659
                }
660

    
661
                private void appendLayers(LayerCollection layers) {
662
                        int i;
663
                        layersList.add(new LayersGroupEvent(layers,
664
                                        LayersGroupEvent.IN_Event));
665
                        for (i = 0; i < layers.getLayersCount(); i++) {
666
                                appendLayer(layers.getLayer(i));
667
                        }
668
                        layersList.add(new LayersGroupEvent(layers,
669
                                        LayersGroupEvent.OUT_Event));
670
                }
671

    
672
                public void remove() {
673
                        throw new UnsupportedOperationException();
674
                }
675

    
676
                public boolean hasNext() {
677
                        return index < layersList.size();
678
                }
679

    
680
                public Object next() {
681
                        if (!this.hasNext()) {
682
                                throw new NoSuchElementException();
683
                        }
684
                        Object aux = layersList.get(index);
685
                        index++;
686
                        return aux;
687
                }
688

    
689
                public boolean evaluate(FLayer layer) {
690
                        if (layer instanceof LayerCollection) {
691
                                return false;
692
                        }
693
                        return layer.isAvailable() && layer.isVisible()
694
                                        && layer.isWithinScale(this.scale);
695
                }
696

    
697
        }
698

    
699
        private class LayersGroupEvent {
700
                public static final String IN_Event = "in";
701
                public static final String OUT_Event = "Out";
702

    
703
                private LayerCollection group = null;
704
                private String type = IN_Event;
705

    
706
                public LayersGroupEvent(LayerCollection group, String type) {
707
                        this.group = group;
708
                        this.type = type;
709
                }
710

    
711
                public String getType() {
712
                        return type;
713
                }
714

    
715
                public LayerCollection getGroup() {
716
                        return group;
717
                }
718
        }
719

    
720
}