Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / gui / layout / fframes / FFrame.java @ 1420

History | View | Annotate | Download (16.2 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

    
57
import com.iver.utiles.XMLEntity;
58

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

    
70
import java.net.URL;
71

    
72
import javax.swing.ImageIcon;
73

    
74

    
75
/**
76
 * Clase que implementa la interface IFFrame con los m?todos por defecto de
77
 * todos los FFrames  que extenderan de este, dejando uno como m?todo
78
 * abstracto para implementar por todos los  FFrames para ser dibujados.
79
 *
80
 * @author Vicente Caballero Navarro
81
 */
82
public abstract class FFrame implements IFFrame {
83
        private static final int N = 1;
84
        private static final int NE = 2;
85
        private static final int E = 3;
86
        private static final int SE = 4;
87
        private static final int S = 5;
88
        private static final int SO = 6;
89
        private static final int O = 7;
90
        private static final int NO = 8;
91
        private static final int RECT = 9;
92

    
93
        /** FFrame no selecccionado. */
94
        public static final int NOSELECT = 0;
95
        protected String m_name = "FFrame";
96
        private Rectangle2D.Double m_BoundBox = new Rectangle2D.Double();
97
        private Rectangle2D.Double m_BoundingBox = new Rectangle2D.Double();
98
        protected int m_Selected = 0;
99
        private Rectangle n = new Rectangle();
100
        private Rectangle ne = new Rectangle();
101
        private Rectangle e = new Rectangle();
102
        private Rectangle se = new Rectangle();
103
        private Rectangle s = new Rectangle();
104
        private Rectangle so = new Rectangle();
105
        private Rectangle o = new Rectangle();
106
        private Rectangle no = new Rectangle();
107
        private String tag = null;
108
        protected int num = 0;
109

    
110
        /**
111
         * Dibuja los handlers sobre el boundingBox en el graphics que se pasa como
112
         * par?metro.
113
         *
114
         * @param g Graphics sobre el que dibujar.
115
         */
116
        public void drawHandlers(Graphics2D g) {
117
                int size = 10;
118
                Rectangle2D.Double r = getBoundingBox(null);
119

    
120
                //g.drawRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
121
                g.fillRect((int) r.x - size, (int) r.y - size, size, size);
122
                no.setRect((int) r.x - size, (int) r.y - size, size, size);
123
                g.fillRect((int) r.getMaxX(), (int) r.y - size, size, size);
124
                ne.setRect((int) r.getMaxX(), (int) r.y - size, size, size);
125
                g.fillRect((int) r.x - size, (int) r.getMaxY(), size, size);
126
                so.setRect((int) r.x - size, (int) r.getMaxY(), size, size);
127
                g.fillRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
128
                se.setRect((int) r.getMaxX(), (int) r.getMaxY(), size, size);
129
                g.fillRect((int) r.getCenterX() - (size / 2), (int) r.y - size, size,
130
                        size);
131
                n.setRect((int) r.getCenterX() - (size / 2), (int) r.y - size, size,
132
                        size);
133
                g.fillRect((int) r.getCenterX() - (size / 2), (int) r.getMaxY(), size,
134
                        size);
135
                s.setRect((int) r.getCenterX() - (size / 2), (int) r.getMaxY(), size,
136
                        size);
137
                g.fillRect((int) r.x - size, (int) r.getCenterY() - (size / 2), size,
138
                        size);
139
                o.setRect((int) r.x - size, (int) r.getCenterY() - (size / 2), size,
140
                        size);
141
                g.fillRect((int) r.getMaxX(), (int) r.getCenterY() - (size / 2), size,
142
                        size);
143
                e.setRect((int) r.getMaxX(), (int) r.getCenterY() - (size / 2), size,
144
                        size);
145
        }
146

    
147
        /**
148
         * Establece que tipo de selecci?n se realiza sobre el fframe.
149
         *
150
         * @param p punto sobre el que se debe de establecer si se selecciona o no
151
         *                   el fframe.
152
         */
153
        public void setSelected(Point2D.Double p) {
154
                m_Selected = getContains(p);
155
        }
156

    
157
        /**
158
         * Actualiza el BoundBox del FFrame a partir de su rect?ngulo en pixels y
159
         * la matriz de transformaci?n.
160
         *
161
         * @param r Rect?ngulo.
162
         * @param at Matriz de transformaci?n.
163
         */
164
        public void updateRect(Rectangle2D r, AffineTransform at) {
165
                Rectangle2D.Double rec = FLayoutUtilities.toSheetRect(r, at);
166
                rec.setRect((int) rec.getMinX(), (int) rec.getMinY(),
167
                        (int) rec.getWidth(), (int) rec.getHeight());
168
                setBoundBox(rec);
169
        }
170

    
171
        /**
172
         * Devuelve el rect?ngulo a partir del desplazamiento en el eje x y el
173
         * desplazamiento en el eje y.
174
         *
175
         * @param difx desplazamiento sobre el eje x.
176
         * @param dify desplazamiento sobre el eje y.
177
         *
178
         * @return rect?ngulo modificado en funci?n del desplazamiento realizado.
179
         */
180
        public Rectangle2D getMovieRect(int difx, int dify) {
181
                double x = 0;
182
                double y = 0;
183
                double w = 0;
184
                double h = 0;
185

    
186
                Rectangle2D.Double rectaux = new Rectangle2D.Double(this.getBoundingBox(
187
                                        null).x, this.getBoundingBox(null).y,
188
                                this.getBoundingBox(null).width,
189
                                this.getBoundingBox(null).height);
190
                Rectangle2D.Double rec = this.getBoundingBox(null);
191
                int difn = 0;
192
                difn = difx;
193
                x = rectaux.x;
194
                y = rectaux.y;
195
                w = rectaux.width;
196
                h = rectaux.height;
197

    
198
                switch (this.getSelected()) {
199
                        case (RECT):
200
                                rectaux.setRect((x + difx), (y + dify), w, h);
201

    
202
                                break;
203

    
204
                        case (N):
205

    
206
                                if ((y + dify) > rec.getMaxY()) {
207
                                        y = rec.getMaxY();
208
                                } else {
209
                                        y = y + dify;
210
                                }
211

    
212
                                rectaux.setRect(x, y, w, Math.abs(h - dify));
213

    
214
                                break;
215

    
216
                        case (O):
217

    
218
                                if ((x + difx) > rec.getMaxX()) {
219
                                        x = rec.getMaxX();
220
                                } else {
221
                                        x = x + difx;
222
                                }
223

    
224
                                rectaux.setRect(x, y, Math.abs(w - difx), h);
225

    
226
                                break;
227

    
228
                        case (S):
229

    
230
                                if (y > (rec.getMaxY() + dify)) {
231
                                        y = rec.getMaxY() + dify;
232
                                }
233

    
234
                                rectaux.setRect(x, y, w, Math.abs(h + dify));
235

    
236
                                break;
237

    
238
                        case (E):
239

    
240
                                if (x > (rec.getMaxX() + difx)) {
241
                                        x = rec.getMaxX() + difx;
242
                                }
243

    
244
                                rectaux.setRect(x, y, Math.abs(w + difx), h);
245

    
246
                                break;
247

    
248
                        case (NE):
249

    
250
                                if ((y - difn) > rec.getMaxY()) {
251
                                        y = rec.getMaxY();
252
                                        x = rec.getMaxX() + difn;
253
                                } else {
254
                                        y = y - difn;
255
                                }
256

    
257
                                rectaux.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
258

    
259
                                break;
260

    
261
                        case (NO):
262

    
263
                                if ((y + difn) > rec.getMaxY()) {
264
                                        y = rec.getMaxY();
265
                                        x = rec.getMaxX();
266
                                } else {
267
                                        x = x + difn;
268
                                        y = y + difn;
269
                                }
270

    
271
                                rectaux.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
272

    
273
                                break;
274

    
275
                        case (SE):
276

    
277
                                if (y > (rec.getMaxY() + difn)) {
278
                                        y = rec.getMaxY() + difn;
279
                                        x = rec.getMaxX() + difn;
280
                                }
281

    
282
                                rectaux.setRect(x, y, Math.abs(w + difn), Math.abs(h + difn));
283

    
284
                                break;
285

    
286
                        case (SO):
287

    
288
                                if ((x + difn) > rec.getMaxX()) {
289
                                        x = rec.getMaxX();
290
                                        y = rec.getMaxY() - difn;
291
                                } else {
292
                                        x = x + difn;
293
                                }
294

    
295
                                rectaux.setRect(x, y, Math.abs(w - difn), Math.abs(h - difn));
296

    
297
                                break;
298

    
299
                        default:
300
                                rectaux.setRect((x), (y), w, h);
301
                }
302

    
303
                return rectaux;
304
        }
305

    
306
        /**
307
         * Devuelve un entero que representa el tipo de selecci?n que se ha
308
         * realizado sobre el fframe.
309
         *
310
         * @return tipo de selecci?n que se ha realizado.
311
         */
312
        public int getSelected() {
313
                return m_Selected;
314
        }
315

    
316
        /**
317
         * Devuelve true, si el punto que se pasa como par?metro esta contenido
318
         * dentro del boundingbox del fframe.
319
         *
320
         * @param p punto a comprobar.
321
         *
322
         * @return true si el punto esta dentro del boundingbox.
323
         */
324
        public boolean contains(Point2D.Double p) {
325
                return getBoundingBox(null).contains(p.x, p.y);
326
        }
327

    
328
        /**
329
         * Devuelve un entero que representa donde esta contenido el punto que se
330
         * pasa como par?metro.
331
         *
332
         * @param p punto a comparar.
333
         *
334
         * @return entero que representa como esta contenido el punto.
335
         */
336
        public int getContains(Point2D.Double p) {
337
                if (n.contains(p.x, p.y)) {
338
                        return N;
339
                } else if (ne.contains(p.x, p.y)) {
340
                        return NE;
341
                } else if (e.contains(p.x, p.y)) {
342
                        return E;
343
                } else if (e.contains(p.x, p.y)) {
344
                        return E;
345
                } else if (se.contains(p.x, p.y)) {
346
                        return SE;
347
                } else if (s.contains(p.x, p.y)) {
348
                        return S;
349
                } else if (so.contains(p.x, p.y)) {
350
                        return SO;
351
                } else if (o.contains(p.x, p.y)) {
352
                        return O;
353
                } else if (no.contains(p.x, p.y)) {
354
                        return NO;
355
                } else if (getBoundingBox(null).contains(p.x, p.y)) {
356
                        return RECT;
357
                }
358

    
359
                return 0;
360
        }
361

    
362
        /**
363
         * Devuelve el Cursor adecuado seg?n como est? contenido el punto, si es
364
         * para desplazamiento, o cambio de tama?o.
365
         *
366
         * @param p punto a comprobar.
367
         *
368
         * @return Cursor adecuado a la posici?n.
369
         */
370
        public Cursor getMapCursor(Point2D.Double p) {
371
                int select = getContains(p);
372

    
373
                switch (select) {
374
                        case (N):
375
                                return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
376

    
377
                        case (NE):
378
                                return Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
379

    
380
                        case (E):
381
                                return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
382

    
383
                        case (SE):
384
                                return Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
385

    
386
                        case (S):
387
                                return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
388

    
389
                        case (SO):
390
                                return Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
391

    
392
                        case (O):
393
                                return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
394

    
395
                        case (NO):
396
                                return Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
397

    
398
                        case (RECT):
399
                                return Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
400
                }
401

    
402
                return null;
403
        }
404

    
405
        /**
406
         * Este m?todo se implementa en cada una de las fframe, ya que cada una se
407
         * dibuja de una forma diferente sobre el graphics. M?todo que dibuja
408
         * sobre el graphics que se le pasa como par?metro, seg?n la transformada
409
         * afin que se debe de aplicar y el rect?ngulo que se debe de dibujar.
410
         * M?todo que dibuja sobre el graphics que se le pasa como par?metro,
411
         * seg?n la transformada afin que se debe de aplicar y el rect?ngulo que
412
         * se debe de dibujar.
413
         *
414
         * @param g Graphics
415
         * @param at Transformada afin.
416
         * @param r rect?ngulo sobre el que hacer un clip.
417
         * @param imgBase DOCUMENT ME!
418
         *
419
         * @throws DriverException
420
         */
421
        public abstract void draw(Graphics2D g, AffineTransform at, Rectangle2D r,
422
                BufferedImage imgBase) throws DriverException;
423

    
424
        /**
425
         * Devuelve el nombre que representa al fframe.
426
         *
427
         * @return String
428
         */
429
        public String getName() {
430
                return m_name;
431
        }
432

    
433
        /**
434
         * Rellena el String que representa al nombre del fframe.
435
         *
436
         * @param n nombre del fframe.
437
         */
438
        public void setName(String n) {
439
                m_name = n;
440
        }
441

    
442
        /**
443
         * Devuelve el boundingBox del fframe en funci?n de la transformada af?n
444
         * que se pasa como par?metro. Si se pasa como par?metro null, devuelve el
445
         * ?ltimo boundingbox que se calcul?.
446
         *
447
         * @param at Transformada af?n
448
         *
449
         * @return Rect?ngulo que representa el BoundingBox del fframe.
450
         */
451
        public Rectangle2D.Double getBoundingBox(AffineTransform at) {
452
                if (at == null) {
453
                        return m_BoundingBox;
454
                }
455

    
456
                m_BoundingBox = FLayoutUtilities.fromSheetRect(m_BoundBox, at);
457

    
458
                return m_BoundingBox;
459
        }
460

    
461
        /**
462
         * Rellena con el rect?ngulo que se pasa como par?metro el boundBox(en
463
         * cent?metros) del fframe del cual con una transformaci?n se podr?
464
         * calcular el BoundingBox (en pixels).
465
         *
466
         * @param r Rect?ngulo en cent?metros.
467
         */
468
        public void setBoundBox(Rectangle2D.Double r) {
469
                m_BoundBox.setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
470
        }
471

    
472
        /**
473
         * Devuelve el rect?ngulo que representa el fframe en cent?metros.
474
         *
475
         * @return Rect?ngulo en centimetros.
476
         */
477
        public Rectangle2D.Double getBoundBox() {
478
                return m_BoundBox;
479
        }
480

    
481
        /**
482
         * Pasando como par?metro true,  se toma como que esta seleccionado el
483
         * fframe  y si es false como que esta sin seleccionar,  de esta forma se
484
         * selecciona un fframe directamente  sin comprobar si un punto esta
485
         * contenido en ?l.
486
         *
487
         * @param b true si se quiere seleccionar y false si se quiere
488
         *                   deseleccionar.
489
         */
490
        public void setSelected(boolean b) {
491
                if (b) {
492
                        m_Selected = RECT;
493
                } else {
494
                        m_Selected = NOSELECT;
495
                }
496
        }
497

    
498
        /**
499
         * Crea un Objeto FFrame seg?n el tipo que sea, a partir de la informaci?n
500
         * del XMLEntity.
501
         *
502
         * @param xml XMLEntity
503
         * @param l Layout.
504
         * @param p Proyecto.
505
         *
506
         * @return Objeto de esta clase.
507
         */
508
        public static IFFrame createFFrame(XMLEntity xml, Layout l, Project p) {
509
                IFFrame fframe = null;
510

    
511
                try {
512
                        Class clase = Class.forName(xml.getStringProperty("className"));
513
                        fframe = (IFFrame) clase.newInstance();
514
                } catch (Exception e) {
515
                        NotificationManager.addError("Clase de Frame sobre el Layout no reconocida",
516
                                e);
517
                }
518

    
519
                if (fframe instanceof FFrameView) {
520
                        ((FFrameView) fframe).setProject(p);
521
                }
522

    
523
                fframe.setXMLEntity(xml, l);
524
                fframe.setName(xml.getStringProperty("m_name"));
525
                fframe.setBoundBox(new Rectangle2D.Double(xml.getDoubleProperty("x"),
526
                                xml.getDoubleProperty("y"), xml.getDoubleProperty("w"),
527
                                xml.getDoubleProperty("h")));
528
                fframe.setTag(xml.getStringProperty("tag"));
529

    
530
                return fframe;
531
        }
532

    
533
        /**
534
         * Dibuja sobre el graphics el rect?ngulo del fframe en modo borrador.
535
         *
536
         * @param g Graphics so bre el que dibujar.
537
         */
538
        public void drawDraft(Graphics2D g) {
539
                Rectangle2D.Double r = getBoundingBox(null);
540
                g.setColor(Color.lightGray);
541
                g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
542
                g.setColor(Color.black);
543

    
544
                int scale = (int) (r.width / 12);
545
                Font f = new Font("SansSerif", Font.PLAIN, scale);
546
                g.setFont(f);
547
                g.drawString(getName(),
548
                        (int) (r.getCenterX() - ((getName().length() * scale) / 4)),
549
                        (int) (r.getCenterY()));
550
        }
551

    
552
        /**
553
         * Rellena con el n?mero de FFrame.
554
         *
555
         * @param i n?mero
556
         */
557
        public void setNum(int i) {
558
                num = i;
559
        }
560

    
561
        /**
562
         * Dibuja sobre el graphics el rect?ngulo del fframe pero vacio, mostrando
563
         * el nombre del fframe y vacio.
564
         *
565
         * @param g Graphics sobre el que dibujar.
566
         */
567
        public void drawEmpty(Graphics2D g) {
568
                Rectangle2D.Double r = getBoundingBox(null);
569
                g.setColor(Color.lightGray);
570
                g.fillRect((int) r.x, (int) r.y, (int) r.width, (int) r.height);
571
                g.setColor(Color.black);
572

    
573
                int scale = (int) (r.width / 12);
574
                Font f = new Font("SansSerif", Font.PLAIN, scale);
575
                g.setFont(f);
576

    
577
                String s = this.getNameFFrame() + " " +
578
                        PluginServices.getText(this, "vacia");
579

    
580
                g.drawString(s, (int) (r.getCenterX() - ((s.length() * scale) / 4)),
581
                        (int) (r.getCenterY()));
582
        }
583

    
584
        /**
585
         * Devuelve true si el rect?ngulo primero es null o si es distinto de null
586
         * e intersecta.
587
         *
588
         * @param rv Rect?ngulo
589
         * @param r Rect?ngulo
590
         *
591
         * @return True si intersecta o es null.
592
         */
593
        public boolean intersects(Rectangle2D rv, Rectangle2D r) {
594
                return (((rv != null) && rv.intersects(r)) || (rv == null));
595
        }
596

    
597
        /**
598
         * Abre el di?logo para cambiar o a?adir el tag.
599
         */
600
        public void openTag() {
601
                Tag tag = new Tag(this);
602
                PluginServices.getMDIManager().addView(tag);
603
        }
604

    
605
        /**
606
         * Rellena el tag del FFrame.
607
         *
608
         * @param s String que representa el valor a guardar en el tag.
609
         */
610
        public void setTag(String s) {
611
                tag = s;
612
        }
613

    
614
        /**
615
         * Devuelve el tag.
616
         *
617
         * @return tag.
618
         */
619
        public String getTag() {
620
                return tag;
621
        }
622

    
623
        /**
624
         * Dibuja sobre el graphics que se pasa como par?metro el icono que
625
         * representa que contiene un tag.
626
         *
627
         * @param g Graphics sobre el que dibujar el icono.
628
         */
629
        public void drawSymbolTag(Graphics2D g) {
630
                Rectangle2D.Double rec = getBoundingBox(null);
631

    
632
                try {
633
                        URL url = Abrir.class.getClassLoader().getResource("images/symbolTag.gif");
634
                        Image image = new ImageIcon(url).getImage();
635
                        g.drawImage(image, (int) rec.x, (int) rec.y, 25, 30, null);
636
                } catch (NullPointerException npe) {
637
                }
638
        }
639
}