Statistics
| Revision:

root / trunk / libraries / libCorePlugin / src / com / iver / core / mdiManager / NewSkin.java @ 3002

History | View | Annotate | Download (16.7 KB)

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

    
43
import java.awt.BorderLayout;
44
import java.awt.Component;
45
import java.awt.Cursor;
46
import java.awt.event.ActionEvent;
47
import java.awt.event.ActionListener;
48
import java.awt.event.WindowAdapter;
49
import java.awt.event.WindowEvent;
50
import java.beans.PropertyVetoException;
51
import java.util.ArrayList;
52
import java.util.Iterator;
53
import java.util.Stack;
54

    
55
import javax.swing.DefaultDesktopManager;
56
import javax.swing.DesktopManager;
57
import javax.swing.JDesktopPane;
58
import javax.swing.JDialog;
59
import javax.swing.JInternalFrame;
60
import javax.swing.JLayeredPane;
61
import javax.swing.event.InternalFrameEvent;
62
import javax.swing.event.InternalFrameListener;
63

    
64
import org.apache.log4j.Logger;
65

    
66
import com.iver.andami.plugins.Extension;
67
import com.iver.andami.ui.mdiFrame.GlassPane;
68
import com.iver.andami.ui.mdiFrame.MDIFrame;
69
import com.iver.andami.ui.mdiManager.MDIManager;
70
import com.iver.andami.ui.mdiManager.MDIUtilities;
71
import com.iver.andami.ui.mdiManager.SingletonDialogAlreadyShownException;
72
import com.iver.andami.ui.mdiManager.SingletonView;
73
import com.iver.andami.ui.mdiManager.View;
74
import com.iver.andami.ui.mdiManager.ViewInfo;
75
import com.iver.andami.ui.mdiManager.ViewListener;
76

    
77

    
78
/**
79
 *
80
 */
