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

History | View | Annotate | Download (16.4 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.reminder.DialogReminder;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.task.CancellableTask;
53
import org.gvsig.tools.task.RunnableWithParameters;
54
import org.gvsig.tools.util.ToolsUtilLocator;
55

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

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

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

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

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

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

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

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

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

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

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

    
129
        private static class JMessageWithCheck extends JPanel {
130
            private final JLabel label;
131
            private final JCheckBox check;
132

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

    
144
            public boolean isCheckSelected() {
145
                return this.check.isSelected();
146
            }
147
        }
148

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

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

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

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

    
249
        public void messageDialog(final String message, final String messageArgs[],
250
                        final String title, final int messageType) {
251
        messageDialog(message, messageArgs, title, messageType, null);
252
    }
253

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

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

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

    
300
    }
301

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

    
343
        class DialogWindow extends JPanel implements IWindow, ComponentListener {
344

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

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

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

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

    
368
                        this.contents = contents;
369

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

    
374
                        this.setLayout(new BorderLayout());
375
                        this.add(this.contents, BorderLayout.CENTER);
376

    
377
                        this.contents.addComponentListener(this);
378
                }
379

    
380
                public WindowInfo getWindowInfo() {
381
                        return this.windowInfo;
382
                }
383

    
384
                public Object getWindowProfile() {
385
                        return this.profile;
386
                }
387

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

    
399
                public void componentMoved(ComponentEvent arg0) {
400
                        // Do nothing
401
                }
402

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

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

    
411
        }
412

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

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

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

    
513
        public File[] showOpenDirectoryDialog(String title, File initialPath) {
514
                return showChooserDialog(title, FileDialogChooser.OPEN_DIALOG, FileDialogChooser.DIRECTORIES_ONLY, false, initialPath, null, false);
515
        }
516

    
517

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

    
522

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

    
527
}