Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / threadsafedialogs / DefaultThreadSafeDialogsManager.java @ 1593

History | View | Annotate | Download (13.8 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.tools.swing.impl.threadsafedialogs;
25

    
26
import java.awt.BorderLayout;
27
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
28
import java.awt.Component;
29
import java.io.File;
30
import java.lang.reflect.Constructor;
31
import javax.swing.JCheckBox;
32

    
33
import javax.swing.JFileChooser;
34
import javax.swing.JLabel;
35
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37
import javax.swing.SwingUtilities;
38
import javax.swing.filechooser.FileFilter;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.i18n.I18nManager;
41
import org.gvsig.tools.swing.api.ToolsSwingLocator;
42
import org.gvsig.tools.swing.api.reminder.DialogReminder;
43

    
44
import org.gvsig.tools.task.RunnableWithParameters;
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
/**
49
 * Thread safe functions for showing dialogs
50
 *
51
 * @author jjdelcerro
52
 *
53
 */
54
public class DefaultThreadSafeDialogsManager implements ThreadSafeDialogsManager {
55

    
56
    private static Logger logger = LoggerFactory
57
        .getLogger(DefaultThreadSafeDialogsManager.class);
58
    private final Component rootComponent;
59

    
60
    public DefaultThreadSafeDialogsManager() {
61
        this.rootComponent = null;
62
    }
63

    
64
    public DefaultThreadSafeDialogsManager(Component rootComponent) {
65
        this.rootComponent = rootComponent;
66
    }
67

    
68
    protected Component getRootComponent() {
69
        return this.rootComponent;
70
    }
71

    
72
    private String translate(String message) {
73
        I18nManager i18nManager = ToolsLocator.getI18nManager();
74
        return i18nManager.getTranslation(message);
75
    }
76

    
77
    private String translate(String message, String[] args) {
78
        I18nManager i18nManager = ToolsLocator.getI18nManager();
79
        return i18nManager.getTranslation(message, args);
80
    }
81

    
82
    @Override
83
    public int confirmDialog(final String message, final String title, final int optionType,
84
        final int messageType) {
85
        return this.confirmDialog(message, title, optionType, messageType, null);
86
    }
87

    
88
    private static class JMessageWithCheck extends JPanel {
89

    
90
        private static final long serialVersionUID = -1902712909850016361L;
91
        private final JLabel label;
92
        private final JCheckBox check;
93

    
94
        public JMessageWithCheck(String msg, String msgchk) {
95
            if( !msg.toLowerCase().trim().startsWith("<html>") ) {
96
                msg = "<html>" + msg.replace("\n", "<br>\n") + "</html>";
97
            }
98
            this.label = new JLabel(msg);
99
            this.check = new JCheckBox(msgchk);
100
            this.setLayout(new BorderLayout(10, 10));
101
            this.add(this.label, BorderLayout.CENTER);
102
            this.add(this.check, BorderLayout.PAGE_END);
103
        }
104

    
105
        public boolean isCheckSelected() {
106
            return this.check.isSelected();
107
        }
108
    }
109

    
110
    @Override
111
    public int confirmDialog(final String message, final String title, final int optionType,
112
        final int messageType, final String msgid) {
113
        RunnableWithParameters runnable = new RunnableWithParameters() {
114
            @Override
115
            public void run() {
116
                DialogReminder r = null;
117
                Object msg = message;
118
                if( msgid != null ) {
119
                    r = ToolsSwingLocator.getDialogReminderManager().add(msgid);
120
                    if( r.hasValue() ) {
121
                        this.returnValue = r.getValue();
122
                        return;
123
                    }
124
                    msg = new JMessageWithCheck(
125
                        message,
126
                        ToolsLocator.getI18nManager().getTranslation("_Remember_answer_and_do_not_ask_again")
127
                    );
128
                }
129
                this.returnValue = JOptionPane.showConfirmDialog(
130
                    getRootComponent(),
131
                    msg,
132
                    title,
133
                    optionType,
134
                    messageType
135
                );
136
                if( r != null ) {
137
                    if( ((JMessageWithCheck) msg).isCheckSelected() ) {
138
                        r.setValue(this.returnValue);
139
                    } else {
140
                        r.reset();
141
                    }
142
                }
143
            }
144
        };
145
        if( SwingUtilities.isEventDispatchThread() ) {
146
            runnable.run();
147
        } else {
148
            try {
149
                SwingUtilities.invokeAndWait(runnable);
150
            } catch (Exception e) {
151
                logger.info("Can't show input dialog '" + message + "'.", e);
152
            }
153
        }
154
        return (Integer) runnable.getReturnValue();
155
    }
156

    
157
    @Override
158
    public String inputDialog(final String message, final String title, final int messageType,
159
        final String initialValue) {
160
        RunnableWithParameters runnable = new RunnableWithParameters() {
161
            @Override
162
            public void run() {
163
                this.returnValue = JOptionPane.showInputDialog(
164
                    getRootComponent(), translate(message),
165
                    translate(title),
166
                    messageType, null, null,
167
                    initialValue);
168
            }
169
        };
170
        if( SwingUtilities.isEventDispatchThread() ) {
171
            runnable.run();
172
        } else {
173
            try {
174
                SwingUtilities.invokeAndWait(runnable);
175
            } catch (Exception e) {
176
                logger.info("Can't show input dialog '" + message + "'.", e);
177
            }
178
        }
179
        return (String) runnable.getReturnValue();
180
    }
181

    
182
    @Override
183
    public String inputDialog(final String message, final String title) {
184
        RunnableWithParameters runnable = new RunnableWithParameters() {
185
            @Override
186
            public void run() {
187
                this.returnValue = JOptionPane.showInputDialog(
188
                    getRootComponent(), (String) translate(message),
189
                    translate(title),
190
                    JOptionPane.QUESTION_MESSAGE, null, null, null);
191
            }
192
        };
193
        if( SwingUtilities.isEventDispatchThread() ) {
194
            runnable.run();
195
        } else {
196
            try {
197
                SwingUtilities.invokeAndWait(runnable);
198
            } catch (Exception e) {
199
                logger.info("Can't show input dialog '" + message + "'.", e);
200
            }
201
        }
202
        return (String) runnable.getReturnValue();
203
    }
204

    
205
    @Override
206
    public void messageDialog(String message, String title, int messageType) {
207
        messageDialog(message, null, title, messageType);
208
    }
209

    
210
    @Override
211
    public void messageDialog(final String message, final String messageArgs[],
212
        final String title, final int messageType) {
213
        messageDialog(message, messageArgs, title, messageType, null);
214
    }
215

    
216
    @Override
217
    public void messageDialog(final String message, final String messageArgs[],
218
        final String title, final int messageType, final String msgid) {
219
        if( !SwingUtilities.isEventDispatchThread() ) {
220
            try {
221
                SwingUtilities.invokeAndWait(new Runnable() {
222
                    @Override
223
                    public void run() {
224
                        messageDialog(message, messageArgs, title, messageType, msgid);
225
                    }
226
                });
227
            } catch (Exception e) {
228
                logger.warn("Can't show message dialog '" + message + "'.", e);
229
            }
230
            return;
231
        }
232

    
233
        if( message == null ) {
234
            logger.info("message if null, message dialog not show.");
235
            return;
236
        }
237
        DialogReminder r = null;
238
        Object msg = translate(message, messageArgs);
239
        if( msgid != null ) {
240
            r = ToolsSwingLocator.getDialogReminderManager().add(msgid);
241
            if( r.hasValue() && ((boolean) r.getValue()) ) {
242
                return;
243
            }
244
            msg = new JMessageWithCheck(
245
                translate(message, messageArgs),
246
                ToolsLocator.getI18nManager().getTranslation("_do_not_show_again")
247
            );
248
        }
249
        JOptionPane.showMessageDialog(getRootComponent(),
250
            msg, translate(title), messageType);
251

    
252
        if( r != null ) {
253
            if( ((JMessageWithCheck) msg).isCheckSelected() ) {
254
                r.setValue(true);
255
            } else {
256
                r.reset();
257
            }
258
        }
259

    
260
    }
261

    
262
    @Override
263
    public Component createComponent(final Class<? extends Component> theClass,
264
        final Object... parameters) {
265
        return createComponentWithParams(theClass, parameters);
266
    }
267

    
268
    @Override
269
    public Component createComponentWithParams(
270
        final Class<? extends Component> theClass, final Object[] parameters) {
271
        final Class<?>[] parameterTypes = new Class<?>[parameters.length];
272
        for( int i = 0; i < parameters.length; i++ ) {
273
            parameterTypes[i] = parameters[i].getClass();
274
        }
275
        final Component component;
276
        final Constructor<?> constructor;
277
        try {
278
            constructor = theClass.getConstructor(parameterTypes);
279
        } catch (Exception e) {
280
            throw new IllegalArgumentException(e);
281
        }
282
        if( SwingUtilities.isEventDispatchThread() ) {
283
            try {
284
                component = (Component) constructor.newInstance(parameters);
285
            } catch (Exception e) {
286
                throw new IllegalArgumentException(e);
287
            }
288
        } else {
289
            try {
290
                RunnableWithParameters runnable = new RunnableWithParameters(parameters) {
291
                    @Override
292
                    public void run() {
293
                        Constructor<?> cons = constructor;
294
                        try {
295
                            this.returnValue = cons.newInstance(parameters.toArray());
296
                        } catch (Exception e) {
297
                            String msg = "Can't create instance of components, constructor=" + cons.toString() + ", parameters=" + this.parameters.toString() + ".";
298
                            logger.info(msg, e);
299
                            throw new IllegalArgumentException(e);
300
                        }
301
                    }
302
                };
303
                SwingUtilities.invokeAndWait(runnable);
304
                component = (Component) runnable.getReturnValue();
305
            } catch (Exception e) {
306
                throw new IllegalArgumentException(e);
307
            }
308
        }
309
        return component;
310
    }
311

    
312
    @Override
313
    public File[] showChooserDialog(
314
        final String title,
315
        final int type, // SAVE_DIALOG / OPEN_DIALOG
316
        final int selectionMode, //    JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY, JFileChooser.FILES_AND_DIRECTORIES
317
        final boolean multiselection,
318
        final File initialPath,
319
        final FileFilter filter,
320
        final boolean fileHidingEnabled
321
    ) {
322
        RunnableWithParameters runnable = new RunnableWithParameters() {
323
            @Override
324
            public void run() {
325
                JFileChooser fc = new JFileChooser();
326
                fc.setDialogTitle(title);
327
                fc.setDialogType(type);
328
                fc.setFileSelectionMode(selectionMode);
329
                fc.setMultiSelectionEnabled(multiselection);
330
                fc.setCurrentDirectory(initialPath);
331
                fc.setFileFilter(filter);
332
                fc.setFileHidingEnabled(fileHidingEnabled);
333
                int r;
334
                switch( type ) {
335
                case JFileChooser.SAVE_DIALOG:
336
                    r = fc.showSaveDialog(getRootComponent());
337
                    break;
338
                case JFileChooser.OPEN_DIALOG:
339
                default:
340
                    r = fc.showOpenDialog(getRootComponent());
341
                    break;
342
                }
343
                if( r != JFileChooser.APPROVE_OPTION ) {
344
                    this.returnValue = null;
345
                    return;
346
                }
347
                if( fc.isMultiSelectionEnabled() ) {
348
                    this.returnValue = fc.getSelectedFiles();
349
                } else {
350
                    this.returnValue = new File[]{fc.getSelectedFile()};
351
                }
352
            }
353
        };
354
        if( SwingUtilities.isEventDispatchThread() ) {
355
            runnable.run();
356
        } else {
357
            try {
358
                SwingUtilities.invokeAndWait(runnable);
359
            } catch (Exception e) {
360
                logger.info("Can't show chooser dialog '" + title + "'.", e);
361
            }
362
        }
363
        return (File[]) runnable.getReturnValue();
364
    }
365

    
366
    @Override
367
    public File[] showOpenDirectoryDialog(String title, File initialPath) {
368
        return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.DIRECTORIES_ONLY, false, initialPath, null, false);
369
    }
370

    
371
    @Override
372
    public File[] showOpenFileDialog(String title, File initialPath) {
373
        return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
374
    }
375

    
376
    @Override
377
    public File[] showSaveFileDialog(String title, File initialPath) {
378
        return showChooserDialog(title, JFileChooser.SAVE_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
379
    }
380

    
381
}