Source Code Cross Referenced for Select.java in  » Web-Framework » Millstone » org » millstone » base » ui » 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 » Web Framework » Millstone » org.millstone.base.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* *************************************************************************
0002:         
0003:                                        Millstone(TM) 
0004:                           Open Sourced User Interface Library for
0005:                               Internet Development with Java
0006:
0007:                     Millstone is a registered trademark of IT Mill Ltd
0008:                          Copyright (C) 2000-2005 IT Mill Ltd
0009:                             
0010:         *************************************************************************
0011:
0012:           This library is free software; you can redistribute it and/or
0013:           modify it under the terms of the GNU Lesser General Public
0014:           license version 2.1 as published by the Free Software Foundation.
0015:
0016:           This library is distributed in the hope that it will be useful,
0017:           but WITHOUT ANY WARRANTY; without even the implied warranty of
0018:           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019:           Lesser General Public License for more details.
0020:
0021:           You should have received a copy of the GNU Lesser General Public
0022:           License along with this library; if not, write to the Free Software
0023:           Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0024:
0025:         *************************************************************************
0026:           
0027:           For more information, contact:
0028:           
0029:           IT Mill Ltd                           phone: +358 2 4802 7180
0030:           Ruukinkatu 2-4                        fax:  +358 2 4802 7181
0031:           20540, Turku                          email: info@itmill.com
0032:           Finland                               company www: www.itmill.com
0033:           
0034:           Primary source for MillStone information and releases: www.millstone.org
0035:
0036:         ********************************************************************** */
0037:
0038:        package org.millstone.base.ui;
0039:
0040:        import java.util.Collection;
0041:        import java.util.Collections;
0042:        import java.util.HashSet;
0043:        import java.util.HashMap;
0044:        import java.util.Iterator;
0045:        import java.util.LinkedList;
0046:        import java.util.Map;
0047:        import java.util.Set;
0048:
0049:        import org.millstone.base.data.Container;
0050:        import org.millstone.base.data.Item;
0051:        import org.millstone.base.data.Property;
0052:        import org.millstone.base.data.util.IndexedContainer;
0053:        import org.millstone.base.terminal.KeyMapper;
0054:        import org.millstone.base.terminal.PaintException;
0055:        import org.millstone.base.terminal.PaintTarget;
0056:        import org.millstone.base.terminal.Resource;
0057:
0058:        /** <p>A class representing a selection of items the user has selected in a
0059:         * UI. The set of choices is presented as a set of
0060:         * {@link org.millstone.base.data.Item}s in a 
0061:         * {@link org.millstone.base.data.Container}.</p>
0062:         * 
0063:         * <p>A <code>Select</code> component may be in single- or multiselect mode.
0064:         * Multiselect mode means that more than one item can be selected
0065:         * simultaneously.</p>
0066:         *
0067:         * @author IT Mill Ltd.
0068:         * @version 3.1.1
0069:         * @since 3.0
0070:         */
0071:        public class Select extends AbstractField implements  Container,
0072:                Container.Viewer, Container.PropertySetChangeListener,
0073:                Container.PropertySetChangeNotifier,
0074:                Container.ItemSetChangeNotifier,
0075:                Container.ItemSetChangeListener {
0076:
0077:            /** Item caption mode: Item's ID's <code>String</code> representation
0078:             * is used as caption.
0079:             */
0080:            public static final int ITEM_CAPTION_MODE_ID = 0;
0081:
0082:            /** Item caption mode: Item's <code>String</code> representation is
0083:             * used as caption.
0084:             */
0085:            public static final int ITEM_CAPTION_MODE_ITEM = 1;
0086:
0087:            /** Item caption mode: Index of the item is used as caption. The
0088:             * index mode can only be used with the containers implementing the
0089:             * {@link org.millstone.base.data.Container.Indexed} interface.
0090:             */
0091:            public static final int ITEM_CAPTION_MODE_INDEX = 2;
0092:
0093:            /** Item caption mode: If an Item has a caption it's used, if not,
0094:             * Item's ID's <code>String</code> representation is used as caption.
0095:             * <b>This is the default</b>.
0096:             */
0097:            public static final int ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = 3;
0098:
0099:            /** Item caption mode: Captions must be explicitly specified.
0100:             */
0101:            public static final int ITEM_CAPTION_MODE_EXPLICIT = 4;
0102:
0103:            /** Item caption mode: Only icons are shown, captions are hidden.
0104:             */
0105:            public static final int ITEM_CAPTION_MODE_ICON_ONLY = 5;
0106:
0107:            /** Item caption mode: Item captions are read from property specified 
0108:             * with <code>setItemCaptionPropertyId</code>.
0109:             */
0110:            public static final int ITEM_CAPTION_MODE_PROPERTY = 6;
0111:
0112:            /** Is the select in multiselect mode? */
0113:            private boolean multiSelect = false;
0114:
0115:            /** Select options */
0116:            protected Container items;
0117:
0118:            /** Is the user allowed to add new options? */
0119:            private boolean allowNewOptions;
0120:
0121:            /** Keymapper used to map key values */
0122:            protected KeyMapper itemIdMapper = new KeyMapper();
0123:
0124:            /** Item icons */
0125:            private HashMap itemIcons = new HashMap();
0126:
0127:            /** Item captions */
0128:            private HashMap itemCaptions = new HashMap();
0129:
0130:            /** Item caption mode */
0131:            private int itemCaptionMode = ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID;
0132:
0133:            /** Item caption source property id */
0134:            private Object itemCaptionPropertyId = null;
0135:
0136:            /** Item icon source property id */
0137:            private Object itemIconPropertyId = null;
0138:
0139:            /** List of property set change event listeners */
0140:            private LinkedList propertySetEventListeners = null;
0141:
0142:            /** List of item set change event listeners */
0143:            private LinkedList itemSetEventListeners = null;
0144:
0145:            /** Item id that represents null selection of this select.
0146:             * 
0147:             * <p>Data interface does not support nulls as item ids. Selecting the item idetified 
0148:             * by this id is the same as selecting no items at all. This setting only affects the
0149:             * single select mode.</p>
0150:             */
0151:            private Object nullSelectionItemId = null;
0152:
0153:            /* Constructors ********************************************************* */
0154:
0155:            /** Creates an empty Select.
0156:             * The caption is not used.
0157:             */
0158:            public Select() {
0159:                setContainerDataSource(new IndexedContainer());
0160:            }
0161:
0162:            /** Creates an empty Select with caption.
0163:             */
0164:            public Select(String caption) {
0165:                setContainerDataSource(new IndexedContainer());
0166:                setCaption(caption);
0167:            }
0168:
0169:            /** Creates a new select wthat is connected to a data-source.
0170:             * @param dataSource Container datasource to be selected from by this select.
0171:             * @param caption Caption of the component.
0172:             * @param selected Selected item id or null, if none selected.
0173:             */
0174:            public Select(String caption, Container dataSource) {
0175:                setCaption(caption);
0176:                setContainerDataSource(dataSource);
0177:            }
0178:
0179:            /** Creates a new select that is filled from a collection of option values.
0180:             * @param caption Caption of this field.
0181:             * @param options Collection containing the options.
0182:             * @param selected Selected option or null, if none selected.
0183:             */
0184:            public Select(String caption, Collection options) {
0185:
0186:                // Create options container and add given options to it
0187:                Container c = new IndexedContainer();
0188:                if (options != null)
0189:                    for (Iterator i = options.iterator(); i.hasNext();)
0190:                        c.addItem(i.next());
0191:
0192:                setCaption(caption);
0193:                setContainerDataSource((Container) c);
0194:            }
0195:
0196:            /* Component methods **************************************************** */
0197:
0198:            /** Paint the content of this component.
0199:             * @param event PaintEvent.
0200:             * @throws PaintException The paint operation failed.
0201:             */
0202:            public void paintContent(PaintTarget target) throws PaintException {
0203:
0204:                // Paint field properties
0205:                super .paintContent(target);
0206:
0207:                // Paint select attributes
0208:                if (isMultiSelect())
0209:                    target.addAttribute("selectmode", "multi");
0210:                if (isNewItemsAllowed())
0211:                    target.addAttribute("allownewitem", true);
0212:
0213:                // Paint options and create array of selected id keys
0214:                String[] selectedKeys;
0215:                if (isMultiSelect())
0216:                    selectedKeys = new String[((Set) getValue()).size()];
0217:                else
0218:                    selectedKeys = new String[(getValue() == null
0219:                            && getNullSelectionItemId() == null ? 0 : 1)];
0220:                int keyIndex = 0;
0221:                target.startTag("options");
0222:
0223:                // Support for external null selection item id
0224:                Collection ids = getItemIds();
0225:                if (getNullSelectionItemId() != null
0226:                        && (!ids.contains(getNullSelectionItemId()))) {
0227:
0228:                    // Get the option attribute values
0229:                    Object id = getNullSelectionItemId();
0230:                    String key = itemIdMapper.key(id);
0231:                    String caption = getItemCaption(id);
0232:                    Resource icon = getItemIcon(id);
0233:
0234:                    // Paint option
0235:                    target.startTag("so");
0236:                    if (icon != null)
0237:                        target.addAttribute("icon", icon);
0238:                    target.addAttribute("caption", caption);
0239:                    target.addAttribute("nullselection", true);
0240:                    target.addAttribute("key", key);
0241:                    if (isSelected(id)) {
0242:                        target.addAttribute("selected", true);
0243:                        selectedKeys[keyIndex++] = key;
0244:                    }
0245:                    target.endTag("so");
0246:                }
0247:
0248:                // Paint available selection options from data source
0249:                for (Iterator i = getItemIds().iterator(); i.hasNext();) {
0250:
0251:                    // Get the option attribute values
0252:                    Object id = i.next();
0253:                    String key = itemIdMapper.key(id);
0254:                    String caption = getItemCaption(id);
0255:                    Resource icon = getItemIcon(id);
0256:
0257:                    // Paint option
0258:                    target.startTag("so");
0259:                    if (icon != null)
0260:                        target.addAttribute("icon", icon);
0261:                    target.addAttribute("caption", caption);
0262:                    if (id != null && id.equals(getNullSelectionItemId()))
0263:                        target.addAttribute("nullselection", true);
0264:                    target.addAttribute("key", key);
0265:                    if (isSelected(id) && keyIndex < selectedKeys.length) {
0266:                        target.addAttribute("selected", true);
0267:                        selectedKeys[keyIndex++] = key;
0268:                    }
0269:                    target.endTag("so");
0270:                }
0271:                target.endTag("options");
0272:
0273:                // Paint variables
0274:                target.addVariable(this , "selected", selectedKeys);
0275:                if (isNewItemsAllowed())
0276:                    target.addVariable(this , "newitem", "");
0277:            }
0278:
0279:            /** Invoked when the value of a variable has changed.
0280:             * @param event Variable change event containing the information about
0281:             * the changed variable.
0282:             */
0283:            public void changeVariables(Object source, Map variables) {
0284:
0285:                // Try to set the property value
0286:
0287:                // New option entered (and it is allowed)
0288:                String newitem = (String) variables.get("newitem");
0289:                if (newitem != null && newitem.length() > 0) {
0290:
0291:                    // Check for readonly
0292:                    if (isReadOnly())
0293:                        throw new Property.ReadOnlyException();
0294:
0295:                    // Add new option
0296:                    if (addItem(newitem) != null) {
0297:
0298:                        // Set the caption property, if used
0299:                        if (getItemCaptionPropertyId() != null)
0300:                            try {
0301:                                getContainerProperty(newitem,
0302:                                        getItemCaptionPropertyId()).setValue(
0303:                                        newitem);
0304:                            } catch (Property.ConversionException ignored) {
0305:                                // The conversion exception is safely ignored, the caption is
0306:                                // just missing 
0307:                            }
0308:                    }
0309:                }
0310:
0311:                // Selection change
0312:                if (variables.containsKey("selected")) {
0313:                    String[] ka = (String[]) variables.get("selected");
0314:
0315:                    // Multiselect mode
0316:                    if (isMultiSelect()) {
0317:
0318:                        // Convert the key-array to id-set
0319:                        LinkedList s = new LinkedList();
0320:                        for (int i = 0; i < ka.length; i++) {
0321:                            Object id = itemIdMapper.get(ka[i]);
0322:                            if (id != null && containsId(id))
0323:                                s.add(id);
0324:                            else if (itemIdMapper.isNewIdKey(ka[i])
0325:                                    && newitem != null && newitem.length() > 0)
0326:                                s.add(newitem);
0327:                        }
0328:
0329:                        // Limit the deselection to the set of visible items
0330:                        // (non-visible items can not be deselected)
0331:                        Collection visible = getVisibleItemIds();
0332:                        if (visible != null) {
0333:                            Set newsel = (Set) getValue();
0334:                            if (newsel == null)
0335:                                newsel = new HashSet();
0336:                            else
0337:                                newsel = new HashSet(newsel);
0338:                            newsel.removeAll(visible);
0339:                            newsel.addAll(s);
0340:                            super .setValue(newsel);
0341:                        }
0342:                    }
0343:
0344:                    // Single select mode
0345:                    else {
0346:                        if (ka.length == 0) {
0347:
0348:                            // Allow deselection only if the deselected item is visible
0349:                            Object current = getValue();
0350:                            Collection visible = getVisibleItemIds();
0351:                            if (visible != null && visible.contains(current))
0352:                                setValue(null);
0353:                        } else {
0354:                            Object id = itemIdMapper.get(ka[0]);
0355:                            if (id != null
0356:                                    && id.equals(getNullSelectionItemId()))
0357:                                setValue(null);
0358:                            else if (itemIdMapper.isNewIdKey(ka[0]))
0359:                                setValue(newitem);
0360:                            else
0361:                                setValue(id);
0362:                        }
0363:                    }
0364:                }
0365:            }
0366:
0367:            /** Get component UIDL tag.
0368:             * @return Component UIDL tag as string.
0369:             */
0370:            public String getTag() {
0371:                return "select";
0372:            }
0373:
0374:            /** Get the visible item ids. In Select, this returns list of all item ids, 
0375:             * but can be overriden in subclasses if they paint only part of the items 
0376:             * to the terminal or null if no items is visible.
0377:             */
0378:            public Collection getVisibleItemIds() {
0379:                if (isVisible())
0380:                    return getItemIds();
0381:                return null;
0382:            }
0383:
0384:            /* Property methods ***************************************************** */
0385:
0386:            /** Return the type of the property.
0387:             * getValue and setValue functions must be compatible with this type:
0388:             * one can safely cast getValue() to given type and pass any variable
0389:             * assignable to this type as a parameter to setValue().
0390:             * @return type Type of the property.
0391:             */
0392:            public Class getType() {
0393:                if (isMultiSelect())
0394:                    return Set.class;
0395:                else
0396:                    return Object.class;
0397:            }
0398:
0399:            /** Get the selected item id or in multiselect mode a set of selected ids.
0400:             */
0401:            public Object getValue() {
0402:                Object retValue = super .getValue();
0403:
0404:                if (isMultiSelect()) {
0405:
0406:                    // If the return value is not a set
0407:                    if (retValue == null)
0408:                        return new HashSet();
0409:                    if (retValue instanceof  Set) {
0410:                        return Collections.unmodifiableSet((Set) retValue);
0411:                    } else if (retValue instanceof  Collection) {
0412:                        return new HashSet((Collection) retValue);
0413:                    } else {
0414:                        Set s = new HashSet();
0415:                        if (items.containsId(retValue))
0416:                            s.add(retValue);
0417:                        return s;
0418:                    }
0419:
0420:                } else
0421:                    return retValue;
0422:            }
0423:
0424:            /** Set the visible value of the property.
0425:             *
0426:             * <p>The value of the select is the selected item id. If the select is in 
0427:             * multiselect-mode, the value is a set of selected item keys. In multiselect
0428:             * mode all collections of id:s can be assigned.</p>
0429:             * 
0430:             * @param newValue New selected item or collection of selected items.
0431:             */
0432:            public void setValue(Object newValue)
0433:                    throws Property.ReadOnlyException,
0434:                    Property.ConversionException {
0435:
0436:                if (isMultiSelect()) {
0437:                    if (newValue == null)
0438:                        super .setValue(new HashSet());
0439:                    else if (Collection.class.isAssignableFrom(newValue
0440:                            .getClass()))
0441:                        super .setValue(new HashSet((Collection) newValue));
0442:                } else if (newValue == null || items.containsId(newValue))
0443:                    super .setValue(newValue);
0444:            }
0445:
0446:            /* Container methods **************************************************** */
0447:
0448:            /** Get the item from the container with given id.
0449:             * If the container does not contain the requested item, null is returned.
0450:             */
0451:            public Item getItem(Object itemId) {
0452:                return items.getItem(itemId);
0453:            }
0454:
0455:            /** Get item Id collection from the container.
0456:             * @return Collection of item ids.
0457:             */
0458:            public Collection getItemIds() {
0459:                return items.getItemIds();
0460:            }
0461:
0462:            /** Get property Id collection from the container.
0463:             * @return Collection of property ids.
0464:             */
0465:            public Collection getContainerPropertyIds() {
0466:                return items.getContainerPropertyIds();
0467:            }
0468:
0469:            /** Get property type.
0470:             * @param id Id identifying the of the property.
0471:             */
0472:            public Class getType(Object propertyId) {
0473:                return items.getType(propertyId);
0474:            }
0475:
0476:            /** Get the number of items in the container.
0477:             * @return Number of items in the container.
0478:             */
0479:            public int size() {
0480:                return items.size();
0481:            }
0482:
0483:            /** Test, if the collection contains an item with given id.
0484:             * @param itemId Id the of item to be tested.
0485:             */
0486:            public boolean containsId(Object itemId) {
0487:                if (itemId != null)
0488:                    return items.containsId(itemId);
0489:                else
0490:                    return false;
0491:            }
0492:
0493:            /**
0494:             * @see org.millstone.base.data.Container#getContainerProperty(Object, Object)
0495:             */
0496:            public Property getContainerProperty(Object itemId,
0497:                    Object propertyId) {
0498:                return items.getContainerProperty(itemId, propertyId);
0499:            }
0500:
0501:            /* Container.Managed methods ******************************************** */
0502:
0503:            /** Add new property to all items.
0504:             * Adds a property with given id, type and default value to all items
0505:             * in the container.
0506:             *
0507:             * This functionality is optional. If the function is unsupported, it always
0508:             * returns false.
0509:             *
0510:             * @return True iff the operation succeeded.
0511:             */
0512:            public boolean addContainerProperty(Object propertyId, Class type,
0513:                    Object defaultValue) throws UnsupportedOperationException {
0514:
0515:                boolean retval = items.addContainerProperty(propertyId, type,
0516:                        defaultValue);
0517:                if (retval
0518:                        && !(items instanceof  Container.PropertySetChangeNotifier)) {
0519:                    firePropertySetChange();
0520:                }
0521:                return retval;
0522:            }
0523:
0524:            /** Remove all items from the container.
0525:             *
0526:             * This functionality is optional. If the function is unsupported, it always
0527:             * returns false.
0528:             *
0529:             * @return True iff the operation succeeded.
0530:             */
0531:            public boolean removeAllItems()
0532:                    throws UnsupportedOperationException {
0533:
0534:                boolean retval = items.removeAllItems();
0535:                this .itemIdMapper.removeAll();
0536:                if (retval) {
0537:                    setValue(null);
0538:                    if (!(items instanceof  Container.ItemSetChangeNotifier))
0539:                        fireItemSetChange();
0540:                }
0541:                return retval;
0542:            }
0543:
0544:            /** Create a new item into container with container managed id.
0545:             * The id of the created new item is returned. The item can be fetched with
0546:             * getItem() method.
0547:             * if the creation fails, null is returned.
0548:             *
0549:             * @return Id of the created item or null in case of failure.
0550:             */
0551:            public Object addItem() throws UnsupportedOperationException {
0552:
0553:                Object retval = items.addItem();
0554:                if (retval != null
0555:                        && !(items instanceof  Container.ItemSetChangeNotifier))
0556:                    fireItemSetChange();
0557:                return retval;
0558:            }
0559:
0560:            /** Create a new item into container.
0561:             * The created new item is returned and ready for setting property values.
0562:             * if the creation fails, null is returned. In case the container already
0563:             * contains the item, null is returned.
0564:             *
0565:             * This functionality is optional. If the function is unsupported, it always
0566:             * returns null.
0567:             *
0568:             * @param itemId Identification of the item to be created.
0569:             * @return Created item with the given id, or null in case of failure.
0570:             */
0571:            public Item addItem(Object itemId)
0572:                    throws UnsupportedOperationException {
0573:
0574:                Item retval = items.addItem(itemId);
0575:                if (retval != null
0576:                        && !(items instanceof  Container.ItemSetChangeNotifier))
0577:                    fireItemSetChange();
0578:                return retval;
0579:            }
0580:
0581:            /** Remove item identified by Id from the container.
0582:             * This functionality is optional. If the function is not implemented,
0583:             * the functions allways returns false.
0584:             *
0585:             * @return True iff the operation succeeded.
0586:             */
0587:            public boolean removeItem(Object itemId)
0588:                    throws UnsupportedOperationException {
0589:
0590:                unselect(itemId);
0591:                boolean retval = items.removeItem(itemId);
0592:                this .itemIdMapper.remove(itemId);
0593:                if (retval
0594:                        && !(items instanceof  Container.ItemSetChangeNotifier))
0595:                    fireItemSetChange();
0596:                return retval;
0597:            }
0598:
0599:            /** Remove property from all items.
0600:             * Removes a property with given id from all the items in the container.
0601:             *
0602:             * This functionality is optional. If the function is unsupported, it always
0603:             * returns false.
0604:             *
0605:             * @return True iff the operation succeeded.
0606:             */
0607:            public boolean removeContainerProperty(Object propertyId)
0608:                    throws UnsupportedOperationException {
0609:
0610:                boolean retval = items.removeContainerProperty(propertyId);
0611:                if (retval
0612:                        && !(items instanceof  Container.PropertySetChangeNotifier))
0613:                    firePropertySetChange();
0614:                return retval;
0615:            }
0616:
0617:            /* Container.Viewer methods ********************************************* */
0618:
0619:            /** Set the container as data-source for viewing.  */
0620:            public void setContainerDataSource(Container newDataSource) {
0621:                if (newDataSource == null)
0622:                    newDataSource = new IndexedContainer();
0623:
0624:                if (items != newDataSource) {
0625:
0626:                    // Remove listeners from the old datasource
0627:                    if (items != null) {
0628:                        try {
0629:                            ((Container.ItemSetChangeNotifier) items)
0630:                                    .removeListener((Container.ItemSetChangeListener) this );
0631:                        } catch (ClassCastException ignored) {
0632:                            // Ignored
0633:                        }
0634:                        try {
0635:                            ((Container.PropertySetChangeNotifier) items)
0636:                                    .removeListener((Container.PropertySetChangeListener) this );
0637:                        } catch (ClassCastException ignored) {
0638:                            // Ignored
0639:                        }
0640:                    }
0641:
0642:                    // Assign new data source
0643:                    items = newDataSource;
0644:
0645:                    // Clear itemIdMapper also
0646:                    this .itemIdMapper.removeAll();
0647:
0648:                    // Add listeners
0649:                    if (items != null) {
0650:                        try {
0651:                            ((Container.ItemSetChangeNotifier) items)
0652:                                    .addListener((Container.ItemSetChangeListener) this );
0653:                        } catch (ClassCastException ignored) {
0654:                            // Ignored
0655:                        }
0656:                        try {
0657:                            ((Container.PropertySetChangeNotifier) items)
0658:                                    .addListener((Container.PropertySetChangeListener) this );
0659:                        } catch (ClassCastException ignored) {
0660:                            // Ignored
0661:                        }
0662:                    }
0663:                    //TODO: This should be conditional
0664:                    fireValueChange();
0665:                }
0666:            }
0667:
0668:            /** Get viewing data-source container.  */
0669:            public Container getContainerDataSource() {
0670:                return items;
0671:            }
0672:
0673:            /* Select attributes **************************************************** */
0674:
0675:            /** Is the select in multiselect mode? In multiselect mode
0676:             * @return Value of property multiSelect.
0677:             */
0678:            public boolean isMultiSelect() {
0679:                return this .multiSelect;
0680:            }
0681:
0682:            /** Set the multiselect mode.
0683:             * Setting multiselect mode false may loose selection information: if
0684:             * selected items set contains one or more selected items, only one of the
0685:             * selected items is kept as selected.
0686:             *
0687:             * @param multiSelect New value of property multiSelect.
0688:             */
0689:            public void setMultiSelect(boolean multiSelect) {
0690:
0691:                if (multiSelect != this .multiSelect) {
0692:
0693:                    // Selection before mode change     
0694:                    Object oldValue = getValue();
0695:
0696:                    this .multiSelect = multiSelect;
0697:
0698:                    // Convert the value type
0699:                    if (multiSelect) {
0700:                        Set s = new HashSet();
0701:                        if (oldValue != null)
0702:                            s.add(oldValue);
0703:                        setValue(s);
0704:                    } else {
0705:                        Set s = (Set) oldValue;
0706:                        if (s == null || s.isEmpty())
0707:                            setValue(null);
0708:                        else
0709:
0710:                            // Set the single select to contain only the first 
0711:                            // selected value in the multiselect
0712:                            setValue(s.iterator().next());
0713:                    }
0714:
0715:                    requestRepaint();
0716:                }
0717:            }
0718:
0719:            /** Does the select allow adding new options by the user.
0720:             * If true, the new options can be added to the Container. The text entered
0721:             * by the user is used as id. No that data-source must allow adding new
0722:             * items (it must implement Container.Managed).
0723:             * @return True iff additions are allowed.
0724:             */
0725:            public boolean isNewItemsAllowed() {
0726:
0727:                return this .allowNewOptions;
0728:            }
0729:
0730:            /** Enable or disable possibility to add new options by the user.
0731:             * @param allowNewOptions New value of property allowNewOptions.
0732:             */
0733:            public void setNewItemsAllowed(boolean allowNewOptions) {
0734:
0735:                // Only handle change requests
0736:                if (this .allowNewOptions != allowNewOptions) {
0737:
0738:                    this .allowNewOptions = allowNewOptions;
0739:
0740:                    requestRepaint();
0741:                }
0742:            }
0743:
0744:            /** Override the caption of an item.
0745:             * Setting caption explicitly overrides id, item and index captions.
0746:             *
0747:             * @param itemId The id of the item to be recaptioned.
0748:             * @param caption New caption.
0749:             */
0750:            public void setItemCaption(Object itemId, String caption) {
0751:                if (itemId != null) {
0752:                    itemCaptions.put(itemId, caption);
0753:                    requestRepaint();
0754:                }
0755:            }
0756:
0757:            /** Get the caption of an item.
0758:             * The caption is generated as specified by the item caption mode. See
0759:             * <code>setItemCaptionMode()</code> for more details.
0760:             *
0761:             * @param itemId The id of the item to be queried.
0762:             * @return caption for specified item.
0763:             */
0764:            public String getItemCaption(Object itemId) {
0765:
0766:                // Null items can not be found
0767:                if (itemId == null)
0768:                    return null;
0769:
0770:                String caption = null;
0771:
0772:                switch (getItemCaptionMode()) {
0773:
0774:                case ITEM_CAPTION_MODE_ID:
0775:                    caption = itemId.toString();
0776:                    break;
0777:
0778:                case ITEM_CAPTION_MODE_INDEX:
0779:                    try {
0780:                        caption = String.valueOf(((Container.Indexed) items)
0781:                                .indexOfId(itemId));
0782:                    } catch (ClassCastException ignored) {
0783:                    }
0784:                    break;
0785:
0786:                case ITEM_CAPTION_MODE_ITEM:
0787:                    Item i = getItem(itemId);
0788:                    if (i != null)
0789:                        caption = i.toString();
0790:                    break;
0791:
0792:                case ITEM_CAPTION_MODE_EXPLICIT:
0793:                    caption = (String) itemCaptions.get(itemId);
0794:                    break;
0795:
0796:                case ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID:
0797:                    caption = (String) itemCaptions.get(itemId);
0798:                    if (caption == null)
0799:                        caption = itemId.toString();
0800:                    break;
0801:
0802:                case ITEM_CAPTION_MODE_PROPERTY:
0803:                    Property p = getContainerProperty(itemId,
0804:                            getItemCaptionPropertyId());
0805:                    if (p != null)
0806:                        caption = p.toString();
0807:                    break;
0808:                }
0809:
0810:                // All items must have some captions
0811:                return caption != null ? caption : "";
0812:            }
0813:
0814:            /** Set icon for an item.
0815:             *
0816:             * @param itemId The id of the item to be assigned an icon.
0817:             * @param icon New icon.
0818:             */
0819:            public void setItemIcon(Object itemId, Resource icon) {
0820:                if (itemId != null) {
0821:                    if (icon == null)
0822:                        itemIcons.remove(itemId);
0823:                    else
0824:                        itemIcons.put(itemId, icon);
0825:                    requestRepaint();
0826:                }
0827:            }
0828:
0829:            /** Get the item icon.
0830:             *
0831:             * @param itemId The id of the item to be assigned an icon.
0832:             * @return Icon for the item or null, if not specified.
0833:             */
0834:            public Resource getItemIcon(Object itemId) {
0835:                Resource explicit = (Resource) itemIcons.get(itemId);
0836:                if (explicit != null)
0837:                    return explicit;
0838:
0839:                if (getItemIconPropertyId() == null)
0840:                    return null;
0841:
0842:                Property ip = getContainerProperty(itemId,
0843:                        getItemIconPropertyId());
0844:                if (ip == null)
0845:                    return null;
0846:                Object icon = ip.getValue();
0847:                if (icon instanceof  Resource)
0848:                    return (Resource) icon;
0849:
0850:                return null;
0851:            }
0852:
0853:            /** Set the item caption mode.
0854:             *
0855:             * <p>The mode can be one of the following ones:
0856:             * <ul>
0857:             *  <li><code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> : Items
0858:             *      Id-objects <code>toString()</code> is used as item caption. If
0859:             *      caption is explicitly specified, it overrides the id-caption.
0860:             *  <li><code>ITEM_CAPTION_MODE_ID</code> : Items Id-objects
0861:             *      <code>toString()</code> is used as item caption.</li>
0862:             *   <li><code>ITEM_CAPTION_MODE_ITEM</code> : Item-objects
0863:             *      <code>toString()</code> is used as item caption.</li>
0864:             *   <li><code>ITEM_CAPTION_MODE_INDEX</code> : The index of the item is
0865:             *      used as item caption. The index mode can
0866:             *      only be used with the containers implementing
0867:             *      <code>Container.Indexed</code> interface.</li>
0868:             *   <li><code>ITEM_CAPTION_MODE_EXPLICIT</code> : The item captions
0869:             *       must be explicitly specified.</li>
0870:             *   <li><code>ITEM_CAPTION_MODE_PROPERTY</code> : The item captions
0871:             *       are read from property, that must be specified with 
0872:             *       <code>setItemCaptionPropertyId()</code>.</li>
0873:             * </ul>
0874:             * The <code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> is the default
0875:             * mode.
0876:             * </p>
0877:             *
0878:             * @param mode One of the modes listed above.
0879:             */
0880:            public void setItemCaptionMode(int mode) {
0881:                if (ITEM_CAPTION_MODE_ID <= mode
0882:                        && mode <= ITEM_CAPTION_MODE_PROPERTY) {
0883:                    itemCaptionMode = mode;
0884:                    requestRepaint();
0885:                }
0886:            }
0887:
0888:            /** Get the item caption mode.
0889:             *
0890:             * <p>The mode can be one of the following ones:
0891:             * <ul>
0892:             *  <li><code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> : Items
0893:             *      Id-objects <code>toString()</code> is used as item caption. If
0894:             *      caption is explicitly specified, it overrides the id-caption.
0895:             *  <li><code>ITEM_CAPTION_MODE_ID</code> : Items Id-objects
0896:             *      <code>toString()</code> is used as item caption.</li>
0897:             *   <li><code>ITEM_CAPTION_MODE_ITEM</code> : Item-objects
0898:             *      <code>toString()</code> is used as item caption.</li>
0899:             *   <li><code>ITEM_CAPTION_MODE_INDEX</code> : The index of the item is
0900:             *      used as item caption. The index mode can
0901:             *      only be used with the containers implementing
0902:             *      <code>Container.Indexed</code> interface.</li>
0903:             *   <li><code>ITEM_CAPTION_MODE_EXPLICIT</code> : The item captions
0904:             *       must be explicitly specified.</li>
0905:             *   <li><code>ITEM_CAPTION_MODE_PROPERTY</code> : The item captions
0906:             *       are read from property, that must be specified with 
0907:             *       <code>setItemCaptionPropertyId()</code>.</li>
0908:             * </ul>
0909:             * The <code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> is the default
0910:             * mode.
0911:             * </p>
0912:             *
0913:             * @return One of the modes listed above.
0914:             */
0915:            public int getItemCaptionMode() {
0916:                return itemCaptionMode;
0917:            }
0918:
0919:            /** Set the item caption property.
0920:             * 
0921:             * <p>Setting the id to a existing property implicitly sets 
0922:             * the item caption mode to <code>ITEM_CAPTION_MODE_PROPERTY</code>.
0923:             * If the object is in <code>ITEM_CAPTION_MODE_PROPERTY</code>
0924:             * mode, setting caption property id null resets the 
0925:             * item caption mode to <code>ITEM_CAPTION_EXPLICIT_DEFAULTS_ID</code>.</p>
0926:            
0927:             * <p>Setting the property id to null disables this feature. The 
0928:             * id is null by default</p>.
0929:             * 
0930:             */
0931:            public void setItemCaptionPropertyId(Object propertyId) {
0932:                if (propertyId != null) {
0933:                    itemCaptionPropertyId = propertyId;
0934:                    setItemCaptionMode(ITEM_CAPTION_MODE_PROPERTY);
0935:                    requestRepaint();
0936:                } else {
0937:                    itemCaptionPropertyId = null;
0938:                    if (getItemCaptionMode() == ITEM_CAPTION_MODE_PROPERTY)
0939:                        setItemCaptionMode(ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID);
0940:                    requestRepaint();
0941:                }
0942:            }
0943:
0944:            /** Get the item caption property.
0945:             * 
0946:             * @return Id of the property used as item caption source.
0947:             */
0948:            public Object getItemCaptionPropertyId() {
0949:                return itemCaptionPropertyId;
0950:            }
0951:
0952:            /** Set the item icon property.
0953:             * 
0954:             * <p>If the property id is set to a valid value, each item is given 
0955:             * an icon got from the given property of the items. The type
0956:             * of the property must be assignable to Icon.</p>
0957:             * 
0958:             * <p>Note that the icons set with <code>setItemIcon</code>
0959:             * function override the icons from the property.</p>
0960:             * 
0961:             * <p>Setting the property id to null disables this feature. The 
0962:             * id is null by default</p>.
0963:             * 
0964:             * @param propertyId Id of the property that specifies icons for
0965:             * items.
0966:             */
0967:            public void setItemIconPropertyId(Object propertyId) {
0968:                if ((propertyId != null)
0969:                        && Resource.class.isAssignableFrom(getType(propertyId))) {
0970:                    itemIconPropertyId = propertyId;
0971:                    requestRepaint();
0972:                } else
0973:                    itemIconPropertyId = null;
0974:            }
0975:
0976:            /** Get the item icon property.
0977:             * 
0978:             * <p>If the property id is set to a valid value, each item is given 
0979:             * an icon got from the given property of the items. The type
0980:             * of the property must be assignable to Icon.</p>
0981:             * 
0982:             * <p>Note that the icons set with <code>setItemIcon</code>
0983:             * function override the icons from the property.</p>
0984:             * 
0985:             * <p>Setting the property id to null disables this feature. The 
0986:             * id is null by default</p>.
0987:             * 
0988:             * @return Id of the property containing the item icons.
0989:             */
0990:            public Object getItemIconPropertyId() {
0991:                return itemIconPropertyId;
0992:            }
0993:
0994:            /** Test if an item is selected
0995:             * 
0996:             * <p>In single select mode testing selection status of the item identified
0997:             * by {@link #getNullSelectionItemId()} returns true if the value of the 
0998:             * property is null.</p>
0999:             * 
1000:             * @see #getNullSelectionItemId()
1001:             * @see #setNullSelectionItemId(Object)
1002:             * @param itemId Id the of the item to be tested
1003:             */
1004:            public boolean isSelected(Object itemId) {
1005:                if (itemId == null)
1006:                    return false;
1007:                if (isMultiSelect())
1008:                    return ((Set) getValue()).contains(itemId);
1009:                else {
1010:                    Object value = getValue();
1011:                    return itemId
1012:                            .equals(value == null ? getNullSelectionItemId()
1013:                                    : value);
1014:                }
1015:            }
1016:
1017:            /** Select an item.
1018:             * 
1019:             * <p>In single select mode selecting item identified
1020:             * by {@link #getNullSelectionItemId()} sets the value of the 
1021:             * property to null.</p>
1022:             * 
1023:             * @see #getNullSelectionItemId()
1024:             * @see #setNullSelectionItemId(Object)
1025:             * @param itemId Item to be selected.
1026:             */
1027:            public void select(Object itemId) {
1028:                if (!isSelected(itemId) && items.containsId(itemId)) {
1029:                    if (isMultiSelect()) {
1030:                        Set s = new HashSet((Set) getValue());
1031:                        s.add(itemId);
1032:                        setValue(s);
1033:                    } else if (itemId.equals(getNullSelectionItemId()))
1034:                        setValue(null);
1035:                    else
1036:                        setValue(itemId);
1037:                }
1038:            }
1039:
1040:            /** Unselect an item.
1041:             * 
1042:             * @see #getNullSelectionItemId()
1043:             * @see #setNullSelectionItemId(Object)
1044:             * @param itemId Item to be unselected.
1045:             */
1046:            public void unselect(Object itemId) {
1047:                if (isSelected(itemId)) {
1048:                    if (isMultiSelect()) {
1049:                        Set s = new HashSet((Set) getValue());
1050:                        s.remove(itemId);
1051:                        setValue(s);
1052:                    } else
1053:                        setValue(null);
1054:                }
1055:            }
1056:
1057:            /**
1058:             * @see org.millstone.base.data.Container.PropertySetChangeListener#containerPropertySetChange(org.millstone.base.data.Container.PropertySetChangeEvent)
1059:             */
1060:            public void containerPropertySetChange(
1061:                    Container.PropertySetChangeEvent event) {
1062:                firePropertySetChange();
1063:            }
1064:
1065:            /**
1066:             * @see org.millstone.base.data.Container.PropertySetChangeNotifier#addListener(org.millstone.base.data.Container.PropertySetChangeListener)
1067:             */
1068:            public void addListener(Container.PropertySetChangeListener listener) {
1069:                if (propertySetEventListeners == null)
1070:                    propertySetEventListeners = new LinkedList();
1071:                propertySetEventListeners.add(listener);
1072:            }
1073:
1074:            /**
1075:             * @see org.millstone.base.data.Container.PropertySetChangeNotifier#removeListener(org.millstone.base.data.Container.PropertySetChangeListener)
1076:             */
1077:            public void removeListener(
1078:                    Container.PropertySetChangeListener listener) {
1079:                if (propertySetEventListeners != null) {
1080:                    propertySetEventListeners.remove(listener);
1081:                    if (propertySetEventListeners.isEmpty())
1082:                        propertySetEventListeners = null;
1083:                }
1084:            }
1085:
1086:            /**
1087:             * @see org.millstone.base.data.Container.ItemSetChangeNotifier#addListener(org.millstone.base.data.Container.ItemSetChangeListener)
1088:             */
1089:            public void addListener(Container.ItemSetChangeListener listener) {
1090:                if (itemSetEventListeners == null)
1091:                    itemSetEventListeners = new LinkedList();
1092:                itemSetEventListeners.add(listener);
1093:            }
1094:
1095:            /**
1096:             * @see org.millstone.base.data.Container.ItemSetChangeNotifier#removeListener(org.millstone.base.data.Container.ItemSetChangeListener)
1097:             */
1098:            public void removeListener(Container.ItemSetChangeListener listener) {
1099:                if (itemSetEventListeners != null) {
1100:                    itemSetEventListeners.remove(listener);
1101:                    if (itemSetEventListeners.isEmpty())
1102:                        itemSetEventListeners = null;
1103:                }
1104:            }
1105:
1106:            /**
1107:             * @see org.millstone.base.data.Container.ItemSetChangeListener#containerItemSetChange(org.millstone.base.data.Container.ItemSetChangeEvent)
1108:             */
1109:            public void containerItemSetChange(
1110:                    Container.ItemSetChangeEvent event) {
1111:                // Clear item id mapping table
1112:                this .itemIdMapper.removeAll();
1113:
1114:                // Notify all listeners
1115:                fireItemSetChange();
1116:            }
1117:
1118:            /** Fire property set change event */
1119:            protected void firePropertySetChange() {
1120:                if (propertySetEventListeners != null
1121:                        && !propertySetEventListeners.isEmpty()) {
1122:                    Container.PropertySetChangeEvent event = new PropertySetChangeEvent();
1123:                    Object[] listeners = propertySetEventListeners.toArray();
1124:                    for (int i = 0; i < listeners.length; i++)
1125:                        ((Container.PropertySetChangeListener) listeners[i])
1126:                                .containerPropertySetChange(event);
1127:                }
1128:                requestRepaint();
1129:            }
1130:
1131:            /** Fire item set change event */
1132:            protected void fireItemSetChange() {
1133:                if (itemSetEventListeners != null
1134:                        && !itemSetEventListeners.isEmpty()) {
1135:                    Container.ItemSetChangeEvent event = new ItemSetChangeEvent();
1136:                    Object[] listeners = itemSetEventListeners.toArray();
1137:                    for (int i = 0; i < listeners.length; i++)
1138:                        ((Container.ItemSetChangeListener) listeners[i])
1139:                                .containerItemSetChange(event);
1140:                }
1141:                requestRepaint();
1142:            }
1143:
1144:            /** Implementation of item set change event */
1145:            private class ItemSetChangeEvent implements 
1146:                    Container.ItemSetChangeEvent {
1147:
1148:                /**
1149:                 * @see org.millstone.base.data.Container.ItemSetChangeEvent#getContainer()
1150:                 */
1151:                public Container getContainer() {
1152:                    return Select.this ;
1153:                }
1154:
1155:            }
1156:
1157:            /** Implementation of property set change event */
1158:            private class PropertySetChangeEvent implements 
1159:                    Container.PropertySetChangeEvent {
1160:
1161:                /**
1162:                 * @see org.millstone.base.data.Container.PropertySetChangeEvent#getContainer()
1163:                 */
1164:                public Container getContainer() {
1165:                    return Select.this ;
1166:                }
1167:
1168:            }
1169:
1170:            /** Returns the item id that represents null value of this select in single select mode.
1171:             * 
1172:             * <p>Data interface does not support nulls as item ids. Selecting the item idetified 
1173:             * by this id is the same as selecting no items at all. This setting only affects the
1174:             * single select mode.</p>
1175:            
1176:             * @return Object Null value item id.
1177:             * @see #setNullSelectionItemId(Object)
1178:             * @see #isSelected(Object)
1179:             * @see #select(Object)
1180:             */
1181:            public final Object getNullSelectionItemId() {
1182:                return nullSelectionItemId;
1183:            }
1184:
1185:            /** Sets the item id that represents null value of this select.
1186:             * 
1187:             * <p>Data interface does not support nulls as item ids. Selecting the item idetified 
1188:             * by this id is the same as selecting no items at all. This setting only affects the
1189:             * single select mode.</p>
1190:             *
1191:             * @param nullPropertyValueContainerItemId The nullPropertyValueContainerItemId to set
1192:             * @see #getNullSelectionItemId()
1193:             * @see #isSelected(Object)
1194:             * @see #select(Object)
1195:             */
1196:            public void setNullSelectionItemId(Object nullSelectionItemId) {
1197:                this.nullSelectionItemId = nullSelectionItemId;
1198:            }
1199:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.