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

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
        private void message(String message, int messageType) {
104
                this.getStatusbar().message(message, messageType);
105
        }
106

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

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

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

    
131
        private static class JMessageWithCheck extends JPanel {
132

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

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

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

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

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

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

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

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

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

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

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

    
304
    }
305

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

    
347
        class DialogWindow extends JPanel implements IWindow, ComponentListener {
348

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

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

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

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

    
372
                        this.contents = contents;
373

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

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

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

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

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

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

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

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

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

    
415
        }
416

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

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

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

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

    
521

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

    
526

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

    
531
}