Source Code Cross Referenced for ScrollableListSelectionDialog.java in  » IDE » DrJava » edu » rice » cs » util » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.util.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.util.swing;
038:
039:        import javax.swing.*;
040:        import java.awt.*;
041:        import java.awt.event.*;
042:        import java.util.*;
043:
044:        import javax.swing.table.AbstractTableModel;
045:
046:        /**
047:         * <p>The ScrollableListSelectionDialog is a popup dialog with a message
048:         * and a scrollable list of items. Each item may be either selected or
049:         * unselected. A ScrollableListSelectionDialog should be used when
050:         * an operation needs to act on a variable number of items, for
051:         * example, when saving modified files.</p>
052:         * 
053:         * <p>The message (also know as the leader text) is displayed above the
054:         * items with an optional icon. The items are displayed in a scrollable
055:         * table. A column of checkboxes allows selection of the items. Buttons
056:         * are added below the list of items.</p>
057:         * 
058:         * <p>This dialog is somewhat styled after
059:         * {@link javax.swing.JOptionPane} and uses the message-type constants
060:         * from JOptionPane.</p>
061:         * 
062:         * @author Chris Warrington
063:         * @version $Id$
064:         * @since 2007-04-08
065:         */
066:        public class ScrollableListSelectionDialog extends JDialog {
067:            /**
068:             * A enumeration of the various selection states.
069:             */
070:            public enum SelectionState {
071:                /** Indicates that an item is selected. */
072:                SELECTED,
073:                /** Indicates that an item is not selected. */
074:                UNSELECTED
075:            };
076:
077:            /** The default width for this dialog. */
078:            private static final int DEFAULT_WIDTH = 400;
079:            /** The default height for this dialog. */
080:            private static final int DEFAULT_HEIGHT = 450;
081:
082:            /** The ratio of the screen width to use by default. */
083:            private static final double WIDTH_RATIO = .75;
084:            /** The ratio of the screen height to use by default. */
085:            private static final double HEIGHT_RATIO = .50;
086:
087:            /** The table displaying the items. */
088:            protected final JTable table;
089:            /** The AbstractTableModel backing the table. */
090:            protected final AbstractTableModel tableModel;
091:
092:            /** The number of columns in the table. */
093:            private static final int NUM_COLUMNS = 2;
094:            /** The column index of the checkboxes column. */
095:            private static final int CHECKBOXES_COLUMN_INDEX = 0;
096:            /** The column index of the strings column. */
097:            private static final int STRINGS_COLUMN_INDEX = 1;
098:
099:            /** The items in the table. */
100:            protected final Vector<String> dataAsStrings;
101:            /** The selected items in the table. This Vector maps to
102:             * _dataAsStrings by index. This value may be accessed by multiple
103:             * threads. Threads wishing to access it should acquire its
104:             * intrinsic lock. */
105:            protected final Vector<Boolean> selectedItems;
106:
107:            /**
108:             * <p>Creates a new ScrollableListSelectionDialog with the given
109:             * title, leader text, and items. The list of items is used to
110:             * construct an internal string list that is not backed by the original
111:             * list. Changes made to the list or items after dialog construction
112:             * will not be reflected in the dialog.</p>
113:             * 
114:             * <p>The default sizing, message type, and icon are used. All the
115:             * items are selected by default.</p>
116:             * 
117:             * @param owner The frame that owns this dialog. May be {@code null}.
118:             * @param dialogTitle The text to use as the dialog title.
119:             * @param leaderText Text to display before the list of items.
120:             * @param listItems The items to display in the list.
121:             * @param itemDescription A textual description of the items. This is used as the column heading for the items.
122:             * 
123:             * @throws IllegalArgumentException if {@code listItems} is {@code null.}
124:             */
125:            public ScrollableListSelectionDialog(final Frame owner,
126:                    final String dialogTitle, final String leaderText,
127:                    final Collection<?> listItems, final String itemDescription) {
128:                this (owner, dialogTitle, leaderText, listItems,
129:                        itemDescription, SelectionState.SELECTED,
130:                        JOptionPane.PLAIN_MESSAGE);
131:            }
132:
133:            /**
134:             * <p>Creates a new ScrollableListSelectionDialog with the given
135:             * title, leader text, items, and message type. The list of items is
136:             * used to construct an internal string list that is not backed by the
137:             * original list. Changes made to the list or items after dialog
138:             * construction will not be reflected in the dialog.</p>
139:             * 
140:             * <p>The message type must be one of the message types from
141:             * {@link javax.swing.JOptionPane}. The message type controlls which
142:             * default icon is used.</p>
143:             * 
144:             * <p>The default sizing and icon are used.</p>
145:             * 
146:             * @param owner The frame that owns this dialog. May be {@code null}.
147:             * @param dialogTitle The text to use as the dialog title.
148:             * @param leaderText Text to display before the list of items.
149:             * @param listItems The items to display in the list.
150:             * @param itemDescription A textual description of the items. This is used as the column heading for the items.
151:             * @param defaultSelection The default selection state (selected or unselected) for the items.
152:             * @param messageType The type of dialog message.
153:             * 
154:             * @throws IllegalArgumentException if {@code listItems} is {@code null.}
155:             * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
156:             */
157:            public ScrollableListSelectionDialog(final Frame owner,
158:                    final String dialogTitle, final String leaderText,
159:                    final Collection<?> listItems,
160:                    final String itemDescription,
161:                    final SelectionState defaultSelection, final int messageType) {
162:                this (owner, dialogTitle, leaderText, listItems,
163:                        itemDescription, defaultSelection, messageType,
164:                        DEFAULT_WIDTH, DEFAULT_HEIGHT, null, true);
165:            }
166:
167:            /**
168:             * <p>Creates a new ScrollableListSelectionDialog with the given
169:             * title, leader text, items, message type, width, height, and icon.
170:             * The list of items is used to construct an internal string list that
171:             * is not backed by the original list. Changes made to the list or
172:             * items after dialog construction will not be reflected in the
173:             * dialog.</p>
174:             * 
175:             * <p>The message type must be one of the message types from
176:             * {@link javax.swing.JOptionPane}. The message type controlls which
177:             * default icon is used. If {@code icon} is non-null, it is used
178:             * instead of the default icon.</p>
179:             * 
180:             * @param owner The frame that owns this dialog. May be {@code null}.
181:             * @param dialogTitle The text to use as the dialog title.
182:             * @param leaderText Text to display before the list of items.
183:             * @param listItems The items to display in the list.
184:             * @param itemDescription A textual description of the items. This is used as the column heading for the items.
185:             * @param defaultSelection The default selection state (selected or unselected) for the items.
186:             * @param messageType The type of dialog message.
187:             * @param width The width of the dialog box.
188:             * @param height The height of the dialog box.
189:             * @param icon The icon to display. May be {@code null}.
190:             * 
191:             * @throws IllegalArgumentException if {@code listItems} is {@code null.}
192:             * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
193:             */
194:            public ScrollableListSelectionDialog(final Frame owner,
195:                    final String dialogTitle, final String leaderText,
196:                    final Collection<?> listItems,
197:                    final String itemDescription,
198:                    final SelectionState defaultSelection,
199:                    final int messageType, final int width, final int height,
200:                    final Icon icon) {
201:                this (owner, dialogTitle, leaderText, listItems,
202:                        itemDescription, defaultSelection, messageType, width,
203:                        height, icon, false);
204:            }
205:
206:            /**
207:             * <p>Creates a new ScrollableListSelectionDialog with the given
208:             * title, leader text, items, message type, width, height, and icon.
209:             * The list of items is used to construct an internal string list that
210:             * is not backed by the original list. Changes made to the list or
211:             * items after dialog construction will not be reflected in the
212:             * dialog.</p>
213:             * 
214:             * <p>The message type must be one of the message types from
215:             * {@link javax.swing.JOptionPane}. The message type controlls which
216:             * default icon is used. If {@code icon} is non-null, it is used
217:             * instead of the default icon.</p>
218:             * 
219:             * @param owner The frame that owns this dialog. May be {@code null}.
220:             * @param dialogTitle The text to use as the dialog title.
221:             * @param leaderText Text to display before the list of items.
222:             * @param listItems The items to display in the list.
223:             * @param itemDescription A textual description of the items. This is used as the column heading for the items.
224:             * @param defaultSelection The default selection state (selected or unselected) for the items.
225:             * @param messageType The type of dialog message.
226:             * @param width The width of the dialog box.
227:             * @param height The height of the dialog box.
228:             * @param icon The icon to display. May be {@code null}.
229:             * @param fitToScreen If {@code true}, the width and height of the dialog will be calculated using the screen dimensions, {@link #WIDTH_RATIO}, and {@link #HEIGHT_RATIO}. If {@code false}, the provided width and height will be used.
230:             * 
231:             * @throws IllegalArgumentException if {@code listItems} is {@code null.}
232:             * @throws IllegalArgumentException if the message type is unknown or {@code listItems} is {@code null.}
233:             */
234:            private ScrollableListSelectionDialog(final Frame owner,
235:                    final String dialogTitle, final String leaderText,
236:                    final Collection<?> listItems,
237:                    final String itemDescription,
238:                    final SelectionState defaultSelection,
239:                    final int messageType, final int width, final int height,
240:                    final Icon icon, final boolean fitToScreen) {
241:                super (owner, dialogTitle, true);
242:
243:                if (!_isknownMessageType(messageType)) {
244:                    throw new IllegalArgumentException("The message type \""
245:                            + messageType + "\" is unknown");
246:                }
247:
248:                if (listItems == null) {
249:                    throw new IllegalArgumentException(
250:                            "listItems cannot be null");
251:                }
252:
253:                /* create the leader text panel */
254:                JLabel dialogIconLabel = null;
255:                if (icon != null) {
256:                    //use the user-provided icon
257:                    dialogIconLabel = new JLabel(icon);
258:                } else {
259:                    //lookup the message-dependent icon
260:                    Icon messageIcon = _getIcon(messageType);
261:                    if (messageIcon != null) {
262:                        dialogIconLabel = new JLabel(messageIcon);
263:                    }
264:                }
265:
266:                final JPanel leaderPanel = new JPanel();
267:                final JLabel leaderLabel = new JLabel(leaderText);
268:                leaderPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
269:                if (dialogIconLabel != null) {
270:                    leaderPanel.add(dialogIconLabel);
271:                }
272:                leaderPanel.add(leaderLabel);
273:
274:                /* create the table */
275:                //copy the items string representations into a vector
276:                dataAsStrings = new Vector<String>(listItems.size());
277:                for (Object obj : listItems) {
278:                    if (obj != null) {
279:                        final String objAsString = obj.toString();
280:                        dataAsStrings.add(objAsString);
281:                    }
282:                }
283:                dataAsStrings.trimToSize();
284:
285:                final int numItems = dataAsStrings.size();
286:
287:                selectedItems = new Vector<Boolean>(numItems);
288:                synchronized (selectedItems) {
289:                    for (int i = 0; i < numItems; ++i) {
290:                        selectedItems.add(i,
291:                                defaultSelection == SelectionState.SELECTED);
292:                    }
293:                    selectedItems.trimToSize();
294:                }
295:                assert selectedItems.size() == dataAsStrings.size();
296:
297:                tableModel = new AbstractTableModel() {
298:                    //@Override - uncomment when we start compiling with Java 6
299:                    public int getRowCount() {
300:                        return numItems;
301:                    }
302:
303:                    //@Override - uncomment when we start compiling with Java 6
304:                    public int getColumnCount() {
305:                        return NUM_COLUMNS;
306:                    }
307:
308:                    //@Override - uncomment when we start compiling with Java 6
309:                    public Object getValueAt(int row, int column) {
310:                        if (column == CHECKBOXES_COLUMN_INDEX) {
311:                            assert row >= 0;
312:                            assert row < numItems;
313:                            synchronized (selectedItems) {
314:                                return selectedItems.get(row);
315:                            }
316:                        } else if (column == STRINGS_COLUMN_INDEX) {
317:                            assert row >= 0;
318:                            assert row < numItems;
319:                            return dataAsStrings.get(row);
320:                        } else {
321:                            assert false;
322:                            return null;
323:                        }
324:                    }
325:
326:                    @Override
327:                    public String getColumnName(int column) {
328:                        if (column == CHECKBOXES_COLUMN_INDEX) {
329:                            return "";
330:                        } else if (column == STRINGS_COLUMN_INDEX) {
331:                            return itemDescription;
332:                        } else {
333:                            assert false;
334:                            return "";
335:                        }
336:                    }
337:
338:                    @Override
339:                    public Class<?> getColumnClass(final int columnIndex) {
340:                        if (columnIndex == CHECKBOXES_COLUMN_INDEX) {
341:                            return Boolean.class;
342:                        } else if (columnIndex == STRINGS_COLUMN_INDEX) {
343:                            return String.class;
344:                        } else {
345:                            assert false;
346:                            return Object.class;
347:                        }
348:                    }
349:
350:                    @Override
351:                    public boolean isCellEditable(final int rowIndex,
352:                            final int columnIndex) {
353:                        return columnIndex == CHECKBOXES_COLUMN_INDEX; //only checkboxes are editable
354:                    }
355:
356:                    @Override
357:                    public void setValueAt(final Object newValue,
358:                            final int rowIndex, final int columnIndex) {
359:                        assert columnIndex == CHECKBOXES_COLUMN_INDEX;
360:                        assert rowIndex >= 0;
361:                        assert rowIndex < numItems;
362:                        assert newValue instanceof  Boolean;
363:
364:                        final Boolean booleanValue = (Boolean) newValue;
365:
366:                        synchronized (selectedItems) {
367:                            selectedItems.set(rowIndex, booleanValue);
368:                        }
369:                    }
370:                };
371:
372:                table = new JTable(tableModel);
373:
374:                /*
375:                 * this listener enabled clicking in the string column to update the
376:                 * checkbox.
377:                 */
378:                table.addMouseListener(new MouseAdapter() {
379:                    @Override
380:                    public void mouseClicked(final MouseEvent e) {
381:                        final Point clickPoint = e.getPoint();
382:                        // which column was clicked on
383:                        final int clickColumn = table.columnAtPoint(clickPoint);
384:
385:                        if (clickColumn == STRINGS_COLUMN_INDEX) {
386:                            //it was the strings column, so update the check status of the row
387:                            //Swing does not do this automatically
388:                            final int clickRow = table.rowAtPoint(clickPoint);
389:
390:                            if (clickRow >= 0 && clickRow < numItems) {
391:                                synchronized (selectedItems) {
392:                                    final boolean currentValue = selectedItems
393:                                            .get(clickRow);
394:                                    final boolean newValue = !currentValue;
395:
396:                                    selectedItems.set(clickRow, newValue);
397:                                    /* We are deliberately holding on to the lock while the
398:                                     * listeners are notified. This, in theory, speeds up the
399:                                     * listeners because they don't have to re-acquire the
400:                                     * lock. Because the internals of Swing are unknown, the
401:                                     * lock may need to be released before the listeners are
402:                                     * notified. Only time will tell.
403:                                     * 
404:                                     * PS: If it turns out that holding the lock during
405:                                     * the listener updates is a problem, modify this comment
406:                                     * accordingly. Thank you.
407:                                     */
408:                                    tableModel.fireTableCellUpdated(clickRow,
409:                                            CHECKBOXES_COLUMN_INDEX);
410:                                }
411:                            }
412:                        }
413:                    }
414:                });
415:
416:                //set the column sizes
417:                table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX)
418:                        .setMinWidth(15);
419:                table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX)
420:                        .setMaxWidth(30);
421:                table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX)
422:                        .setPreferredWidth(20);
423:                table.getColumnModel().getColumn(CHECKBOXES_COLUMN_INDEX)
424:                        .sizeWidthToFit();
425:
426:                //create a scrollable view around the table
427:                final JScrollPane scrollPane = new JScrollPane(table);
428:
429:                /* create the select all/select none panel */
430:                final JPanel selectButtonsPanel = new JPanel();
431:                selectButtonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
432:                _addSelectButtons(selectButtonsPanel);
433:
434:                /* create the button panel */
435:                final JPanel buttonPanel = new JPanel();
436:                buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
437:                //allow children to add additional buttons, if overridden
438:                _addButtons(buttonPanel);
439:
440:                /* create the center panel which contains the scroll pane and the
441:                 * select all/select none buttons */
442:                final JPanel centerPanel = new JPanel();
443:                centerPanel.setLayout(new BorderLayout());
444:                centerPanel.add(selectButtonsPanel, BorderLayout.NORTH);
445:                centerPanel.add(scrollPane, BorderLayout.CENTER);
446:
447:                /* create the dialog */
448:                final JPanel contentPanel = new JPanel();
449:                contentPanel.setLayout(new BorderLayout(10, 5));
450:                contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 10,
451:                        0, 10));
452:
453:                contentPanel.add(leaderPanel, BorderLayout.NORTH);
454:                contentPanel.add(centerPanel, BorderLayout.CENTER);
455:                contentPanel.add(buttonPanel, BorderLayout.SOUTH);
456:
457:                getContentPane().add(contentPanel);
458:
459:                /* calculate the dialog's dimensions */
460:                final Dimension dialogSize = new Dimension();
461:
462:                if (fitToScreen) {
463:                    //use the screen dimensions to calculate the dialog's
464:                    final Dimension screenSize = Toolkit.getDefaultToolkit()
465:                            .getScreenSize();
466:                    int screenBasedWidth = (int) (WIDTH_RATIO * screenSize
467:                            .getWidth());
468:                    int screenBasedHeight = (int) (HEIGHT_RATIO * screenSize
469:                            .getHeight());
470:
471:                    dialogSize.setSize(Math
472:                            .max(DEFAULT_WIDTH, screenBasedWidth), Math.max(
473:                            DEFAULT_HEIGHT, screenBasedHeight));
474:                } else {
475:                    //use the user-provided dimensions
476:                    dialogSize.setSize(width, height);
477:                }
478:
479:                setSize(dialogSize);
480:            }
481:
482:            /**
483:             * A method to check if they given message type is a know message
484:             * type.
485:             * 
486:             * @param messageType The message type to check
487:             * @return {@code true} if the message type is known, {@code false} otherwise
488:             */
489:            private boolean _isknownMessageType(final int messageType) {
490:                return messageType == JOptionPane.ERROR_MESSAGE
491:                        || messageType == JOptionPane.INFORMATION_MESSAGE
492:                        || messageType == JOptionPane.WARNING_MESSAGE
493:                        || messageType == JOptionPane.QUESTION_MESSAGE
494:                        || messageType == JOptionPane.PLAIN_MESSAGE;
495:            }
496:
497:            /**
498:             * Lookup the icon associated with the given messageType. The message
499:             * type must be one of the message types from
500:             * {@link javax.swing.JOptionPane}.
501:             * 
502:             * @param messageType The message for which the icon is requested.
503:             * @return The message's icon or {@code null} is no icon was found.
504:             */
505:            private Icon _getIcon(final int messageType) {
506:                assert _isknownMessageType(messageType);
507:
508:                /* The OptionPane.xxxIcon constants were taken from 
509:                 * javax.swing.plaf.basic.BasicOptionPaneUI, which may changed
510:                 * without notice.
511:                 */
512:                if (messageType == JOptionPane.ERROR_MESSAGE) {
513:                    return UIManager.getIcon("OptionPane.errorIcon");
514:                } else if (messageType == JOptionPane.INFORMATION_MESSAGE) {
515:                    return UIManager.getIcon("OptionPane.informationIcon");
516:                } else if (messageType == JOptionPane.WARNING_MESSAGE) {
517:                    return UIManager.getIcon("OptionPane.warningIcon");
518:                } else if (messageType == JOptionPane.QUESTION_MESSAGE) {
519:                    return UIManager.getIcon("OptionPane.questionIcon");
520:                } else if (messageType == JOptionPane.PLAIN_MESSAGE) {
521:                    return null;
522:                } else {
523:                    //should never get here
524:                    assert false;
525:                }
526:
527:                return null;
528:            }
529:
530:            /**
531:             * Adds the &quot;Select All&quot; and &quot;Select None&quot; buttons
532:             * to the given panel.
533:             * 
534:             * @param selectButtonsPanel The panel that should contain the buttons.
535:             */
536:            private void _addSelectButtons(final JPanel selectButtonsPanel) {
537:                final JButton selectAllButton = new JButton("Select All");
538:                selectAllButton.setMnemonic(KeyEvent.VK_A);
539:                selectAllButton
540:                        .addActionListener(new SelectAllNoneActionListener(
541:                                SelectionState.SELECTED));
542:                selectButtonsPanel.add(selectAllButton);
543:
544:                final JButton selectNoneButton = new JButton("Select None");
545:                selectNoneButton.setMnemonic(KeyEvent.VK_N);
546:                selectNoneButton
547:                        .addActionListener(new SelectAllNoneActionListener(
548:                                SelectionState.UNSELECTED));
549:                selectButtonsPanel.add(selectNoneButton);
550:            }
551:
552:            /**
553:             * Adds buttons to the bottom of the dialog. By default, a single
554:             * &quot;OK&quot; button is added that calls {@link #closeDialog}. It
555:             * is also set as the dialog's default button.
556:             *
557:             * Inheritors should feel free the change settings of the panel such
558:             * as the layout manager. However, no guarantees are made that every
559:             * change will work with every version of this class.
560:             * 
561:             * @param buttonPanel The JPanel that should contain the buttons.
562:             */
563:            protected void _addButtons(final JPanel buttonPanel) {
564:                final JButton okButton = new JButton("OK");
565:                okButton.addActionListener(new ActionListener() {
566:                    public void actionPerformed(ActionEvent notUsed) {
567:                        closeDialog();
568:                    }
569:                });
570:
571:                buttonPanel.add(okButton);
572:                getRootPane().setDefaultButton(okButton);
573:            }
574:
575:            /**
576:             * Shows the dialog.
577:             */
578:            public void showDialog() {
579:                pack();
580:                setVisible(true);
581:            }
582:
583:            /**
584:             * Should be called when the dialog should be closed. The default implementation
585:             * simply hides the dialog.
586:             */
587:            protected void closeDialog() {
588:                setVisible(false);
589:            }
590:
591:            /**
592:             * Returns the string representation of those items that are
593:             * currently selected. The items will be in the same relative order
594:             * as they were at construction time. The resultant collection may be
595:             * empty. The resultant collection is unmodifiable. The resultant
596:             * collection is simply a snapshot (i.e., It will not be updated as
597:             * more items are selected.). This method may be called from
598:             * non-event&nbsp;queue threads.
599:             * 
600:             * @return The currently selected items.
601:             */
602:            public java.util.List<String> selectedItems() {
603:                final java.util.List<String> results = new ArrayList<String>();
604:
605:                synchronized (selectedItems) {
606:                    /* This entire loop is synchronized so that we get a consistent
607:                     * view of the selected items. It is also faster.
608:                     */
609:                    for (int i = 0; i < dataAsStrings.size(); ++i) {
610:                        if (selectedItems.get(i)) {
611:                            results.add(dataAsStrings.get(i));
612:                        }
613:                    }
614:                }
615:
616:                return Collections.unmodifiableList(results);
617:            }
618:
619:            /**
620:             * An ActionListener that handles the &quot;Select All&quot; and
621:             * &quot;Select None&quot; buttons. It will set the selection state
622:             * of every item to the given selection state.
623:             */
624:            private class SelectAllNoneActionListener implements  ActionListener {
625:                /** The value that the selection state will be set to when this
626:                 * listener runs. */
627:                private final boolean _setToValue;
628:
629:                /**
630:                 * Creates a new SelectAllNoneActionListener that will set the state
631:                 * of every item to the given state.
632:                 * 
633:                 * @param setToState The state to set all the items to.
634:                 */
635:                public SelectAllNoneActionListener(SelectionState setToState) {
636:                    _setToValue = setToState == SelectionState.SELECTED;
637:                }
638:
639:                /**
640:                 * The code that runs in response to the button's action.
641:                 * This is the code that actually sets the selection state of the
642:                 * items.
643:                 * 
644:                 * @param notUsed Not used.
645:                 */
646:                public void actionPerformed(ActionEvent notUsed) {
647:                    /* See comment in the table's mouse listener for a discussion
648:                     * about the duration of the lock.
649:                     */
650:                    synchronized (selectedItems) {
651:                        for (int i = 0; i < selectedItems.size(); ++i) {
652:                            selectedItems.set(i, _setToValue);
653:                        }
654:                        tableModel.fireTableRowsUpdated(0, Math.max(0,
655:                                selectedItems.size() - 1));
656:                    }
657:                }
658:            }
659:
660:            /**
661:             * A simple main method for testing purposes.
662:             * 
663:             * @param args Not used.
664:             */
665:            public static void main(String args[]) {
666:                final Collection<String> data = new java.util.ArrayList<String>();
667:                data.add("how");
668:                data.add("now");
669:                data.add("brown");
670:                data.add("cow");
671:
672:                SwingUtilities.invokeLater(new Runnable() {
673:                    public void run() {
674:                        ScrollableListSelectionDialog ld = new ScrollableListSelectionDialog(
675:                                null, "TITLE", "LEADER", data, "Words",
676:                                SelectionState.SELECTED,
677:                                JOptionPane.ERROR_MESSAGE) {
678:                            @Override
679:                            protected void closeDialog() {
680:                                super .closeDialog();
681:                                Collection<String> si = selectedItems();
682:                                for (String i : si) {
683:                                    System.out.println(i);
684:                                }
685:                            }
686:                        };
687:                        ld.pack();
688:                        ld.setVisible(true);
689:                    }
690:                });
691:            }
692:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.