Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.framework / org.gvsig.andami / src / main / java / org / gvsig / andami / ui / mdiFrame / DefaultThreadSafeDialogs.java @ 43167

History | View | Annotate | Download (16.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.andami.ui.mdiFrame;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Component;
28
import java.awt.Dimension;
29
import java.awt.GridBagConstraints;
30
import java.awt.event.ComponentEvent;
31
import java.awt.event.ComponentListener;
32
import java.io.File;
33
import java.lang.reflect.Constructor;
34
import javax.swing.JCheckBox;
35

    
36
import javax.swing.JFileChooser;
37
import javax.swing.JLabel;
38
import javax.swing.JOptionPane;
39
import javax.swing.JPanel;
40
import javax.swing.SwingUtilities;
41
import javax.swing.filechooser.FileFilter;
42

    
43
import org.gvsig.andami.PluginServices;
44
import org.gvsig.andami.PluginsLocator;
45
import org.gvsig.andami.ui.mdiManager.IWindow;
46
import org.gvsig.andami.ui.mdiManager.MDIManager;
47
import org.gvsig.andami.ui.mdiManager.WindowInfo;
48
import org.gvsig.dialogremember.DialogRememeber;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.task.CancellableTask;
51
import org.gvsig.tools.task.RunnableWithParameters;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

    
55
/**
56
 * Thread safe functions for showing dialogs
57
 * 
58
 * @author jjdelcerro
59
 * 
60
 */
61
public class DefaultThreadSafeDialogs implements ThreadSafeDialogs {
62

    
63
        private static Logger logger = LoggerFactory
64
                        .getLogger(DefaultThreadSafeDialogs.class);
65
        private Component rootComponent;
66
        private NewStatusBar statusbar;
67

    
68
        public DefaultThreadSafeDialogs() {
69
            this(null, null);
70
        }
71

    
72
        public DefaultThreadSafeDialogs(Component rootComponent) {
73
            this(rootComponent,null);
74
        }
75

    
76
        public DefaultThreadSafeDialogs(Component rootComponent,
77
                        NewStatusBar statusbar) {
78
                this.statusbar = statusbar;
79
                this.rootComponent = rootComponent;
80
        }
81

    
82
        private Component getRootComponent() {
83
                if (this.rootComponent == null) {
84
                        try {
85
                                this.rootComponent = (MDIFrame) PluginServices.getMainFrame();
86
                        } catch (Throwable t) {
87
                                // Ignore and return null
88
                        }
89
                }
90
                return this.rootComponent;
91
        }
92

    
93
        private NewStatusBar getStatusbar() {
94
                if (this.statusbar == null) {
95
                        this.statusbar = PluginServices.getMainFrame().getStatusBar();
96
                }
97
                return this.statusbar;
98
        }
99

    
100
        private void message(String message, int messageType) {
101
                this.getStatusbar().message(message, messageType);
102
        }
103

    
104
        private String translate(String message) {
105
                return translate(message, null);
106
        }
107

    
108
        private String translate(String message, String[] args) {
109
                String msg = message;
110
                if (msg == null) {
111
                        msg = "";
112
                }
113
                if (msg.startsWith("_")) {
114
                        msg = org.gvsig.i18n.Messages.getText(msg, args);
115
                        if (msg == null) {
116
                                msg = "_" + message.replace("_", " ");
117
                        }
118
                }
119
                return msg;
120
        }
121

    
122
        @Override
123
        public int confirmDialog(final String message, final String title, final int optionType,
124
                        final int messageType) {
125
            return this.confirmDialog(message, title, optionType, messageType, null);
126
        }
127

    
128
        private static class JMessageWithCheck extends JPanel {
129
            private final JLabel label;
130
            private final JCheckBox check;
131
            
132
            public JMessageWithCheck(String msg, String msgchk) {
133
                if( !msg.toLowerCase().trim().startsWith("<html>") ) {
134
                    msg = "<html>" + msg.replace("\n", "<br>\n") + "</html>";
135
                }
136
                this.label = new JLabel(msg);
137
                this.check = new JCheckBox(msgchk);
138
                this.setLayout(new BorderLayout(10,10));
139
                this.add(this.label,BorderLayout.CENTER);
140
                this.add(this.check,BorderLayout.PAGE_END);
141
            }
142
            
143
            public boolean isCheckSelected() {
144
                return this.check.isSelected();
145
            }
146
        }
147
        
148
        @Override
149
        public int confirmDialog(final String message, final String title, final int optionType,
150
                        final int messageType, final String msgid) {
151
                RunnableWithParameters runnable = new RunnableWithParameters() {
152
                        @Override
153
                        public void run() {
154
                            DialogRememeber r = null;
155
                            Object msg = message;
156
                            if( msgid != null ) {
157
                                r = PluginsLocator.getDialogRemembereManager().add(msgid);
158
                                if( r.hasValue() ) {
159
                                    this.returnValue = r.getValue();
160
                                    return;
161
                                }
162
                                msg = new JMessageWithCheck(
163
                                        message, 
164
                                        ToolsLocator.getI18nManager().getTranslation("_Remember_answer_and_do_not_ask_again")
165
                                );
166
                            }
167
                            this.returnValue = JOptionPane.showConfirmDialog(
168
                                getRootComponent(), 
169
                                msg,
170
                                title, 
171
                                optionType, 
172
                                messageType
173
                            );
174
                            if( r!=null ) {
175
                                if( ((JMessageWithCheck)msg).isCheckSelected() ) {
176
                                    r.setValue(this.returnValue);
177
                                } else {
178
                                    r.reset();
179
                                }
180
                            }
181
                        }
182
                };
183
                if (SwingUtilities.isEventDispatchThread()) {
184
                        runnable.run();
185
                } else {
186
                        try {
187
                                SwingUtilities.invokeAndWait(runnable);
188
                        } catch (Exception e) {
189
                                logger.info("Can't show input dialog '" + message + "'.", e);
190
                        }
191
                }
192
                return (Integer) runnable.getReturnValue();
193
        }
194

    
195
        public String inputDialog(final String message, final String title, final int messageType,
196
                        final String initialValue) {
197
                // inputDialog dlg = new inputDialog();
198
                // return dlg.show(translate(message), translate(title), messageType,
199
                // initialValue);
200
                //
201
                RunnableWithParameters runnable = new RunnableWithParameters() {
202
                        public void run() {
203
                                this.returnValue = JOptionPane.showInputDialog(
204
                                                getRootComponent(), translate(message),
205
                                                translate(title),
206
                                                messageType, null, null,
207
                                                initialValue);
208
                        }
209
                };
210
                if (SwingUtilities.isEventDispatchThread()) {
211
                        runnable.run();
212
                } else {
213
                        try {
214
                                SwingUtilities.invokeAndWait(runnable);
215
                        } catch (Exception e) {
216
                                logger.info("Can't show input dialog '" + message + "'.", e);
217
                        }
218
                }
219
                return (String) runnable.getReturnValue();
220
        }
221

    
222
        public String inputDialog(final String message, final String title) {
223
                RunnableWithParameters runnable = new RunnableWithParameters() {
224
                        public void run() {
225
                                this.returnValue = JOptionPane.showInputDialog(
226
                                                getRootComponent(), (String) translate(message),
227
                                                translate(title),
228
                                                JOptionPane.QUESTION_MESSAGE, null, null, null);
229
                        }
230
                };
231
                if (SwingUtilities.isEventDispatchThread()) {
232
                        runnable.run();
233
                } else {
234
                        try {
235
                                SwingUtilities.invokeAndWait(runnable);
236
                        } catch (Exception e) {
237
                                logger.info("Can't show input dialog '" + message + "'.", e);
238
                        }
239
                }
240
                return (String) runnable.getReturnValue();
241
        }
242

    
243
        @Override
244
        public void messageDialog(String message, String title, int messageType) {
245
                messageDialog(message, null, title, messageType);
246
        }
247

    
248
        public void messageDialog(final String message, final String messageArgs[],
249
                        final String title, final int messageType) {
250
        }
251
        
252
        @Override
253
    public void messageDialog(final String message, final String messageArgs[],
254
            final String title, final int messageType, final String msgid) {
255
        if (!SwingUtilities.isEventDispatchThread()) {
256
            try {
257
                SwingUtilities.invokeAndWait(new Runnable() {
258
                    @Override
259
                    public void run() {
260
                        messageDialog(message, messageArgs, title, messageType, msgid);
261
                    }
262
                });
263
            } catch (Exception e) {
264
                logger.info("Can't show message dialog '" + message
265
                        + "'. redirect to status bar", e);
266
                this.message(message, messageType);
267
            }
268
            return;
269
        }
270

    
271
        if (message == null) {
272
            logger.info("message if null, message dialog not show.");
273
            return;
274
        }
275
        DialogRememeber r = null;
276
        Object msg = message;
277
        if (msgid != null) {
278
            r = PluginsLocator.getDialogRemembereManager().add(msgid);
279
            if (r.hasValue() && ((boolean)r.getValue()) ) {
280
                return;
281
            }
282
            msg = new JMessageWithCheck(
283
                    message,
284
                    ToolsLocator.getI18nManager().getTranslation("_do_not_show_again")
285
            );
286
        }
287
        JOptionPane.showMessageDialog(getRootComponent(),
288
                translate(message, messageArgs), translate(title), messageType);
289

    
290
        if (r != null) {
291
            if (((JMessageWithCheck) msg).isCheckSelected()) {
292
                r.setValue(true);
293
            } else {
294
                r.reset();
295
            }
296
        }
297

    
298
    }
299

    
300
        public void showDialog(final Component contents, final String title) {
301
                if (SwingUtilities.isEventDispatchThread()) {
302
                        final DialogWindow window = new DialogWindow();
303
                        window.setDialogFlag();
304
                        window.setContents(contents, title);
305
                        MDIManager manager = PluginServices.getMDIManager();
306
                        manager.addWindow(window, GridBagConstraints.CENTER);
307
                } else {
308
                        final DialogWindow window = new DialogWindow();
309
                        SwingUtilities.invokeLater(new Runnable() {
310
                                public void run() {
311
                                        window.setContents(contents, title);
312
                                        MDIManager manager = PluginServices.getMDIManager();
313
                                        manager.addWindow(window, GridBagConstraints.CENTER);
314
                                }
315
                        });
316
                        try {
317
                                synchronized (window) {
318
                                        if (contents instanceof CancellableTask) {
319
                                                while( contents.isVisible()  ) {
320
                                                        if( ((CancellableTask)contents).isCancellationRequested() ) {
321
                                                                SwingUtilities.invokeLater(new Runnable() {
322
                                                                        public void run() {
323
                                                                                contents.setVisible(false);
324
                                                                        }
325
                                                                });
326
                                                        }
327
                                                        window.wait(10000);
328
                                                }
329
                                        } else {
330
                                                while( contents.isVisible() ) {
331
                                                        window.wait();
332
                                                }
333
                                        }
334
                                }
335
                        } catch (InterruptedException e) {
336
                                logger.info("showDialog can wait to close dialog.", e);
337
                        }
338
                }
339
        }
340

    
341
        class DialogWindow extends JPanel implements IWindow, ComponentListener {
342

    
343
                /**
344
                 * 
345
                 */
346
                private static final long serialVersionUID = 6283975319620714565L;
347
                protected WindowInfo windowInfo;
348
                protected Object profile;
349
                protected Component contents;
350
                private int code = 0;
351

    
352
                public DialogWindow() {
353
                        code = WindowInfo.RESIZABLE | WindowInfo.MAXIMIZABLE
354
                                        | WindowInfo.ICONIFIABLE;
355
                        profile = WindowInfo.DIALOG_PROFILE;
356
                }
357

    
358
                public void setDialogFlag() {
359
                        code |= WindowInfo.MODALDIALOG;
360
                }
361

    
362
                public void setContents(Component contents, String title) {
363
                        this.windowInfo = new WindowInfo(code);
364
                        this.windowInfo.setTitle(title);
365

    
366
                        this.contents = contents;
367

    
368
                        Dimension size = this.contents.getPreferredSize();
369
                        this.windowInfo.setHeight(size.height);
370
                        this.windowInfo.setWidth(size.width);
371

    
372
                        this.setLayout(new BorderLayout());
373
                        this.add(this.contents, BorderLayout.CENTER);
374

    
375
                        this.contents.addComponentListener(this);
376
                }
377

    
378
                public WindowInfo getWindowInfo() {
379
                        return this.windowInfo;
380
                }
381

    
382
                public Object getWindowProfile() {
383
                        return this.profile;
384
                }
385

    
386
                public void componentHidden(ComponentEvent arg0) {
387
                        // Close window when hide contents panel.
388
                        MDIManager manager = PluginServices.getMDIManager();
389
                        manager.closeWindow(this);
390
                        if ((code & WindowInfo.MODALDIALOG) == 0) {
391
                                synchronized (this) {
392
                                        this.notifyAll();
393
                                }
394
                        }
395
                }
396

    
397
                public void componentMoved(ComponentEvent arg0) {
398
                        // Do nothing
399
                }
400

    
401
                public void componentResized(ComponentEvent arg0) {
402
                        // Do nothing
403
                }
404

    
405
                public void componentShown(ComponentEvent arg0) {
406
                        // Do nothing
407
                }
408

    
409
        }
410

    
411
        public Component createComponent(final Class<? extends Component> theClass,
412
                        final Object... parameters) {
413
                return createComponentWithParams(theClass, parameters);
414
        }
415

    
416
        public Component createComponentWithParams(
417
                        final Class<? extends Component> theClass, final Object[] parameters) {
418
                final Class<?>[] parameterTypes = new Class<?>[parameters.length];
419
                for (int i = 0; i < parameters.length; i++) {
420
                        parameterTypes[i] = parameters[i].getClass();
421
                }
422
                final Component component;
423
                final Constructor<?> constructor;
424
                try {
425
                        constructor = theClass.getConstructor(parameterTypes);
426
                } catch (Exception e) {
427
                        throw new IllegalArgumentException(e);
428
                }
429
                if (SwingUtilities.isEventDispatchThread()) {
430
                        try {
431
                                component = (Component) constructor.newInstance(parameters);
432
                        } catch (Exception e) {
433
                                throw new IllegalArgumentException(e);
434
                        }
435
                } else {
436
                        try {
437
                                RunnableWithParameters runnable = new RunnableWithParameters(parameters) {
438
                                        public void run() {
439
                                                Constructor<?> cons = constructor;
440
                                                try {
441
                                                        this.returnValue = cons.newInstance(parameters.toArray());
442
                                                } catch (Exception e) {
443
                                                        String msg ="Can't create instance of components, constructor="+cons.toString()+", parameters="+this.parameters.toString()+"."; 
444
                                                        logger.info(msg,e);
445
                                                        throw new IllegalArgumentException(e);
446
                                                }
447
                                        }
448
                                };
449
                                SwingUtilities.invokeAndWait(runnable);
450
                                component = (Component) runnable.getReturnValue();
451
                        } catch (Exception e) {
452
                                throw new IllegalArgumentException(e);
453
                        }
454
                }
455
                return component;
456
        }
457

    
458
        public File[] showChooserDialog(
459
                        final String title,
460
                        final int type, // SAVE_DIALOG / OPEN_DIALOG
461
                        final int selectionMode, //    JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY, JFileChooser.FILES_AND_DIRECTORIES
462
                        final boolean multiselection, 
463
                        final File initialPath,
464
                        final FileFilter filter,
465
                        final boolean fileHidingEnabled
466
                        ) {
467
                RunnableWithParameters runnable = new RunnableWithParameters() {
468
                        public void run() {
469
                                JFileChooser fc = new JFileChooser();
470
                                fc.setDialogTitle(title);
471
                                fc.setDialogType(type);
472
                                fc.setFileSelectionMode(selectionMode);
473
                                fc.setMultiSelectionEnabled(multiselection);
474
                                fc.setCurrentDirectory(initialPath);
475
                                fc.setFileFilter(filter);
476
                                fc.setFileHidingEnabled(fileHidingEnabled);
477
                                int r = JFileChooser.CANCEL_OPTION;
478
                                switch(type) {
479
                                case JFileChooser.SAVE_DIALOG:
480
                                        r = fc.showSaveDialog(getRootComponent());
481
                                        break;
482
                                case JFileChooser.OPEN_DIALOG:
483
                                default:
484
                                        r = fc.showOpenDialog(getRootComponent());
485
                                        break;
486
                                }
487
                                if( r != JFileChooser.APPROVE_OPTION ) {
488
                                        this.returnValue = null;
489
                                        return;
490
                                }
491
                                if( fc.isMultiSelectionEnabled() ) {
492
                                        this.returnValue = fc.getSelectedFiles();
493
                                } else {
494
                                        this.returnValue = new File[] { fc.getSelectedFile() };
495
                                }
496
                        }
497
                };
498
                if (SwingUtilities.isEventDispatchThread()) {
499
                        runnable.run();
500
                } else {
501
                        try {
502
                                SwingUtilities.invokeAndWait(runnable);
503
                        } catch (Exception e) {
504
                                logger.info("Can't show chooser dialog '" + title + "'.", e);
505
                        }
506
                }
507
                return (File[]) runnable.getReturnValue();
508
        }
509
        
510
        public File[] showOpenDirectoryDialog(String title, File initialPath) {
511
                return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.DIRECTORIES_ONLY, false, initialPath, null, false);
512
        }
513

    
514
        
515
        public File[] showOpenFileDialog(String title, File initialPath) {
516
                return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
517
        }
518

    
519
        
520
        public File[] showSaveFileDialog(String title, File initialPath) {
521
                return showChooserDialog(title, JFileChooser.SAVE_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
522
        }
523

    
524
}