Statistics
| Revision:

root / branches / gvSIG_CAD_Layout_version / applications / appgvSIG / src / com / iver / cit / gvsig / gui / layout / fframes / FFrame.java @ 1822

History | View | Annotate | Download (15.9 KB)

1
/*
2
 * Created on 17-may-2004
3
 *
4
 */
5
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
6
 *
7
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
22
 *
23
 * For more information, contact:
24
 *
25
 *  Generalitat Valenciana
26
 *   Conselleria d'Infraestructures i Transport
27
 *   Av. Blasco Ib??ez, 50
28
 *   46010 VALENCIA
29
 *   SPAIN
30
 *
31
 *      +34 963862235
32
 *   gvsig@gva.es
33
 *      www.gvsig.gva.es
34
 *
35
 *    or
36
 *
37
 *   IVER T.I. S.A
38
 *   Salamanca 50
39
 *   46005 Valencia
40
 *   Spain
41
 *
42
 *   +34 963163400
43
 *   dac@iver.es
44
 */
45
package com.iver.cit.gvsig.gui.layout.fframes;
46

    
47
import com.iver.andami.PluginServices;
48
import com.iver.andami.messages.NotificationManager;
49

    
50
import com.iver.cit.gvsig.Abrir;
51
import com.iver.cit.gvsig.fmap.DriverException;
52
import com.iver.cit.gvsig.gui.layout.FLayoutUtilities;
53
import com.iver.cit.gvsig.gui.layout.Layout;
54
import com.iver.cit.gvsig.gui.layout.dialogs.Tag;
55
import com.iver.cit.gvsig.project.Project;
56
import com.iver.cit.gvsig.project.ProjectMap;
57

    
58
import com.iver.utiles.XMLEntity;
59

    
60
import java.awt.Color;
61
import java.awt.Cursor;
62
import java.awt.Font;
63
import java.awt.Graphics2D;
64
import java.awt.Image;
65
import java.awt.Rectangle;
66
import java.awt.geom.AffineTransform;
67
import java.awt.geom.Point2D;
68
import java.awt.geom.Rectangle2D;
69
import java.awt.image.BufferedImage;
70

    
71
import java.net.URL;
72

    
73
import javax.swing.ImageIcon;
74

    
75

    
76
/**
77
 * Clase que implementa la interface IFFrame con los m?todos por defecto de
78
 * todos los FFrames  que extenderan de este, dejando uno como m?todo
79
 * abstracto para implementar por todos los  FFrames para ser dibujados.
80
 *
81
 * @author Vicente Caballero Navarro
82
 */