81
public class NewSkin implements MDIManager, Extension {
82
        /**
83
         * Variable privada <code>desktopManager</code> para usarlo cuando sale una
84
         * ventana que no queremos que nos restaure las que tenemos maximizadas.
85
         * Justo antes de usar el setMaximize(false), le pegamos el cambiazo.
86
         */
87
        private static DesktopManager desktopManager = new DefaultDesktopManager();
88

    
89
        /** log */
90
        private static Logger logger = Logger.getLogger(NewSkin.class.getName());
91

    
92
        /** Panel de la MDIFrame */
93
        private JDesktopPane panel = new JDesktopPane();
94

    
95
        /** MDIFrame */
96
        private MDIFrame mainFrame;
97
        private GlassPane glassPane = new GlassPane();
98
        private DialogStackSupport dss;
99
        private FrameViewSupport fvs;
100
        private ViewInfoSupport vis;
101
        private ViewStackSupport vss;
102
        private SingletonViewSupport svs;
103
    private Cursor lastCursor = null;
104
    
105
        /**
106
         * @see com.iver.andami.ui.mdiManager.MDIManager#init(com.iver.andami.ui.mdiFrame.MDIFrame)
107
         */
108
        public void init(MDIFrame f) {
109
                //Inicializa el Frame y la consola
110
                mainFrame = f;
111
                mainFrame.setGlassPane(glassPane);
112
                panel.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
113

    
114
                mainFrame.getContentPane().add(panel, BorderLayout.CENTER);
115
                panel.setDesktopManager(desktopManager);
116

    
117
                fvs = new FrameViewSupport(mainFrame);
118
                dss = new DialogStackSupport(mainFrame);
119
                svs = new SingletonViewSupport(vis, fvs);
120
                vis = new ViewInfoSupport(mainFrame, fvs, svs);
121
                fvs.setVis(vis);
122
                vss = new ViewStackSupport(vis);
123
        }
124

    
125
        /**
126
         * @see com.iver.andami.ui.mdiManager.MDIManager#addView(com.iver.andami.ui.mdiManager.View)
127
         */
128
        public View addView(View p) throws SingletonDialogAlreadyShownException {
129
                //se obtiene la informaci?n de la vista
130
                ViewInfo vi = vis.getViewInfo(p);
131

    
132
                //Se comprueban las incompatibilidades que pudieran haber en la vista
133
                MDIUtilities.checkViewInfo(vi);
134
                if ((p instanceof SingletonView) && (vi.isModal())){
135
                        throw new RuntimeException("A modal view cannot be a SingletonView");                        
136
                }
137

    
138
        // FJP: Las ventanas tipo palete se a?aden sin pasar por
139
        // los registros para que no les afecte el cambio de menus.
140
        // Ellas ser?n las responsables de mostrarse o no con
141
        // c?digo dentro de su plugin. Adem?s, se ponen
142
        // por encima del resto de ventanas.
143
        if (vi.isPalette())
144
        {
145
            JLayeredPane lyrPane = mainFrame.getLayeredPane();
146
            JInternalFrame nuevo =  fvs.createJInternalFrame(p);
147
            lyrPane.add(nuevo, JDesktopPane.PALETTE_LAYER);
148
            return p;
149
        }
150
 
151
        
152
                /*
153
                 * Se obtiene la referencia a la vista anterior por si es una singleton y est?
154
                 * siendo mostrada. Se obtiene su informaci?n si ya fue mostrada
155
                 */
156
                boolean singletonPreviouslyAdded = false;
157
                
158
                if (p instanceof SingletonView){
159
                        SingletonView sv = (SingletonView) p;
160
                        if (svs.registerView(sv.getClass(), sv.getViewModel(), vis.getViewInfo(sv))){
161
                                singletonPreviouslyAdded = true;
162
                        }
163
                }
164

    
165
                if (singletonPreviouslyAdded){
166
                        //Si la vista no est? actualmente abierta
167
                        if (!svs.contains((SingletonView)p)){
168
                                JInternalFrame frame = fvs.getJInternalFrame(p);
169
                                svs.openSingletonView((SingletonView)p, frame);
170
                                addJInternalFrame(frame, vi);
171
                                vss.add(p,
172
                                                new ActionListener() {
173
                                                        public void actionPerformed(ActionEvent e) {
174
                                                                View v = vis.getViewById(Integer.parseInt(
175
                                                                                        e.getActionCommand()));
176
                                                                JInternalFrame f = fvs.getJInternalFrame(v);
177
                                                                activateJInternalFrame(f);
178
                                                        }
179
                                                });
180
                                return p;
181
                        }else{
182
                                //La vista est? actualmente abierta
183
                                JInternalFrame frame = (JInternalFrame) svs.getFrame((SingletonView)p);
184
                                activateJInternalFrame(frame);
185
                vss.setActive(p);
186
                                return fvs.getView((JInternalFrame) frame);
187
                        }
188
                } else {
189
                        if (vi.isModal()) {
190
                                addJDialog(p);
191
                        } else {
192
                                //Se sit?a la vista en la pila de vistas
193
                                vss.add(p,
194
                                        new ActionListener() {
195
                                                public void actionPerformed(ActionEvent e) {
196
                                                        View v = vis.getViewById(Integer.parseInt(
197
                                                                                e.getActionCommand()));
198
                                                        JInternalFrame f = fvs.getJInternalFrame(v);
199
                                                        activateJInternalFrame(f);
200
                                                }
201
                                        });
202
                                addJInternalFrame(p);
203
                        }
204

    
205
                        return p;
206
                }
207
        }
208

    
209
        /**
210
         * DOCUMENT ME!
211
         *
212
         * @param wnd DOCUMENT ME!
213
         * @param vi DOCUMENT ME!
214
         */
215
        private void addJInternalFrame(JInternalFrame wnd, ViewInfo vi) {
216
                wnd.addInternalFrameListener(new FrameListener());
217

    
218
                wnd.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
219
                
220
                if (vi.isModeless()) {
221
                        panel.add(wnd, JDesktopPane.PALETTE_LAYER);
222
                } else {
223
                        panel.add(wnd);
224
                }
225

    
226
                activateJInternalFrame(wnd);
227
        }
228

    
229
        /**
230
         * DOCUMENT ME!
231
         *
232
         * @param p
233
         */
234
        private void addJInternalFrame(View p) {
235
                ViewInfo vi = vis.getViewInfo(p);
236

    
237
                JInternalFrame wnd = fvs.getJInternalFrame(p);
238

    
239
                if (p instanceof SingletonView){
240
                        SingletonView sv = (SingletonView) p;
241
                        svs.openSingletonView(sv, wnd);
242
                }
243

    
244
                addJInternalFrame(wnd, vi);
245
        }
246

    
247
        /**
248
         * DOCUMENT ME!
249
         *
250
         * @param wnd
251
         */
252
        private void activateJInternalFrame(JInternalFrame wnd) {
253
                try {
254
                        wnd.moveToFront();
255
            logger.debug("Activando " + wnd.getTitle());
256
                        wnd.setSelected(true);
257
                        wnd.setIcon(false);
258
                } catch (PropertyVetoException e) {
259
                        logger.error(e);
260
                }
261
        }
262

    
263
        /**
264
         * Situa un di?logo modal en el centro de la pantalla
265
         *
266
         * @param d Di?logo que se quiere situar
267
         */
268
        private void centerDialog(JDialog d) {
269
                int offSetX = d.getWidth() / 2;
270
                int offSetY = d.getHeight() / 2;
271

    
272
                d.setLocation((mainFrame.getWidth() / 2) - offSetX,
273
                        (mainFrame.getHeight() / 2) - offSetY);
274
        }
275

    
276
        /**
277
         * DOCUMENT ME!
278
         *
279
         * @param p
280
         */
281
        private void addJDialog(View p) {
282
                JDialog dlg = fvs.getJDialog(p);
283

    
284
                centerDialog(dlg);
285

    
286
                dlg.addWindowListener(new DialogWindowListener());
287
                dss.pushDialog(dlg);
288

    
289
                dlg.setVisible(vis.getViewInfo(p).isVisible());
290
        }
291

    
292
        /**
293
         * @see com.iver.andami.ui.mdiManager.MDIManager#getActiveView()
294
         */
295
        public View getActiveView() {
296
                JInternalFrame jif = panel.getSelectedFrame();
297

    
298
                if (jif != null) {
299
                        return fvs.getView(jif);
300
                }
301

    
302
                return null;
303
        }
304

    
305
        /**
306
         * @see com.iver.andami.ui.mdiManager.MDIManager#closeView(com.iver.andami.ui.mdiManager.View)
307
         */
308
        public void closeView(View p) {
309
                //Si es un di?logo modal 
310
                if (p.getViewInfo().isModal()) {
311
                        closeJDialog();
312
                } else { //Si no es modal se cierra el JInternalFrame
313
                        closeJInternalFrame(fvs.getJInternalFrame(p));
314
                }
315
        }
316

    
317
        /**
318
         * @see com.iver.andami.ui.mdiManager.MDIManager#closeAllViews()
319
         */
320
        public void closeAllViews() {
321
                ArrayList eliminar = new ArrayList();
322
                Iterator i = fvs.getViewIterator();
323

    
324
                while (i.hasNext()) {
325
                        eliminar.add((View) i.next());
326
                }
327

    
328
                for (Iterator iter = eliminar.iterator(); iter.hasNext();) {
329
                        View vista = (View) iter.next();
330
                        closeView(vista);
331
                }
332
        }
333

    
334
        /**
335
         * @see com.iver.andami.ui.mdiManager.MDIManager#getViewInfo(com.iver.andami.ui.mdiManager.View)
336
         */
337
        public ViewInfo getViewInfo(View v) {
338
                return vis.getViewInfo(v);
339
        }
340

    
341
        /**
342
         * DOCUMENT ME!
343
         *
344
         * @param dialog
345
         *
346
         * @throws RuntimeException DOCUMENT ME!
347
         */
348
        private void closeJDialog() {
349
                JDialog dlg = dss.popDialog();
350

    
351
                dlg.setVisible(false);
352

    
353
                View s = (View) fvs.getView(dlg);
354

    
355
                callViewClosed(s);
356

    
357
                fvs.closeView(s);
358

    
359
                //Si es singleton se desasocia el modelo con la vista
360
                if (s instanceof SingletonView) {
361
                        svs.closeView((SingletonView) s);
362
                }
363
        }
364

    
365
        /**
366
         * DOCUMENT ME!
367
         *
368
         * @param view DOCUMENT ME!
369
         */
370
        private void callViewClosed(View view) {
371
                if (view instanceof ViewListener) {
372
                        ((ViewListener) view).viewClosed();
373
                }
374
        }
375

    
376
        /**
377
         * DOCUMENT ME!
378
         *
379
         * @param view DOCUMENT ME!
380
         */
381
        private void callViewActivated(View view) {
382
        logger.debug("View " + view.getViewInfo().getTitle()+ " activated (callViewActivated)");
383
                if (view instanceof ViewListener) {
384
                        ((ViewListener) view).viewActivated();
385
                }
386
        }
387

    
388
        /**
389
         * DOCUMENT ME!
390
         *
391
         * @param frame
392
         */
393
        private void closeJInternalFrame(JInternalFrame frame) {
394
                try {
395
                        View s = (View) fvs.getView(frame);
396

    
397
                        frame.setClosed(true);
398
                        callViewClosed(s);
399
                } catch (PropertyVetoException e) {
400
                        logger.error("Not compatible with property veto's. Use ViewInfo instead.",
401
                                e);
402
                }
403
        }
404

    
405
        /**
406
         * @see com.iver.andami.plugins.Extension#inicializar()
407
         */
408
        public void inicializar() {
409
        }
410

    
411
        /**
412
         * @see com.iver.andami.plugins.Extension#execute(java.lang.String)
413
         */
414
        public void execute(String actionCommand) {
415
                if (actionCommand.equals("cascada")) {
416
                } else if (actionCommand.equals("mosaico")) {
417
                }
418
        }
419

    
420
        /**
421
         * @see com.iver.andami.plugins.Extension#isEnabled()
422
         */
423
        public boolean isEnabled() {
424
                // TODO Auto-generated method stub
425
                return false;
426
        }
427

    
428
        /**
429
         * @see com.iver.andami.plugins.Extension#isVisible()
430
         */
431
        public boolean isVisible() {
432
                // TODO Auto-generated method stub
433
                return true;
434
        }
435

    
436
        /**
437
         * @see com.iver.andami.ui.mdiManager.MDIManager#setWaitCursor()
438
         */
439
        public void setWaitCursor() {
440
                if (mainFrame != null) {
441
                        glassPane.setVisible(true);
442
            lastCursor = mainFrame.getCursor();                        
443
                        dss.setWaitCursor();
444
            mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
445
                }
446
        }
447

    
448
        /**
449
         * @see com.iver.andami.ui.mdiManager.MDIManager#restoreCursor()
450
         */
451
        public void restoreCursor() {
452
                if (mainFrame != null) {
453
                        glassPane.setVisible(false);                        
454
                        dss.restoreCursor();
455
            mainFrame.setCursor(lastCursor);
456
                }
457
        }
458

    
459
        /**
460
         * Listener para los eventos de cerrado de los di?logos. Tiene su raz?n de
461
         * ser en que los di?logos han de devolverse al pool cuando se cierran
462
         *
463
         * @author Fernando Gonz?lez Cort?s
464
         */
465
        public class DialogWindowListener extends WindowAdapter {
466
                /**
467
                 * Captura el evento de cerrado de los di?logos con el fin de realizar
468
                 * tareas de mantenimiento
469
                 *
470
                 * @param e evento
471
                 */
472
                public void windowClosing(WindowEvent e) {
473
                        closeJDialog();
474
                }
475
        }
476

    
477
        /**
478
         * DOCUMENT ME!
479
         */
480
        public class FrameListener implements InternalFrameListener {
481
                /**
482
                 * @see javax.swing.event.InternalFrameListener#internalFrameActivated(javax.swing.event.InternalFrameEvent)
483
                 */
484
                public void internalFrameActivated(InternalFrameEvent e) {
485
            logger.debug("internalFrameActivated " + e.getInternalFrame().getTitle());
486
            
487
            // activatedInternalFramesStack.push(e.getInternalFrame());
488
            
489
                        View panel = fvs.getView((JInternalFrame) e.getSource());
490
            vss.setActive(panel);
491
                        ViewInfo vi = vis.getViewInfo(panel);
492

    
493
                        JInternalFrame frame = fvs.getJInternalFrame(panel);
494

    
495
                        if (!frame.isMaximizable() && frame.isMaximum()) {
496
                                try {
497
                                        frame.setMaximum(false);
498
                                } catch (PropertyVetoException e1) {
499
                                }
500
                        }
501
                        mainFrame.enableControls();
502
            if (vi.getSelectedTool() != null)
503
                mainFrame.setSelectedTool(vi.getSelectedTool());
504
                        callViewActivated(panel);
505

    
506
                        
507
                }
508

    
509
                /**
510
                 * @see javax.swing.event.InternalFrameListener#internalFrameClosed(javax.swing.event.InternalFrameEvent)
511
                 */
512
                public void internalFrameClosed(InternalFrameEvent e) {
513
                }
514

    
515
                /**
516
                 * @see javax.swing.event.InternalFrameListener#internalFrameClosing(javax.swing.event.InternalFrameEvent)
517
                 */
518
                public void internalFrameClosing(InternalFrameEvent e) {
519
                        // Se elimina la memoria del JInternalFrame si no es ALWAYS_LIVE
520
            logger.debug("internalFrameClosing " + e.getInternalFrame().getTitle());
521
            
522
                        JInternalFrame c = (JInternalFrame) e.getSource();
523
                        ViewInfo vi = vis.getViewInfo((View) fvs.getView(c));
524

    
525
                        View view = fvs.getView(c);
526

    
527
                        boolean alwaysLive;
528
                        if (view instanceof SingletonView) {
529
                                svs.closeView((SingletonView) view);
530
                        }
531

    
532
                        fvs.closeView(view);
533
            
534
                        panel.remove(c);
535

    
536
                        vss.remove(view);
537

    
538
                        mainFrame.enableControls();
539

    
540
                        panel.repaint();
541
            
542
            // Para activar el JInternalFrame desde la que hemos
543
            // abierto la ventana que estamos cerrando
544
            View lastView = vss.getActiveView();
545
            // La activamos
546
            if (lastView != null)
547
            {
548
                System.err.println("Devuelvo el foco a " + lastView.getViewInfo().getTitle());
549
                JInternalFrame frame = fvs.getJInternalFrame(lastView);
550
                try {
551
                    frame.setSelected(true);
552
                } catch (PropertyVetoException e1) {
553
                    // TODO Auto-generated catch block
554
                    // e1.printStackTrace();
555
                }
556
                // addView(lastView);
557
            }
558

    
559
                }
560

    
561
                /**
562
                 * @see javax.swing.event.InternalFrameListener#internalFrameDeactivated(javax.swing.event.InternalFrameEvent)
563
                 */
564
                public void internalFrameDeactivated(InternalFrameEvent e) {
565
            logger.debug("internalDeActivated " + e.getInternalFrame().getTitle());
566
            JInternalFrame c = (JInternalFrame) e.getSource();
567
            View andamiView = fvs.getView(c);
568
            if (andamiView != null)
569
            {
570
                ViewInfo vi = vis.getViewInfo(andamiView);
571
                vi.setSelectedTool(mainFrame.getSelectedTool());
572
            }
573

    
574
                }
575

    
576
                /**
577
                 * @see javax.swing.event.InternalFrameListener#internalFrameDeiconified(javax.swing.event.InternalFrameEvent)
578
                 */
579
                public void internalFrameDeiconified(InternalFrameEvent e) {
580
                        mainFrame.enableControls();
581
                }
582

    
583
                /**
584
                 * @see javax.swing.event.InternalFrameListener#internalFrameIconified(javax.swing.event.InternalFrameEvent)
585
                 */
586
                public void internalFrameIconified(InternalFrameEvent e) {
587
                        mainFrame.enableControls();
588
                }
589

    
590
                /**
591
                 * @see javax.swing.event.InternalFrameListener#internalFrameOpened(javax.swing.event.InternalFrameEvent)
592
                 */
593
                public void internalFrameOpened(InternalFrameEvent e) {
594
            logger.debug("internalFrameOpened. Source= " + e.getSource().toString());
595
                }
596
        }
597

    
598
        /**
599
         * @see com.iver.andami.ui.mdiManager.MDIManager#closeSingletonView(java.lang.Class, java.lang.Object)
600
         */
601
        public boolean closeSingletonView(Class viewClass, Object model) {
602
                JInternalFrame frame = svs.getFrame(viewClass, model);
603
                if (frame == null) return false;
604
                closeJInternalFrame(frame);
605
                return true;
606
        }
607

    
608
        /**
609
         * @see com.iver.andami.ui.mdiManager.MDIManager#closeSingletonView(java.lang.Object)
610
         */
611
        public boolean closeSingletonView(Object model) {
612
                JInternalFrame[] frames = svs.getFrames(model);
613
                if (frames.length == 0) return false;
614
                for (int i = 0; i < frames.length; i++) {
615
                        closeJInternalFrame(frames[i]);
616
                }
617
                return true;
618
        }
619

    
620
        public View[] getAllViews() {
621
                ArrayList views = new ArrayList();
622
                Iterator i = fvs.getViewIterator();
623

    
624
                while (i.hasNext()) {
625
                        views.add((View) i.next());
626
                }
627
                return (View[])views.toArray(new View[0]);
628
        }
629
}