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

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
import javax.swing.JCheckBox;
35

    
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.gvsig.andami.PluginServices;
43
import org.gvsig.andami.PluginsLocator;
44
import org.gvsig.andami.ui.mdiManager.IWindow;
45
import org.gvsig.andami.ui.mdiManager.MDIManager;
46
import org.gvsig.andami.ui.mdiManager.WindowInfo;
47
import org.gvsig.dialogremember.DialogRememeber;
48
import org.gvsig.filedialogchooser.FileDialogChooser;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.task.CancellableTask;
51
import org.gvsig.tools.task.RunnableWithParameters;
52
import org.gvsig.tools.util.ToolsUtilLocator;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
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
                            DialogRememeber r = null;
156
                            Object msg = message;
157
                            if( msgid != null ) {
158
                                r = ToolsUtilLocator.getDialogRemembereManager().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
        }
252
        
253
        @Override
254
    public void messageDialog(final String message, final String messageArgs[],
255
            final String title, final int messageType, final String msgid) {
256
        if (!SwingUtilities.isEventDispatchThread()) {
257
            try {
258
                SwingUtilities.invokeAndWait(new Runnable() {
259
                    @Override
260
                    public void run() {
261
                        messageDialog(message, messageArgs, title, messageType, msgid);
262
                    }
263
                });
264
            } catch (Exception e) {
265
                logger.info("Can't show message dialog '" + message
266
                        + "'. redirect to status bar", e);
267
                this.message(message, messageType);
268
            }
269
            return;
270
        }
271

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

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

    
299
    }
300

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

    
342
        class DialogWindow extends JPanel implements IWindow, ComponentListener {
343

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

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

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

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

    
367
                        this.contents = contents;
368

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

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

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

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

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

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

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

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

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

    
410
        }
411

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

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

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

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

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

    
526
}