83
public abstract class FFrame implements IFFrame {
84
        
85
        protected String m_name = "FFrame";
86
        private Rectangle2D.Double m_BoundBox = new Rectangle2D.Double();
87
        private Rectangle2D.Double m_BoundingBox = new Rectangle2D.Double();
88
        protected int m_Selected = 0;
89
        private Rectangle n = new Rectangle();
90
        private Rectangle ne = new Rectangle();
91
        private Rectangle e = new Rectangle();
92
        private Rectangle se = new Rectangle();
93
        private Rectangle s = new Rectangle();
94
        private Rectangle so = new Rectangle();
95
        private Rectangle o = new Rectangle();
96
        private Rectangle no = new Rectangle();
97
        private String tag = null;
98
        protected int num = 0;
99

    
100
        public void refreshHandlers(AffineTransform at){
101
                int size = 10;
102
                Rectangle2D.Double r = getBoundingBox(at);
103
                no.setRect((int) r.x - size, (int) r.y - size, size, size);
104
                ne.setRect((int) r.getMaxX(), (int) r.y - size, size, size);
105
                so.setRect((int) r.x - size, (int) r.getMaxY(), size, size);
106
                se.setRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
107
                n.setRect((int) r.getCenterX() - (size / 2), (int) r.y - size, size, size);
108
                s.setRect((int) r.getCenterX() - (size / 2), (int) r.getMaxY(), size, size);
109
                o.setRect((int) r.x - size, (int) r.getCenterY() - (size / 2), size, size);
110
                e.setRect((int) r.getMaxX(), (int) r.getCenterY() - (size / 2), size, size);
111
        }
112
        /**
113
         * Dibuja los handlers sobre el boundingBox en el graphics que se pasa como
114
         * par?metro.
115
         *
116
         * @param g Graphics sobre el que dibujar.
117
         */
118
        public void drawHandlers(Graphics2D g) {
119
                refreshHandlers(null);
120
                g.fillRect((int) no.x, (int) no.y , no.width, no.height);
121
                g.fillRect((int) ne.x, (int) ne.y , ne.width, ne.height);
122
                g.fillRect((int) so.x, (int) so.y , so.width, so.height);
123
                g.fillRect((int) se.x, (int) se.y , se.width, se.height);
124
                g.fillRect((int) n.x, (int) n.y , n.width, n.height);
125
                g.fillRect((int) s.x, (int) s.y , s.width, s.height);
126
                g.fillRect((int) o.x, (int) o.y , o.width, o.height);
127
                g.fillRect((int) e.x, (int) e.y , e.width, e.height);
128
        }
129

    
130
        /**
131
         * Establece que tipo de selecci?n se realiza sobre el fframe.
132
         *
133
         * @param p punto sobre el que se debe de establecer si se selecciona o no
134
         *                   el fframe.
135
         */
136
        public void setSelected(Point2D.Double p) {
137
                m_Selected = getContains(p);
138
        }
139

    
140
        /**
141
         * Actualiza el BoundBox del FFrame a partir de su rect?ngulo en pixels y
142
         * la matriz de transformaci?n.
143
         *
144
         * @param r Rect?ngulo.
145
         * @param at Matriz de transformaci?n.
146
         */
147
        public void updateRect(Rectangle2D r, AffineTransform at) {
148
                Rectangle2D.Double rec = FLayoutUtilities.toSheetRect(r, at);
149
                rec.setRect((int) rec.getMinX(), (int) rec.getMinY(),
150
                        (int) rec.getWidth(), (int) rec.getHeight());
151
                setBoundBox(rec);
152
        }
153

    
154
        /**
155
         * Devuelve el rect?ngulo a partir del desplazamiento en el eje x y el
156
         * desplazamiento en el eje y.
157
         *
158
         * @param difx desplazamiento sobre el eje x.
159
         * @param dify desplazamiento sobre el eje y.
160
         *
161
         * @return rect?ngulo modificado en funci?n del desplazamiento realizado.
162
         */
163
        public Rectangle2D getMovieRect(int difx, int dify) {
164
                double x = 0;
165
                double y = 0;
166
                double w = 0;
167
                double h = 0;
168

    
169
                Rectangle2D.Double rectaux = new Rectangle2D.Double(this.getBoundingBox(
170
                                        null).x, this.getBoundingBox(null).y,
171
                                this.getBoundingBox(null).width,
172
                                this.getBoundingBox(null).height);
173
                Rectangle2D.Double rec = this.getBoundingBox(null);
174
                int difn = 0;
175
                difn = difx;
176
                x = rectaux.x;
177
                y = rectaux.y;
178
                w = rectaux.width;
179
                h = rectaux.height;
180

    
181
                switch (this.getSelected()) {
182
                        case (RECT):
183
                                rectaux.setRect((x + difx), (y + dify), w, h);
184

    
185
                                break;
186

    
187
                        case (N):
188

    
189
                                if ((y + dify) > rec.getMaxY()) {
190
                                        y = rec.getMaxY();
191
                                } else {
192
                                        y = y + dify;
193
                                }
194

    
195
                                rectaux.setRect(x, y, w, Math.abs(h - dify));
196

    
197
                                break;
198

    
199
                        case (O):
200

    
201
                                if ((x + difx) > rec.getMaxX()) {
202
                                        x = rec.getMaxX();
203
                                } else {
204
                                        x = x + difx;
205
                                }
206

    
207
                                rectaux.setRect(x, y, Math.abs(w - difx), h);
208

    
209
                                break;
210

    
211
                        case (S):
212

    
213
                                if (y > (rec.getMaxY() + dify)) {
214
                                        y = rec.getMaxY() + dify;
215
                                }
216

    
217
                                rectaux.setRect(x, y, w, Math.abs(h + dify));
218

    
219
                                break;
220

    
221
                        case (E):
222

    
223
                                if (x > (rec.getMaxX() + difx)) {
224
                                        x = rec.getMaxX() + difx;
225
                                }
226

    
227
                                rectaux.setRect(x, y, Math.abs(w + difx), h);
228

    
229
                                break;
230

    
231
                        case (NE):
232

    
233
                                if ((y - difn) > rec.getMaxY()) {
234
                                        y = rec.getMaxY();
235
                                        x = rec.getMaxX() + difn;
236
                                } else {
237
                                        y = y - difn;
238
                                }
239

    
240
                                rectaux.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
241

    
242
                                break;
243

    
244
                        case (NO):
245

    
246
                                if ((y + difn) > rec.getMaxY()) {
247
                                        y = rec.getMaxY();
248
                                        x = rec.getMaxX();
249
                                } else {
250
                                        x = x + difn;
251
                                        y = y + difn;
252
                                }
253

    
254
                                rectaux.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
255

    
256
                                break;
257

    
258
                        case (SE):
259

    
260
                                if (y > (rec.getMaxY() + difn)) {
261
                                        y = rec.getMaxY() + difn;
262
                                        x = rec.getMaxX() + difn;
263
                                }
264

    
265
                                rectaux.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
266

    
267
                                break;
268

    
269
                        case (SO):
270

    
271
                                if ((x + difn) > rec.getMaxX()) {
272
                                        x = rec.getMaxX();
273
                                        y = rec.getMaxY() - difn;
274
                                } else {
275
                                        x = x + difn;
276
                                }
277

    
278
                                rectaux.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
279

    
280
                                break;
281

    
282
                        default:
283
                                rectaux.setRect((x), (y), w, h);
284
                }
285

    
286
                return rectaux;
287
        }
288

    
289
        /**
290
         * Devuelve un entero que representa el tipo de selecci?n que se ha
291
         * realizado sobre el fframe.
292
         *
293
         * @return tipo de selecci?n que se ha realizado.
294
         */
295
        public int getSelected() {
296
                return m_Selected;
297
        }
298

    
299
        /**
300
         * Devuelve true, si el punto que se pasa como par?metro esta contenido
301
         * dentro del boundingbox del fframe.
302
         *
303
         * @param p punto a comprobar.
304
         *
305
         * @return true si el punto esta dentro del boundingbox.
306
         */
307
        public boolean contains(Point2D.Double p) {
308
                return getBoundingBox(null).contains(p.x, p.y);
309
        }
310

    
311
        /**
312
         * Devuelve un entero que representa donde esta contenido el punto que se
313
         * pasa como par?metro.
314
         *
315
         * @param p punto a comparar.
316
         *
317
         * @return entero que representa como esta contenido el punto.
318
         */
319
        public int getContains(Point2D p) {
320
                if (n.contains(p.getX(), p.getY())) {
321
                        return N;
322
                } else if (ne.contains(p.getX(), p.getY())) {
323
                        return NE;
324
                } else if (e.contains(p.getX(), p.getY())) {
325
                        return E;
326
                } else if (e.contains(p.getX(), p.getY())) {
327
                        return E;
328
                } else if (se.contains(p.getX(), p.getY())) {
329
                        return SE;
330
                } else if (s.contains(p.getX(), p.getY())) {
331
                        return S;
332
                } else if (so.contains(p.getX(), p.getY())) {
333
                        return SO;
334
                } else if (o.contains(p.getX(), p.getY())) {
335
                        return O;
336
                } else if (no.contains(p.getX(), p.getY())) {
337
                        return NO;
338
                } else if (getBoundingBox(null).contains(p.getX(), p.getY())) {
339
                        return RECT;
340
                }
341

    
342
                return 0;
343
        }
344

    
345
        /**
346
         * Devuelve el Cursor adecuado seg?n como est? contenido el punto, si es
347
         * para desplazamiento, o cambio de tama?o.
348
         *
349
         * @param p punto a comprobar.
350
         *
351
         * @return Cursor adecuado a la posici?n.
352
         */
353
        public Cursor getMapCursor(Point2D.Double p) {
354
                int select = getContains(p);
355

    
356
                switch (select) {
357
                        case (N):
358
                                return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
359

    
360
                        case (NE):
361
                                return Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
362

    
363
                        case (E):
364
                                return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
365

    
366
                        case (SE):
367
                                return Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
368

    
369
                        case (S):
370
                                return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
371

    
372
                        case (SO):
373
                                return Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
374

    
375
                        case (O):
376
                                return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
377

    
378
                        case (NO):
379
                                return Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
380

    
381
                        case (RECT):
382
                                return Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
383
                }
384

    
385
                return null;
386
        }
387

    
388
        /**
389
         * Este m?todo se implementa en cada una de las fframe, ya que cada una se
390
         * dibuja de una forma diferente sobre el graphics. M?todo que dibuja
391
         * sobre el graphics que se le pasa como par?metro, seg?n la transformada
392
         * afin que se debe de aplicar y el rect?ngulo que se debe de dibujar.
393
         * M?todo que dibuja sobre el graphics que se le pasa como par?metro,
394
         * seg?n la transformada afin que se debe de aplicar y el rect?ngulo que
395
         * se debe de dibujar.
396
         *
397
         * @param g Graphics
398
         * @param at Transformada afin.
399
         * @param r rect?ngulo sobre el que hacer un clip.
400
         * @param imgBase DOCUMENT ME!
401
         *
402
         * @throws DriverException
403
         */
404
        public abstract void draw(Graphics2D g, AffineTransform at, Rectangle2D r,
405
                BufferedImage imgBase) throws DriverException;
406

    
407
        /**
408
         * Devuelve el nombre que representa al fframe.
409
         *
410
         * @return String
411
         */
412
        public String getName() {
413
                return m_name;
414
        }
415

    
416
        /**
417
         * Rellena el String que representa al nombre del fframe.
418
         *
419
         * @param n nombre del fframe.
420
         */
421
        public void setName(String n) {
422
                m_name = n;
423
        }
424

    
425
        /**
426
         * Devuelve el boundingBox del fframe en funci?n de la transformada af?n
427
         * que se pasa como par?metro. Si se pasa como par?metro null, devuelve el
428
         * ?ltimo boundingbox que se calcul?.
429
         *
430
         * @param at Transformada af?n
431
         *
432
         * @return Rect?ngulo que representa el BoundingBox del fframe.
433
         */
434
        public Rectangle2D.Double getBoundingBox(AffineTransform at) {
435
                if (at == null) {
436
                        return m_BoundingBox;
437
                }
438

    
439
                m_BoundingBox = FLayoutUtilities.fromSheetRect(m_BoundBox, at);
440

    
441
                return m_BoundingBox;
442
        }
443

    
444
        /**
445
         * Rellena con el rect?ngulo que se pasa como par?metro el boundBox(en
446
         * cent?metros) del fframe del cual con una transformaci?n se podr?
447
         * calcular el BoundingBox (en pixels).
448
         *
449
         * @param r Rect?ngulo en cent?metros.
450
         */
451
        public void setBoundBox(Rectangle2D r) {
452
                m_BoundBox.setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
453
        }
454

    
455
        /**
456
         * Devuelve el rect?ngulo que representa el fframe en cent?metros.
457
         *
458
         * @return Rect?ngulo en centimetros.
459
         */
460
        public Rectangle2D.Double getBoundBox() {
461
                return m_BoundBox;
462
        }
463

    
464
        /**
465
         * Pasando como par?metro true,  se toma como que esta seleccionado el
466
         * fframe  y si es false como que esta sin seleccionar,  de esta forma se
467
         * selecciona un fframe directamente  sin comprobar si un punto esta
468
         * contenido en ?l.
469
         *
470
         * @param b true si se quiere seleccionar y false si se quiere
471
         *                   deseleccionar.
472
         */
473
        public void setSelected(boolean b) {
474
                if (b) {
475
                        m_Selected = RECT;
476
                } else {
477
                        m_Selected = NOSELECT;
478
                }
479
        }
480

    
481
        /**
482
         * Crea un Objeto FFrame seg?n el tipo que sea, a partir de la informaci?n
483
         * del XMLEntity.
484
         *
485
         * @param xml XMLEntity
486
         * @param l Layout.
487
         * @param p Proyecto.
488
         *
489
         * @return Objeto de esta clase.
490
         */
491
        public static IFFrame createFFrame(XMLEntity xml, Layout l, Project p) {
492
                IFFrame fframe = null;
493

    
494
                try {
495
                        Class clase = Class.forName(xml.getStringProperty("className"));
496
                        fframe = (IFFrame) clase.newInstance();
497
                } catch (Exception e) {
498
                        NotificationManager.addError("Clase de Frame sobre el Layout no reconocida",
499
                                e);
500
                }
501

    
502
                if (fframe instanceof FFrameView) {
503
                        ((FFrameView) fframe).setProject(p);
504
                }
505

    
506
                fframe.setXMLEntity(xml, l);
507
                fframe.setName(xml.getStringProperty("m_name"));
508
                fframe.setBoundBox(new Rectangle2D.Double(xml.getDoubleProperty("x"),
509
                                xml.getDoubleProperty("y"), xml.getDoubleProperty("w"),
510
                                xml.getDoubleProperty("h")));
511
                fframe.setTag(xml.getStringProperty("tag"));
512

    
513
                return fframe;
514
        }
515

    
516
        /**
517
         * Dibuja sobre el graphics el rect?ngulo del fframe en modo borrador.
518
         *
519
         * @param g Graphics so bre el que dibujar.
520
         */
521
        public void drawDraft(Graphics2D g) {
522
                Rectangle2D.Double r = getBoundingBox(null);
523
                g.setColor(Color.lightGray);
524
                g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
525
                g.setColor(Color.black);
526

    
527
                int scale = (int) (r.width / 12);
528
                Font f = new Font("SansSerif", Font.PLAIN, scale);
529
                g.setFont(f);
530
                g.drawString(getName(),
531
                        (int) (r.getCenterX() - ((getName().length() * scale) / 4)),
532
                        (int) (r.getCenterY()));
533
        }
534

    
535
        /**
536
         * Rellena con el n?mero de FFrame.
537
         *
538
         * @param i n?mero
539
         */
540
        public void setNum(int i) {
541
                num = i;
542
        }
543

    
544
        /**
545
         * Dibuja sobre el graphics el rect?ngulo del fframe pero vacio, mostrando
546
         * el nombre del fframe y vacio.
547
         *
548
         * @param g Graphics sobre el que dibujar.
549
         */
550
        public void drawEmpty(Graphics2D g) {
551
                Rectangle2D.Double r = getBoundingBox(null);
552
                g.setColor(Color.lightGray);
553
                g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
554
                g.setColor(Color.black);
555

    
556
                int scale = (int) (r.width / 12);
557
                Font f = new Font("SansSerif", Font.PLAIN, scale);
558
                g.setFont(f);
559

    
560
                String s = this.getNameFFrame() + " " +
561
                        PluginServices.getText(this, "vacia");
562

    
563
                g.drawString(s, (int) (r.getCenterX() - ((s.length() * scale) / 4)),
564
                        (int) (r.getCenterY()));
565
        }
566

    
567
        /**
568
         * Devuelve true si el rect?ngulo primero es null o si es distinto de null
569
         * e intersecta.
570
         *
571
         * @param rv Rect?ngulo
572
         * @param r Rect?ngulo
573
         *
574
         * @return True si intersecta o es null.
575
         */
576
        public boolean intersects(Rectangle2D rv, Rectangle2D r) {
577
                return (((rv != null) && rv.intersects(r)) || (rv == null));
578
        }
579

    
580
        /**
581
         * Abre el di?logo para cambiar o a?adir el tag.
582
         */
583
        public void openTag() {
584
                Tag tag = new Tag(this);
585
                PluginServices.getMDIManager().addView(tag);
586
        }
587

    
588
        /**
589
         * Rellena el tag del FFrame.
590
         *
591
         * @param s String que representa el valor a guardar en el tag.
592
         */
593
        public void setTag(String s) {
594
                tag = s;
595
        }
596

    
597
        /**
598
         * Devuelve el tag.
599
         *
600
         * @return tag.
601
         */
602
        public String getTag() {
603
                return tag;
604
        }
605

    
606
        /**
607
         * Dibuja sobre el graphics que se pasa como par?metro el icono que
608
         * representa que contiene un tag.
609
         *
610
         * @param g Graphics sobre el que dibujar el icono.
611
         */
612
        public void drawSymbolTag(Graphics2D g) {
613
                Rectangle2D.Double rec = getBoundingBox(null);
614

    
615
                try {
616
                        URL url = Abrir.class.getClassLoader().getResource("images/symbolTag.gif");
617
                        Image image = new ImageIcon(url).getImage();
618
                        g.drawImage(image, (int) rec.x, (int) rec.y, 25, 30, null);
619
                } catch (NullPointerException npe) {
620
                }
621
        }
622
        public IFFrame cloneFFrame(Layout l){
623
                return createFFrame(this.getXMLEntity(),l,((ProjectMap)l.getViewModel()).getProject());
624
        }
625
}