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

History | View | Annotate | Download (15.3 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
import com.notification.NotificationFactory;
49
import com.notification.NotificationFactory.Location;
50
import com.notification.NotificationManager;
51
import com.notification.manager.SimpleManager;
52
import com.notification.types.TextNotification;
53
import com.theme.ThemePackagePresets;
54
import com.utils.Time;
55

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

    
64
    private static Logger logger = LoggerFactory
65
        .getLogger(DefaultThreadSafeDialogsManager.class);
66
    private final Component rootComponent;
67

    
68
    public DefaultThreadSafeDialogsManager() {
69
        this.rootComponent = null;
70
    }
71

    
72
    public DefaultThreadSafeDialogsManager(Component rootComponent) {
73
        this.rootComponent = rootComponent;
74
    }
75

    
76
    protected Component getRootComponent() {
77
        return this.rootComponent;
78
    }
79

    
80
    private String translate(String message) {
81
        I18nManager i18nManager = ToolsLocator.getI18nManager();
82
        return i18nManager.getTranslation(message);
83
    }
84

    
85
    private String translate(String message, String[] args) {
86
        I18nManager i18nManager = ToolsLocator.getI18nManager();
87
        return i18nManager.getTranslation(message, args);
88
    }
89

    
90
    @Override
91
    public int confirmDialog(final String message, final String title, final int optionType,
92
        final int messageType) {
93
        return this.confirmDialog(message, title, optionType, messageType, null);
94
    }
95

    
96
    @Override
97
    public void message(String message, int message_type) {
98
        try {
99
            // makes a factory with the built-in clean theme
100
            // themes are customizeable
101
            NotificationFactory factory = new NotificationFactory(ThemePackagePresets.cleanLight());
102
            // factories build notifications using a theme, while managers handle how
103
            // how they appear on the screen
104
            // this manager just simple pops up the notification in the specified location
105
            // other managers do sliding, queues, etc.
106
            NotificationManager plain = new SimpleManager(Location.SOUTHWEST);
107

    
108
            // creates a text notification; you can also have progress bar Notifications,
109
            // icon Notifications, Notifications that ask for user feedback, etc.
110
            TextNotification notification = factory.buildTextNotification(
111
                    "Message",
112
                    message);
113
            notification.setCloseOnClick(true);
114
            // the notification will disappear after 2 seconds, or after you click it 
115
            plain.addNotification(notification, Time.seconds(2));        
116
        } catch(Exception ex) {
117
            System.out.println("Message: "+message);
118
        }
119
    }
120

    
121
    private static class JMessageWithCheck extends JPanel {
122

    
123
        private static final long serialVersionUID = -1902712909850016361L;
124
        private final JLabel label;
125
        private final JCheckBox check;
126

    
127
        public JMessageWithCheck(String msg, String msgchk) {
128
            if( !msg.toLowerCase().trim().startsWith("<html>") ) {
129
                msg = "<html>" + msg.replace("\n", "<br>\n") + "</html>";
130
            }
131
            this.label = new JLabel(msg);
132
            this.check = new JCheckBox(msgchk);
133
            this.setLayout(new BorderLayout(10, 10));
134
            this.add(this.label, BorderLayout.CENTER);
135
            this.add(this.check, BorderLayout.PAGE_END);
136
        }
137

    
138
        public boolean isCheckSelected() {
139
            return this.check.isSelected();
140
        }
141
    }
142

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

    
190
    @Override
191
    public String inputDialog(final String message, final String title, final int messageType,
192
        final String initialValue) {
193
        RunnableWithParameters runnable = new RunnableWithParameters() {
194
            @Override
195
            public void run() {
196
                this.returnValue = JOptionPane.showInputDialog(
197
                    getRootComponent(), translate(message),
198
                    translate(title),
199
                    messageType, null, null,
200
                    initialValue);
201
            }
202
        };
203
        if( SwingUtilities.isEventDispatchThread() ) {
204
            runnable.run();
205
        } else {
206
            try {
207
                SwingUtilities.invokeAndWait(runnable);
208
            } catch (Exception e) {
209
                logger.info("Can't show input dialog '" + message + "'.", e);
210
            }
211
        }
212
        return (String) runnable.getReturnValue();
213
    }
214

    
215
    @Override
216
    public String inputDialog(final String message, final String title) {
217
        RunnableWithParameters runnable = new RunnableWithParameters() {
218
            @Override
219
            public void run() {
220
                this.returnValue = JOptionPane.showInputDialog(
221
                    getRootComponent(), (String) translate(message),
222
                    translate(title),
223
                    JOptionPane.QUESTION_MESSAGE, null, null, null);
224
            }
225
        };
226
        if( SwingUtilities.isEventDispatchThread() ) {
227
            runnable.run();
228
        } else {
229
            try {
230
                SwingUtilities.invokeAndWait(runnable);
231
            } catch (Exception e) {
232
                logger.info("Can't show input dialog '" + message + "'.", e);
233
            }
234
        }
235
        return (String) runnable.getReturnValue();
236
    }
237

    
238
    @Override
239
    public void messageDialog(String message, String title, int messageType) {
240
        messageDialog(message, null, title, messageType);
241
    }
242

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

    
249
    @Override
250
    public void messageDialog(final String message, final String messageArgs[],
251
        final String title, final int messageType, final String msgid) {
252
        if( !SwingUtilities.isEventDispatchThread() ) {
253
            try {
254
                SwingUtilities.invokeAndWait(new Runnable() {
255
                    @Override
256
                    public void run() {
257
                        messageDialog(message, messageArgs, title, messageType, msgid);
258
                    }
259
                });
260
            } catch (Exception e) {
261
                logger.warn("Can't show message dialog '" + message + "'.", e);
262
            }
263
            return;
264
        }
265

    
266
        if( message == null ) {
267
            logger.info("message if null, message dialog not show.");
268
            return;
269
        }
270
        DialogReminder r = null;
271
        Object msg = translate(message, messageArgs);
272
        if( msgid != null ) {
273
            r = ToolsSwingLocator.getDialogReminderManager().add(msgid);
274
            if( r.hasValue() && ((boolean) r.getValue()) ) {
275
                return;
276
            }
277
            msg = new JMessageWithCheck(
278
                translate(message, messageArgs),
279
                ToolsLocator.getI18nManager().getTranslation("_do_not_show_again")
280
            );
281
        }
282
        JOptionPane.showMessageDialog(getRootComponent(),
283
            msg, translate(title), messageType);
284

    
285
        if( r != null ) {
286
            if( ((JMessageWithCheck) msg).isCheckSelected() ) {
287
                r.setValue(true);
288
            } else {
289
                r.reset();
290
            }
291
        }
292

    
293
    }
294

    
295
    @Override
296
    public Component createComponent(final Class<? extends Component> theClass,
297
        final Object... parameters) {
298
        return createComponentWithParams(theClass, parameters);
299
    }
300

    
301
    @Override
302
    public Component createComponentWithParams(
303
        final Class<? extends Component> theClass, final Object[] parameters) {
304
        final Class<?>[] parameterTypes = new Class<?>[parameters.length];
305
        for( int i = 0; i < parameters.length; i++ ) {
306
            parameterTypes[i] = parameters[i].getClass();
307
        }
308
        final Component component;
309
        final Constructor<?> constructor;
310
        try {
311
            constructor = theClass.getConstructor(parameterTypes);
312
        } catch (Exception e) {
313
            throw new IllegalArgumentException(e);
314
        }
315
        if( SwingUtilities.isEventDispatchThread() ) {
316
            try {
317
                component = (Component) constructor.newInstance(parameters);
318
            } catch (Exception e) {
319
                throw new IllegalArgumentException(e);
320
            }
321
        } else {
322
            try {
323
                RunnableWithParameters runnable = new RunnableWithParameters(parameters) {
324
                    @Override
325
                    public void run() {
326
                        Constructor<?> cons = constructor;
327
                        try {
328
                            this.returnValue = cons.newInstance(parameters.toArray());
329
                        } catch (Exception e) {
330
                            String msg = "Can't create instance of components, constructor=" + cons.toString() + ", parameters=" + this.parameters.toString() + ".";
331
                            logger.info(msg, e);
332
                            throw new IllegalArgumentException(e);
333
                        }
334
                    }
335
                };
336
                SwingUtilities.invokeAndWait(runnable);
337
                component = (Component) runnable.getReturnValue();
338
            } catch (Exception e) {
339
                throw new IllegalArgumentException(e);
340
            }
341
        }
342
        return component;
343
    }
344

    
345
    @Override
346
    public File[] showChooserDialog(
347
        final String title,
348
        final int type, // SAVE_DIALOG / OPEN_DIALOG
349
        final int selectionMode, //    JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY, JFileChooser.FILES_AND_DIRECTORIES
350
        final boolean multiselection,
351
        final File initialPath,
352
        final FileFilter filter,
353
        final boolean fileHidingEnabled
354
    ) {
355
        RunnableWithParameters runnable = new RunnableWithParameters() {
356
            @Override
357
            public void run() {
358
                JFileChooser fc = new JFileChooser();
359
                fc.setDialogTitle(title);
360
                fc.setDialogType(type);
361
                fc.setFileSelectionMode(selectionMode);
362
                fc.setMultiSelectionEnabled(multiselection);
363
                fc.setCurrentDirectory(initialPath);
364
                fc.setFileFilter(filter);
365
                fc.setFileHidingEnabled(fileHidingEnabled);
366
                int r;
367
                switch( type ) {
368
                case JFileChooser.SAVE_DIALOG:
369
                    r = fc.showSaveDialog(getRootComponent());
370
                    break;
371
                case JFileChooser.OPEN_DIALOG:
372
                default:
373
                    r = fc.showOpenDialog(getRootComponent());
374
                    break;
375
                }
376
                if( r != JFileChooser.APPROVE_OPTION ) {
377
                    this.returnValue = null;
378
                    return;
379
                }
380
                if( fc.isMultiSelectionEnabled() ) {
381
                    this.returnValue = fc.getSelectedFiles();
382
                } else {
383
                    this.returnValue = new File[]{fc.getSelectedFile()};
384
                }
385
            }
386
        };
387
        if( SwingUtilities.isEventDispatchThread() ) {
388
            runnable.run();
389
        } else {
390
            try {
391
                SwingUtilities.invokeAndWait(runnable);
392
            } catch (Exception e) {
393
                logger.info("Can't show chooser dialog '" + title + "'.", e);
394
            }
395
        }
396
        return (File[]) runnable.getReturnValue();
397
    }
398

    
399
    @Override
400
    public File[] showOpenDirectoryDialog(String title, File initialPath) {
401
        return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.DIRECTORIES_ONLY, false, initialPath, null, false);
402
    }
403

    
404
    @Override
405
    public File[] showOpenFileDialog(String title, File initialPath) {
406
        return showChooserDialog(title, JFileChooser.OPEN_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
407
    }
408

    
409
    @Override
410
    public File[] showSaveFileDialog(String title, File initialPath) {
411
        return showChooserDialog(title, JFileChooser.SAVE_DIALOG, JFileChooser.FILES_ONLY, false, initialPath, null, false);
412
    }
413

    
414
}