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 @ 43913

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

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

    
42
import org.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44

    
45
import org.gvsig.andami.PluginServices;
46
import org.gvsig.andami.ui.mdiManager.IWindow;
47
import org.gvsig.andami.ui.mdiManager.MDIManager;
48
import org.gvsig.andami.ui.mdiManager.WindowInfo;
49
import org.gvsig.filedialogchooser.FileDialogChooser;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.swing.api.ToolsSwingLocator;
52
import org.gvsig.tools.swing.api.reminder.DialogReminder;
53
import org.gvsig.tools.task.CancellableTask;
54
import org.gvsig.tools.task.RunnableWithParameters;
55
import org.gvsig.tools.util.ToolsUtilLocator;
56

    
57

    
58
/**
59
 * Thread safe functions for showing dialogs
60
 *
61
 * @author jjdelcerro
62
 *
63
 */
64
public class DefaultThreadSafeDialogs implements ThreadSafeDialogs {
65

    
66
        private static Logger logger = LoggerFactory
67
                        .getLogger(DefaultThreadSafeDialogs.class);
68
        private Component rootComponent;
69
        private NewStatusBar statusbar;
70

    
71
        public DefaultThreadSafeDialogs() {
72
            this(null, null);
73
        }
74

    
75
        public DefaultThreadSafeDialogs(Component rootComponent) {
76
            this(rootComponent,null);
77
        }
78

    
79
        public DefaultThreadSafeDialogs(Component rootComponent,
80
                        NewStatusBar statusbar) {
81
                this.statusbar = statusbar;
82
                this.rootComponent = rootComponent;
83
        }
84

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

    
96
        private NewStatusBar getStatusbar() {
97
                if (this.statusbar == null) {
98
                        this.statusbar = PluginServices.getMainFrame().getStatusBar();
99
                }
100
                return this.statusbar;
101
        }
102

    
103
        @Override
104
        public void message(String message, int messageType) {
105
                this.getStatusbar().message(message, messageType);
106
        }
107

    
108
        private String translate(String message) {
109
                return translate(message, null);
110
        }
111

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

    
126
        @Override
127
        public int confirmDialog(final String message, final String title, final int optionType,
128
                        final int messageType) {
129
            return this.confirmDialog(message, title, optionType, messageType, null);
130
        }
131

    
132
        private static class JMessageWithCheck extends JPanel {
133

    
134
        private static final long serialVersionUID = -1902712909850016361L;
135
            private final JLabel label;
136
            private final JCheckBox check;
137

    
138
            public JMessageWithCheck(String msg, String msgchk) {
139
                if( !msg.toLowerCase().trim().startsWith("<html>") ) {
140
                    msg = "<html>" + msg.replace("\n", "<br>\n") + "</html>";
141
                }
142
                this.label = new JLabel(msg);
143
                this.check = new JCheckBox(msgchk);
144
                this.setLayout(new BorderLayout(10,10));
145
                this.add(this.label,BorderLayout.CENTER);
146
                this.add(this.check,BorderLayout.PAGE_END);
147
            }
148

    
149
            public boolean isCheckSelected() {
150
                return this.check.isSelected();
151
            }
152
        }
153

    
154
        @Override
155
        public int confirmDialog(final String message, final String title, final int optionType,
156
                        final int messageType, final String msgid) {
157
                RunnableWithParameters runnable = new RunnableWithParameters() {
158
                        @Override
159
                        public void run() {
160
                            DialogReminder r = null;
161
                            Object msg = message;
162
                            if( msgid != null ) {
163
                                r = ToolsSwingLocator.getDialogReminderManager().add(msgid);
164
                                if( r.hasValue() ) {
165
                                    this.returnValue = r.getValue();
166
                                    return;
167
                                }
168
                                msg = new JMessageWithCheck(
169
                                        message,
170
                                        ToolsLocator.getI18nManager().getTranslation("_Remember_answer_and_do_not_ask_again")
171
                                );
172
                            }
173
                            this.returnValue = JOptionPane.showConfirmDialog(
174
                                getRootComponent(),
175
                                msg,
176
                                title,
177
                                optionType,
178
                                messageType
179
                            );
180
                            if( r!=null ) {
181
                                if( ((JMessageWithCheck)msg).isCheckSelected() ) {
182
                                    r.setValue(this.returnValue);
183
                                } else {
184
                                    r.reset();
185
                                }
186
                            }
187
                        }
188
                };
189
                if (SwingUtilities.isEventDispatchThread()) {
190
                        runnable.run();
191
                } else {
192
                        try {
193
                                SwingUtilities.invokeAndWait(runnable);
194
                        } catch (Exception e) {
195
                                logger.info("Can't show input dialog '" + message + "'.", e);
196
                        }
197
                }
198
                return (Integer) runnable.getReturnValue();
199
        }
200

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

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

    
249
        @Override
250
        public void messageDialog(String message, String title, int messageType) {
251
                messageDialog(message, null, title, messageType);
252
        }
253

    
254
        public void messageDialog(final String message, final String messageArgs[],
255
                        final String title, final int messageType) {
256
        messageDialog(message, messageArgs, title, messageType, null);
257
    }
258

    
259
        @Override
260
    public void messageDialog(final String message, final String messageArgs[],
261
            final String title, final int messageType, final String msgid) {
262
        if (!SwingUtilities.isEventDispatchThread()) {
263
            try {
264
                SwingUtilities.invokeAndWait(new Runnable() {
265
                    @Override
266
                    public void run() {
267
                        messageDialog(message, messageArgs, title, messageType, msgid);
268
                    }
269
                });
270
            } catch (Exception e) {
271
                logger.info("Can't show message dialog '" + message
272
                        + "'. redirect to status bar", e);
273
                this.message(message, messageType);
274
            }
275
            return;
276
        }
277

    
278
        if (message == null) {
279
            logger.info("message if null, message dialog not show.");
280
            return;
281
        }
282
        DialogReminder r = null;
283
        Object msg = translate(message, messageArgs);
284
        if (msgid != null) {
285
            r = ToolsSwingLocator.getDialogReminderManager().add(msgid);
286
            if (r.hasValue() && ((Boolean)r.getValue()) ) {
287
                return;
288
            }
289
            msg = new JMessageWithCheck(
290
                    translate(message, messageArgs),
291
                    ToolsLocator.getI18nManager().getTranslation("_do_not_show_again")
292
            );
293
        }
294
        JOptionPane.showMessageDialog(getRootComponent(),
295
                msg, translate(title), messageType);
296

    
297
        if (r != null) {
298
            if (((JMessageWithCheck) msg).isCheckSelected()) {
299
                r.setValue(true);
300
            } else {
301
                r.reset();
302
            }
303
        }
304

    
305
    }
306

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

    
348
        class DialogWindow extends JPanel implements IWindow, ComponentListener {
349

    
350
                /**
351
                 *
352
                 */
353
                private static final long serialVersionUID = 6283975319620714565L;
354
                protected WindowInfo windowInfo;
355
                protected Object profile;
356
                protected Component contents;
357
                private int code = 0;
358

    
359
                public DialogWindow() {
360
                        code = WindowInfo.RESIZABLE | WindowInfo.MAXIMIZABLE
361
                                        | WindowInfo.ICONIFIABLE;
362
                        profile = WindowInfo.DIALOG_PROFILE;
363
                }
364

    
365
                public void setDialogFlag() {
366
                        code |= WindowInfo.MODALDIALOG;
367
                }
368

    
369
                public void setContents(Component contents, String title) {
370
                        this.windowInfo = new WindowInfo(code);
371
                        this.windowInfo.setTitle(title);
372

    
373
                        this.contents = contents;
374

    
375
                        Dimension size = this.contents.getPreferredSize();
376
                        this.windowInfo.setHeight(size.height);
377
                        this.windowInfo.setWidth(size.width);
378

    
379
                        this.setLayout(new BorderLayout());
380
                        this.add(this.contents, BorderLayout.CENTER);
381

    
382
                        this.contents.addComponentListener(this);
383
                }
384

    
385
                public WindowInfo getWindowInfo() {
386
                        return this.windowInfo;
387
                }
388

    
389
                public Object getWindowProfile() {
390
                        return this.profile;
391
                }
392

    
393
                public void componentHidden(ComponentEvent arg0) {
394
                        // Close window when hide contents panel.
395
                        MDIManager manager = PluginServices.getMDIManager();
396
                        manager.closeWindow(this);
397
                        if ((code & WindowInfo.MODALDIALOG) == 0) {
398
                                synchronized (this) {
399
                                        this.notifyAll();
400
                                }
401
                        }
402
                }
403

    
404
                public void componentMoved(ComponentEvent arg0) {
405
                        // Do nothing
406
                }
407

    
408
                public void componentResized(ComponentEvent arg0) {
409
                        // Do nothing
410
                }
411

    
412
                public void componentShown(ComponentEvent arg0) {
413
                        // Do nothing
414
                }
415

    
416
        }
417

    
418
        public Component createComponent(final Class<? extends Component> theClass,
419
                        final Object... parameters) {
420
                return createComponentWithParams(theClass, parameters);
421
        }
422

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

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

    
518
        public File[] showOpenDirectoryDialog(String title, File initialPath) {
519
                return showChooserDialog(title, FileDialogChooser.OPEN_DIALOG, FileDialogChooser.DIRECTORIES_ONLY, false, initialPath, null, false);
520
        }
521

    
522

    
523
        public File[] showOpenFileDialog(String title, File initialPath) {
524
                return showChooserDialog(title, FileDialogChooser.OPEN_DIALOG, FileDialogChooser.FILES_ONLY, false, initialPath, null, false);
525
        }
526

    
527

    
528
        public File[] showSaveFileDialog(String title, File initialPath) {
529
                return showChooserDialog(title, FileDialogChooser.SAVE_DIALOG, FileDialogChooser.FILES_ONLY, false, initialPath, null, false);
530
        }
531

    
532
}