Source Code Cross Referenced for Listbox.java in  » Ajax » zk » org » zkoss » zul » 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 » Ajax » zk » org.zkoss.zul 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Listbox.java
0002:
0003:        {{IS_NOTE
0004:        	Purpose:
0005:        		
0006:        	Description:
0007:        		
0008:        	History:
0009:        		Wed Jun 15 17:25:00     2005, Created by tomyeh
0010:        }}IS_NOTE
0011:
0012:        Copyright (C) 2005 Potix Corporation. All Rights Reserved.
0013:
0014:        {{IS_RIGHT
0015:        	This program is distributed under GPL Version 2.0 in the hope that
0016:        	it will be useful, but WITHOUT ANY WARRANTY.
0017:        }}IS_RIGHT
0018:         */
0019:        package org.zkoss.zul;
0020:
0021:        import java.util.List;
0022:        import java.util.AbstractSequentialList;
0023:        import java.util.LinkedList;
0024:        import java.util.ArrayList;
0025:        import java.util.Set;
0026:        import java.util.HashSet;
0027:        import java.util.LinkedHashSet;
0028:        import java.util.Iterator;
0029:        import java.util.ListIterator;
0030:        import java.util.Collection;
0031:        import java.util.Collections;
0032:        import java.util.AbstractCollection;
0033:        import java.util.NoSuchElementException;
0034:
0035:        import org.zkoss.lang.D;
0036:        import org.zkoss.lang.Classes;
0037:        import org.zkoss.lang.Objects;
0038:        import org.zkoss.lang.Strings;
0039:        import org.zkoss.lang.Exceptions;
0040:        import org.zkoss.util.logging.Log;
0041:        import org.zkoss.xml.HTMLs;
0042:
0043:        import org.zkoss.zk.ui.Page;
0044:        import org.zkoss.zk.ui.Component;
0045:        import org.zkoss.zk.ui.UiException;
0046:        import org.zkoss.zk.ui.WrongValueException;
0047:        import org.zkoss.zk.ui.ext.client.RenderOnDemand;
0048:        import org.zkoss.zk.ui.ext.client.Selectable;
0049:        import org.zkoss.zk.ui.ext.client.InnerWidth;
0050:        import org.zkoss.zk.ui.ext.render.Cropper;
0051:        import org.zkoss.zk.ui.event.Event;
0052:        import org.zkoss.zk.ui.event.EventListener;
0053:        import org.zkoss.zk.ui.event.Events;
0054:
0055:        import org.zkoss.zul.impl.XulElement;
0056:        import org.zkoss.zul.event.ListDataEvent;
0057:        import org.zkoss.zul.event.ListDataListener;
0058:        import org.zkoss.zul.ext.Paginal;
0059:        import org.zkoss.zul.event.ZulEvents;
0060:        import org.zkoss.zul.event.PagingEvent;
0061:
0062:        /**
0063:         * A listbox.
0064:         *
0065:         * <p>Event:
0066:         * <ol>
0067:         * <li>org.zkoss.zk.ui.event.SelectEvent is sent when user changes
0068:         * the selection.</li>
0069:         * </ol>
0070:         *
0071:         * <p>See <a href="package-summary.html">Specification</a>.</p>
0072:         *
0073:         * <p>Besides creating {@link Listitem} programmingly, you could assign
0074:         * a data model (a {@link ListModel} instance) to a listbox
0075:         * via {@link #setModel} and then
0076:         * the listbox will retrieve data via {@link ListModel#getElementAt} when
0077:         * necessary.
0078:         *
0079:         * <p>Besides assign a list model, you could assign a renderer
0080:         * (a {@link ListitemRenderer} instance) to a listbox, such that
0081:         * the listbox will use this
0082:         * renderer to render the data returned by {@link ListModel#getElementAt}.
0083:         * If not assigned, the default renderer, which assumes a label per
0084:         * list item, is used.
0085:         * In other words, the default renderer adds a label to
0086:         * a row by calling toString against the object returned
0087:         * by {@link ListModel#getElementAt}
0088:         * 
0089:         * <p>There are two ways to handle long content: scrolling and paging.
0090:         * If {@link #getMold} is "default", scrolling is used if {@link #setHeight}
0091:         * is called and too much content to display.
0092:         * If {@link #getMold} is "paging", paging is used if two or more pages are
0093:         * required. To control the number of items to display in a page, use
0094:         * {@link #setPageSize}.
0095:         *
0096:         * <p>If paging is used, the page controller is either created automatically
0097:         * or assigned explicity by {@link #setPaginal}.
0098:         * The paging controller specified explicitly by {@link #setPaginal} is called
0099:         * the external page controller. It is useful if you want to put the paging
0100:         * controller at different location (other than as a child component), or
0101:         * you want to use the same controller to control multiple listboxes.
0102:         *
0103:         * <p>Default {@link #getSclass}: listbox.
0104:         *
0105:         * <p>To have a list box without stripping, you can specify a non-existent
0106:         * style class to {@link #setOddRowSclass}.
0107:         * If you want to disable all striping, you can specify the style:
0108:         * <pre><code>
0109:         tr.odd {
0110:         background: white;
0111:         }
0112:         * </code></pre>
0113:         *
0114:         * @author tomyeh
0115:         * @see ListModel
0116:         * @see ListitemRenderer
0117:         * @see ListitemRendererExt
0118:         */
0119:        public class Listbox extends XulElement {
0120:            private static final Log log = Log.lookup(Listbox.class);
0121:
0122:            private transient List _items;
0123:            /** A list of selected items. */
0124:            private transient Set _selItems;
0125:            /** A readonly copy of {@link #_selItems}. */
0126:            private transient Set _roSelItems;
0127:            private int _maxlength;
0128:            private int _rows, _jsel = -1;
0129:            private transient Listhead _listhead;
0130:            private transient Listfoot _listfoot;
0131:            private ListModel _model;
0132:            private ListitemRenderer _renderer;
0133:            private transient ListDataListener _dataListener;
0134:            private transient Collection _heads;
0135:            private int _hdcnt;
0136:            private String _innerWidth = "100%";
0137:            /** The name. */
0138:            private String _name;
0139:            /** The paging controller, used only if mold = "paging". */
0140:            private transient Paginal _pgi;
0141:            /** The paging controller, used only if mold = "paging" and user
0142:             * doesn't assign a controller via {@link #setPaginal}.
0143:             * If exists, it is the last child
0144:             */
0145:            private transient Paging _paging;
0146:            private transient EventListener _pgListener, _pgImpListener;
0147:            /** The style class of the odd row. */
0148:            private String _scOddRow = "odd";
0149:            private int _tabindex = -1;
0150:            /** the # of rows to preload. */
0151:            private int _preloadsz = 7;
0152:            private boolean _multiple;
0153:            private boolean _disabled, _checkmark;
0154:            private boolean _vflex;
0155:            /** disable smartUpdate; usually caused by the client. */
0156:            private boolean _noSmartUpdate;
0157:
0158:            public Listbox() {
0159:                setSclass("listbox");
0160:                init();
0161:            }
0162:
0163:            private void init() {
0164:                _items = new AbstractSequentialList() {
0165:                    public ListIterator listIterator(int index) {
0166:                        return new ItemIter(index);
0167:                    }
0168:
0169:                    public Object get(int j) {
0170:                        final Object o = Listbox.this .getChildren().get(
0171:                                j + _hdcnt);
0172:                        if (!(o instanceof  Listitem))
0173:                            throw new IndexOutOfBoundsException("Wrong index: "
0174:                                    + j);
0175:                        return o;
0176:                    }
0177:
0178:                    public int size() {
0179:                        int sz = getChildren().size() - _hdcnt;
0180:                        if (_listfoot != null)
0181:                            --sz;
0182:                        if (_paging != null)
0183:                            --sz;
0184:                        return sz;
0185:                    }
0186:                };
0187:                _selItems = new LinkedHashSet(5);
0188:                _roSelItems = Collections.unmodifiableSet(_selItems);
0189:
0190:                _heads = new AbstractCollection() {
0191:                    public int size() {
0192:                        return _hdcnt;
0193:                    }
0194:
0195:                    public Iterator iterator() {
0196:                        return new Iter();
0197:                    }
0198:                };
0199:            }
0200:
0201:            /** Initializes _dataListener and register the listener to the model
0202:             */
0203:            private void initDataListener() {
0204:                if (_dataListener == null)
0205:                    _dataListener = new ListDataListener() {
0206:                        public void onChange(ListDataEvent event) {
0207:                            onListDataChange(event);
0208:                        }
0209:                    };
0210:
0211:                _model.addListDataListener(_dataListener);
0212:            }
0213:
0214:            /** Returns {@link Listhead} belonging to this listbox, or null
0215:             * if no list headers at all.
0216:             */
0217:            public Listhead getListhead() {
0218:                return _listhead;
0219:            }
0220:
0221:            /** Returns {@link Listfoot} belonging to this listbox, or null
0222:             * if no list footers at all.
0223:             */
0224:            public Listfoot getListfoot() {
0225:                return _listfoot;
0226:            }
0227:
0228:            /** Returns a collection of heads, including {@link #getListhead}
0229:             * and auxiliary heads ({@link Auxhead}) (never null).
0230:             *
0231:             * @since 3.0.0
0232:             */
0233:            public Collection getHeads() {
0234:                return _heads;
0235:            }
0236:
0237:            /** Returns whether the HTML's select tag is used.
0238:             */
0239:            /*package*/final boolean inSelectMold() {
0240:                return "select".equals(getMold());
0241:            }
0242:
0243:            /** Returns whether the check mark shall be displayed in front
0244:             * of each item.
0245:             * <p>Default: false.
0246:             */
0247:            public final boolean isCheckmark() {
0248:                return _checkmark;
0249:            }
0250:
0251:            /** Sets whether the check mark shall be displayed in front
0252:             * of each item.
0253:             * <p>The check mark is a checkbox if {@link #isMultiple} returns
0254:             * true. It is a radio button if {@link #isMultiple} returns false.
0255:             */
0256:            public void setCheckmark(boolean checkmark) {
0257:                if (_checkmark != checkmark) {
0258:                    _checkmark = checkmark;
0259:                    if (!inSelectMold())
0260:                        invalidate();
0261:                }
0262:            }
0263:
0264:            /**
0265:             * Sets the inner width of this component.
0266:             * The inner width is the width of the inner table.
0267:             * By default, it is 100%. That is, it is the same as the width
0268:             * of this component. However, it is changed when the user
0269:             * is sizing the column's width.
0270:             *
0271:             * <p>Application developers rarely call this method, unless
0272:             * they want to preserve the widths of sizable columns
0273:             * changed by the user.
0274:             * To preserve the widths, the developer have to store the widths of
0275:             * all columns and the inner width ({@link #getInnerWidth}),
0276:             * and then restore them when re-creating this component.
0277:             *
0278:             * @param innerWidth the inner width. If null, "100%" is assumed.
0279:             * @since 3.0.0
0280:             */
0281:            public void setInnerWidth(String innerWidth) {
0282:                if (innerWidth == null)
0283:                    innerWidth = "100%";
0284:                if (!_innerWidth.equals(innerWidth)) {
0285:                    _innerWidth = innerWidth;
0286:                    smartUpdate("z.innerWidth", innerWidth);
0287:                }
0288:            }
0289:
0290:            /**
0291:             * Returns the inner width of this component.
0292:             * The inner width is the width of the inner table.
0293:             * <p>Default: "100%"
0294:             * @see #setInnerWidth
0295:             * @since 3.0.0
0296:             */
0297:            public String getInnerWidth() {
0298:                return _innerWidth;
0299:            }
0300:
0301:            /** Returns whether to grow and shrink vertical to fit their given space,
0302:             * so called vertial flexibility.
0303:             *
0304:             * <p>Note: this attribute is ignored if {@link #setRows} is specified
0305:             *
0306:             * <p>Default: false.
0307:             */
0308:            public final boolean isVflex() {
0309:                return _vflex;
0310:            }
0311:
0312:            /** Sets whether to grow and shrink vertical to fit their given space,
0313:             * so called vertial flexibility.
0314:             *
0315:             * <p>Note: this attribute is ignored if {@link #setRows} is specified
0316:             */
0317:            public void setVflex(boolean vflex) {
0318:                if (_vflex != vflex) {
0319:                    _vflex = vflex;
0320:                    if (!inSelectMold())
0321:                        smartUpdate("z.flex", _vflex);
0322:                }
0323:            }
0324:
0325:            /** Returns whether it is disabled.
0326:             * <p>Default: false.
0327:             */
0328:            public final boolean isDisabled() {
0329:                return _disabled;
0330:            }
0331:
0332:            /** Sets whether it is disabled.
0333:             */
0334:            public void setDisabled(boolean disabled) {
0335:                if (_disabled != disabled) {
0336:                    _disabled = disabled;
0337:                    if (inSelectMold()) {
0338:                        smartUpdate("disabled", _disabled);
0339:                    } else {
0340:                        smartUpdate("z.disabled", _disabled);
0341:                    }
0342:                }
0343:            }
0344:
0345:            /** Returns the tab order of this component.
0346:             * <p>Currently, only the "select" mold supports this property.
0347:             * <p>Default: -1 (means the same as browser's default).
0348:             */
0349:            public int getTabindex() {
0350:                return _tabindex;
0351:            }
0352:
0353:            /** Sets the tab order of this component.
0354:             * <p>Currently, only the "select" mold supports this property.
0355:             */
0356:            public void setTabindex(int tabindex) throws WrongValueException {
0357:                if (_tabindex != tabindex) {
0358:                    _tabindex = tabindex;
0359:                    if (tabindex < 0)
0360:                        smartUpdate("tabindex", null);
0361:                    else
0362:                        smartUpdate("tabindex", Integer.toString(_tabindex));
0363:                }
0364:            }
0365:
0366:            /** Returns the rows. Zero means no limitation.
0367:             * <p>Default: 0.
0368:             */
0369:            public int getRows() {
0370:                return _rows;
0371:            }
0372:
0373:            /** Sets the rows.
0374:             * <p>Note: if both {@link #setHeight} is specified with non-empty,
0375:             * {@link #setRows} is ignored
0376:             */
0377:            public void setRows(int rows) throws WrongValueException {
0378:                if (rows < 0)
0379:                    throw new WrongValueException("Illegal rows: " + rows);
0380:
0381:                if (_rows != rows) {
0382:                    _rows = rows;
0383:
0384:                    if (inSelectMold()) {
0385:                        smartUpdate("size", _rows > 0 ? Integer.toString(_rows)
0386:                                : null);
0387:                    } else {
0388:                        smartUpdate("z.size", Integer.toString(_rows));
0389:                    }
0390:                }
0391:            }
0392:
0393:            /** Returns the seltype.
0394:             * <p>Default: "single".
0395:             */
0396:            public String getSeltype() {
0397:                return _multiple ? "multiple" : "single";
0398:            }
0399:
0400:            /** Sets the seltype.
0401:             */
0402:            public void setSeltype(String seltype) throws WrongValueException {
0403:                if ("single".equals(seltype))
0404:                    setMultiple(false);
0405:                else if ("multiple".equals(seltype))
0406:                    setMultiple(true);
0407:                else
0408:                    throw new WrongValueException("Unknown seltype: " + seltype);
0409:            }
0410:
0411:            /** Returns whether multiple selections are allowed.
0412:             * <p>Default: false.
0413:             */
0414:            public boolean isMultiple() {
0415:                return _multiple;
0416:            }
0417:
0418:            /** Sets whether multiple selections are allowed.
0419:             */
0420:            public void setMultiple(boolean multiple) {
0421:                if (_multiple != multiple) {
0422:                    _multiple = multiple;
0423:                    if (!_multiple && _selItems.size() > 1) {
0424:                        final Listitem item = getSelectedItem();
0425:                        for (Iterator it = _selItems.iterator(); it.hasNext();) {
0426:                            final Listitem li = (Listitem) it.next();
0427:                            if (li != item) {
0428:                                li.setSelectedDirectly(false);
0429:                                it.remove();
0430:                            }
0431:                        }
0432:                        //No need to update z.selId because z.multiple will do the job
0433:                    }
0434:
0435:                    if (inSelectMold())
0436:                        smartUpdate("multiple", _multiple);
0437:                    else if (isCheckmark())
0438:                        invalidate(); //change check mark
0439:                    else
0440:                        smartUpdate("z.multiple", _multiple);
0441:                    //No need to use response because such info is carried on tags
0442:                }
0443:            }
0444:
0445:            /** Returns the ID of the selected item (it is stored as the z.selId
0446:             * attribute of the listbox).
0447:             */
0448:            private String getSelectedId() {
0449:                final Listitem sel = getSelectedItem();
0450:                return sel != null ? sel.getUuid() : "zk_n_a";
0451:            }
0452:
0453:            /** Returns the maximal length of each item's label.
0454:             */
0455:            public int getMaxlength() {
0456:                return _maxlength;
0457:            }
0458:
0459:            /** Sets the maximal length of each item's label.
0460:             */
0461:            public void setMaxlength(int maxlength) {
0462:                if (maxlength < 0)
0463:                    maxlength = 0;
0464:                if (_maxlength != maxlength) {
0465:                    _maxlength = maxlength;
0466:                    if (inSelectMold()) //affects only the HTML-select listbox
0467:                        invalidate();
0468:                    //Both IE and Mozilla are buggy if we insert options by innerHTML
0469:                }
0470:            }
0471:
0472:            /** Returns the name of this component.
0473:             * <p>Default: null.
0474:             * <p>The name is used only to work with "legacy" Web application that
0475:             * handles user's request by servlets.
0476:             * It works only with HTTP/HTML-based browsers. It doesn't work
0477:             * with other kind of clients.
0478:             * <p>Don't use this method if your application is purely based
0479:             * on ZK's event-driven model.
0480:             */
0481:            public String getName() {
0482:                return _name;
0483:            }
0484:
0485:            /** Sets the name of this component.
0486:             * <p>The name is used only to work with "legacy" Web application that
0487:             * handles user's request by servlets.
0488:             * It works only with HTTP/HTML-based browsers. It doesn't work
0489:             * with other kind of clients.
0490:             * <p>Don't use this method if your application is purely based
0491:             * on ZK's event-driven model.
0492:             *
0493:             * @param name the name of this component.
0494:             */
0495:            public void setName(String name) {
0496:                if (name != null && name.length() == 0)
0497:                    name = null;
0498:                if (!Objects.equals(_name, name)) {
0499:                    _name = name;
0500:                    if (inSelectMold())
0501:                        smartUpdate("name", _name);
0502:                    else if (_name != null)
0503:                        smartUpdate("z.name", _name);
0504:                    else
0505:                        invalidate(); //1) generate _value; 2) add submit listener
0506:                }
0507:            }
0508:
0509:            /** Returns a live list of all {@link Listitem}.
0510:             * By live we mean you can add or remove them directly with
0511:             * the List interface. In other words, you could add or remove
0512:             * an item by manipulating the returned list directly.
0513:             */
0514:            public List getItems() {
0515:                return _items;
0516:            }
0517:
0518:            /** Returns the number of items.
0519:             */
0520:            public int getItemCount() {
0521:                return _items.size();
0522:            }
0523:
0524:            /** Returns the item at the specified index.
0525:             *
0526:             * <p>Note: if live data is used ({@link #getModel} is not null),
0527:             * the returned item might NOT be loaded yet.
0528:             * To ensure it is loaded, you have to invoke {@link #renderItem}.
0529:             */
0530:            public Listitem getItemAtIndex(int index) {
0531:                return (Listitem) _items.get(index);
0532:            }
0533:
0534:            /** Returns the index of the specified item, or -1 if not found.
0535:             */
0536:            public int getIndexOfItem(Listitem item) {
0537:                return item == null ? -1 : item.getIndex();
0538:            }
0539:
0540:            /** Returns the index of the selected item (-1 if no one is selected).
0541:             */
0542:            public int getSelectedIndex() {
0543:                return _jsel;
0544:            }
0545:
0546:            /** Deselects all of the currently selected items and selects
0547:             * the item with the given index.
0548:             */
0549:            public void setSelectedIndex(int jsel) {
0550:                if (jsel >= _items.size())
0551:                    throw new UiException("Out of bound: " + jsel
0552:                            + " while size=" + _items.size());
0553:
0554:                if (jsel < -1)
0555:                    jsel = -1;
0556:                if (jsel < 0) { //unselct all
0557:                    clearSelection();
0558:                } else if (jsel != _jsel || (_multiple && _selItems.size() > 1)) {
0559:                    for (Iterator it = _selItems.iterator(); it.hasNext();) {
0560:                        final Listitem item = (Listitem) it.next();
0561:                        item.setSelectedDirectly(false);
0562:                    }
0563:                    _selItems.clear();
0564:
0565:                    _jsel = jsel;
0566:                    final Listitem item = getItemAtIndex(_jsel);
0567:                    item.setSelectedDirectly(true);
0568:                    _selItems.add(item);
0569:                    if (inSelectMold())
0570:                        smartUpdate("selectedIndex", Integer.toString(_jsel));
0571:                    else
0572:                        smartUpdate("select", item.getUuid());
0573:                    //Bug 1734950: don't count on index (since it may change)
0574:                    //On the other hand, it is OK with select-mold since
0575:                    //it invalidates if items are added or removed
0576:                }
0577:            }
0578:
0579:            /**  Deselects all of the currently selected items and selects
0580:             * the given item.
0581:             * <p>It is the same as {@link #setSelectedItem}.
0582:             * @param item the item to select. If null, all items are deselected.
0583:             */
0584:            public void selectItem(Listitem item) {
0585:                if (item == null) {
0586:                    setSelectedIndex(-1);
0587:                } else {
0588:                    if (item.getParent() != this )
0589:                        throw new UiException("Not a child: " + item);
0590:                    if (_multiple || !item.isSelected())
0591:                        setSelectedIndex(item.getIndex());
0592:                }
0593:            }
0594:
0595:            /** Selects the given item, without deselecting any other items
0596:             * that are already selected..
0597:             */
0598:            public void addItemToSelection(Listitem item) {
0599:                if (item.getParent() != this )
0600:                    throw new UiException("Not a child: " + item);
0601:
0602:                if (!item.isSelected()) {
0603:                    if (!_multiple) {
0604:                        selectItem(item);
0605:                    } else {
0606:                        if (item.getIndex() < _jsel || _jsel < 0) {
0607:                            _jsel = item.getIndex();
0608:                            if (!inSelectMold())
0609:                                smartUpdate("z.selId", getSelectedId());
0610:                        }
0611:                        item.setSelectedDirectly(true);
0612:                        _selItems.add(item);
0613:                        if (inSelectMold()) {
0614:                            item.smartUpdate("selected", true);
0615:                        } else {
0616:                            smartUpdateSelection();
0617:                        }
0618:                    }
0619:                }
0620:            }
0621:
0622:            /**  Deselects the given item without deselecting other items.
0623:             */
0624:            public void removeItemFromSelection(Listitem item) {
0625:                if (item.getParent() != this )
0626:                    throw new UiException("Not a child: " + item);
0627:
0628:                if (item.isSelected()) {
0629:                    if (!_multiple) {
0630:                        clearSelection();
0631:                    } else {
0632:                        final int oldSel = _jsel;
0633:                        item.setSelectedDirectly(false);
0634:                        _selItems.remove(item);
0635:                        fixSelectedIndex(0);
0636:                        if (inSelectMold()) {
0637:                            item.smartUpdate("selected", false);
0638:                        } else {
0639:                            smartUpdateSelection();
0640:                            if (oldSel != _jsel)
0641:                                smartUpdate("z.selId", getSelectedId());
0642:                        }
0643:                    }
0644:                }
0645:            }
0646:
0647:            /** Note: we have to update all selection at once, since addItemToSelection
0648:             * and removeItemFromSelection might be called interchangeably.
0649:             */
0650:            private void smartUpdateSelection() {
0651:                final StringBuffer sb = new StringBuffer(80);
0652:                for (Iterator it = _selItems.iterator(); it.hasNext();) {
0653:                    if (sb.length() > 0)
0654:                        sb.append(',');
0655:                    sb.append(((Listitem) it.next()).getUuid());
0656:                }
0657:                smartUpdate("chgSel", sb.toString());
0658:            }
0659:
0660:            /** If the specified item is selected, it is deselected.
0661:             * If it is not selected, it is selected. Other items in the list box
0662:             * that are selected are not affected, and retain their selected state.
0663:             */
0664:            public void toggleItemSelection(Listitem item) {
0665:                if (item.isSelected())
0666:                    removeItemFromSelection(item);
0667:                else
0668:                    addItemToSelection(item);
0669:            }
0670:
0671:            /** Clears the selection.
0672:             */
0673:            public void clearSelection() {
0674:                if (!_selItems.isEmpty()) {
0675:                    for (Iterator it = _selItems.iterator(); it.hasNext();) {
0676:                        final Listitem item = (Listitem) it.next();
0677:                        item.setSelectedDirectly(false);
0678:                    }
0679:                    _selItems.clear();
0680:                    _jsel = -1;
0681:                    if (inSelectMold())
0682:                        smartUpdate("selectedIndex", "-1");
0683:                    else
0684:                        smartUpdate("select", "");
0685:                    //Bug 1734950: don't count on index (since it may change)
0686:                }
0687:            }
0688:
0689:            /** Selects all items.
0690:             */
0691:            public void selectAll() {
0692:                if (!_multiple)
0693:                    throw new UiException(
0694:                            "Appliable only to the multiple seltype: " + this );
0695:
0696:                if (_items.size() != _selItems.size()) {
0697:                    for (Iterator it = _items.iterator(); it.hasNext();) {
0698:                        final Listitem item = (Listitem) it.next();
0699:                        _selItems.add(item);
0700:                        item.setSelectedDirectly(true);
0701:                    }
0702:                    _jsel = _items.isEmpty() ? -1 : 0;
0703:                    smartUpdate("selectAll", "true");
0704:                }
0705:            }
0706:
0707:            /** Returns the selected item.
0708:             *
0709:             * <p>Note: if live data is used ({@link #getModel} is not null),
0710:             * the returned item might NOT be loaded yet.
0711:             * To ensure it is loaded, you have to invoke {@link #renderItem}.
0712:             */
0713:            public Listitem getSelectedItem() {
0714:                return _jsel >= 0 ? _jsel > 0 && _selItems.size() == 1 ? //optimize for performance
0715:                (Listitem) _selItems.iterator().next()
0716:                        : getItemAtIndex(_jsel) : null;
0717:            }
0718:
0719:            /**  Deselects all of the currently selected items and selects
0720:             * the given item.
0721:             * <p>It is the same as {@link #selectItem}.
0722:             */
0723:            public void setSelectedItem(Listitem item) {
0724:                selectItem(item);
0725:            }
0726:
0727:            /** Returns all selected items.
0728:             *
0729:             * <p>Note: if live data is used ({@link #getModel} is not null),
0730:             * the returned item might NOT be loaded yet.
0731:             * To ensure it is loaded, you have to invoke {@link #renderItem}.
0732:             */
0733:            public Set getSelectedItems() {
0734:                return _roSelItems;
0735:            }
0736:
0737:            /** Returns the number of items being selected.
0738:             */
0739:            public int getSelectedCount() {
0740:                return _selItems.size();
0741:            }
0742:
0743:            /** Appends an item.
0744:             *
0745:             * <p>Note: if live data is used ({@link #getModel} is not null),
0746:             * the returned item might NOT be loaded yet.
0747:             * To ensure it is loaded, you have to invoke {@link #renderItem}.
0748:             */
0749:            public Listitem appendItem(String label, String value) {
0750:                final Listitem item = new Listitem(label, value);
0751:                item.applyProperties();
0752:                item.setParent(this );
0753:                return item;
0754:            }
0755:
0756:            /**  Removes the child item in the list box at the given index.
0757:             *
0758:             * <p>Note: if live data is used ({@link #getModel} is not null),
0759:             * the returned item might NOT be loaded yet.
0760:             * To ensure it is loaded, you have to invoke {@link #renderItem}.
0761:             *
0762:             * @return the removed item.
0763:             */
0764:            public Listitem removeItemAt(int index) {
0765:                final Listitem item = getItemAtIndex(index);
0766:                removeChild(item);
0767:                return item;
0768:            }
0769:
0770:            //--Paging--//
0771:            /** Returns the paging controller, or null if not available.
0772:             * Note: the paging controller is used only if {@link #getMold} is "paging".
0773:             *
0774:             * <p>If mold is "paging", this method never returns null, because
0775:             * a child paging controller is created automcatically (if not specified
0776:             * by developers with {@link #setPaginal}).
0777:             *
0778:             * <p>If a paging controller is specified (either by {@link #setPaginal},
0779:             * or by {@link #setMold} with "paging"),
0780:             * the listbox will rely on the paging controller to handle long-content
0781:             * instead of scrolling.
0782:             */
0783:            public Paginal getPaginal() {
0784:                return _pgi;
0785:            }
0786:
0787:            /* Specifies the paging controller.
0788:             * Note: the paging controller is used only if {@link #getMold} is "paging".
0789:             *
0790:             * <p>It is OK, though without any effect, to specify a paging controller
0791:             * even if mold is not "paging".
0792:             *
0793:             * @param pgi the paging controller. If null and {@link #getMold} is "paging",
0794:             * a paging controller is created automatically as a child component
0795:             * (see {@link #getPaging}).
0796:             */
0797:            public void setPaginal(Paginal pgi) {
0798:                if (!Objects.equals(pgi, _pgi)) {
0799:                    final Paginal old = _pgi;
0800:                    _pgi = pgi;
0801:
0802:                    if (inPagingMold()) {
0803:                        if (old != null)
0804:                            removePagingListener(old);
0805:                        if (_pgi == null) {
0806:                            if (_paging != null)
0807:                                _pgi = _paging;
0808:                            else
0809:                                newInternalPaging();
0810:                        } else { //_pgi != null
0811:                            if (_pgi != _paging) {
0812:                                if (_paging != null)
0813:                                    _paging.detach();
0814:                                _pgi.setTotalSize(getItemCount());
0815:                                addPagingListener(_pgi);
0816:                            }
0817:                        }
0818:                    }
0819:                }
0820:            }
0821:
0822:            /** Creates the internal paging component.
0823:             */
0824:            private void newInternalPaging() {
0825:                assert D.OFF || inPagingMold() : "paging mold only";
0826:                assert D.OFF || (_paging == null && _pgi == null);
0827:
0828:                final Paging paging = new Paging();
0829:                paging.setAutohide(true);
0830:                paging.setDetailed(true);
0831:                paging.setTotalSize(getItemCount());
0832:                paging.setParent(this );
0833:                addPagingListener(_pgi);
0834:            }
0835:
0836:            /** Adds the event listener for the onPaging event. */
0837:            private void addPagingListener(Paginal pgi) {
0838:                if (_pgListener == null)
0839:                    _pgListener = new EventListener() {
0840:                        public void onEvent(Event event) {
0841:                            final PagingEvent evt = (PagingEvent) event;
0842:                            Events.postEvent(new PagingEvent(evt.getName(),
0843:                                    Listbox.this , evt.getPageable(), evt
0844:                                            .getActivePage()));
0845:                        }
0846:                    };
0847:                pgi.addEventListener(ZulEvents.ON_PAGING, _pgListener);
0848:
0849:                if (_pgImpListener == null)
0850:                    _pgImpListener = new EventListener() {
0851:                        public void onEvent(Event event) {
0852:                            if (_model != null && inPagingMold()) {
0853:                                final Renderer renderer = new Renderer();
0854:                                try {
0855:                                    final Paginal pgi = getPaginal();
0856:                                    int pgsz = pgi.getPageSize();
0857:                                    final int ofs = pgi.getActivePage() * pgsz;
0858:                                    for (final Iterator it = getItems()
0859:                                            .listIterator(ofs); --pgsz >= 0
0860:                                            && it.hasNext();)
0861:                                        renderer.render((Listitem) it.next());
0862:                                } catch (Throwable ex) {
0863:                                    renderer.doCatch(ex);
0864:                                } finally {
0865:                                    renderer.doFinally();
0866:                                }
0867:                            }
0868:                            invalidate();
0869:                        }
0870:                    };
0871:                pgi.addEventListener("onPagingImpl", _pgImpListener);
0872:            }
0873:
0874:            /** Removes the event listener for the onPaging event. */
0875:            private void removePagingListener(Paginal pgi) {
0876:                pgi.removeEventListener(ZulEvents.ON_PAGING, _pgListener);
0877:                pgi.removeEventListener("onPagingImpl", _pgImpListener);
0878:            }
0879:
0880:            /** Returns the child paging controller that is created automatically,
0881:             * or null if mold is not "paging", or the controller is specified externally
0882:             * by {@link #setPaginal}.
0883:             */
0884:            public Paging getPaging() {
0885:                return _paging;
0886:            }
0887:
0888:            /** Returns the page size, aka., the number items per page.
0889:             * @exception IllegalStateException if {@link #getPaginal} returns null,
0890:             * i.e., mold is not "paging" and no external controller is specified.
0891:             */
0892:            public int getPageSize() {
0893:                if (_pgi == null)
0894:                    throw new IllegalStateException(
0895:                            "Available only the paging mold");
0896:                return _pgi.getPageSize();
0897:            }
0898:
0899:            /** Sets the page size, aka., the number items per page.
0900:             * @exception IllegalStateException if {@link #getPaginal} returns null,
0901:             * i.e., mold is not "paging" and no external controller is specified.
0902:             */
0903:            public void setPageSize(int pgsz) {
0904:                if (_pgi == null)
0905:                    throw new IllegalStateException(
0906:                            "Available only the paging mold");
0907:                _pgi.setPageSize(pgsz);
0908:            }
0909:
0910:            /** Returns whether this listbox is in the paging mold.
0911:             */
0912:            /*package*/boolean inPagingMold() {
0913:                return "paging".equals(getMold());
0914:            }
0915:
0916:            /** Returns the index of the first visible child.
0917:             * <p>Used only for component development, not for application developers.
0918:             */
0919:            public int getVisibleBegin() {
0920:                if (!inPagingMold())
0921:                    return 0;
0922:                final Paginal pgi = getPaginal();
0923:                return pgi.getActivePage() * pgi.getPageSize();
0924:            }
0925:
0926:            /** Returns the index of the last visible child.
0927:             * <p>Used only for component development, not for application developers.
0928:             */
0929:            public int getVisibleEnd() {
0930:                if (!inPagingMold())
0931:                    return Integer.MAX_VALUE;
0932:                final Paginal pgi = getPaginal();
0933:                return (pgi.getActivePage() + 1) * pgi.getPageSize() - 1; //inclusive
0934:            }
0935:
0936:            /** Returns the style class for the odd rows.
0937:             * <p>Default: odd.
0938:             * @since 3.0.0
0939:             */
0940:            public String getOddRowSclass() {
0941:                return _scOddRow;
0942:            }
0943:
0944:            /** Sets the style class for the odd rows.
0945:             * If the style class doesn't exist, the striping effect disappears.
0946:             * You can provide different effects by providing the proper style
0947:             * classes.
0948:             * @since 3.0.0
0949:             */
0950:            public void setOddRowSclass(String scls) {
0951:                if (scls != null && scls.length() == 0)
0952:                    scls = null;
0953:                if (!Objects.equals(_scOddRow, scls)) {
0954:                    _scOddRow = scls;
0955:                    smartUpdate("z.scOddRow", scls);
0956:                }
0957:            }
0958:
0959:            //-- Component --//
0960:            public void smartUpdate(String attr, String value) {
0961:                if (!_noSmartUpdate)
0962:                    super .smartUpdate(attr, value);
0963:            }
0964:
0965:            public void onChildAdded(Component child) {
0966:                super .onChildAdded(child);
0967:                if (inSelectMold())
0968:                    invalidate();
0969:                //Both IE and Mozilla are buggy if we insert options by innerHTML
0970:                else if (inPagingMold() && (child instanceof  Listitem))
0971:                    _pgi.setTotalSize(getItemCount());
0972:            }
0973:
0974:            public void onChildRemoved(Component child) {
0975:                super .onChildRemoved(child);
0976:                if (inSelectMold())
0977:                    invalidate();
0978:                //Both IE and Mozilla are buggy if we remove options by outerHTML
0979:                //CONSIDER: use special command to remove items
0980:                //Cons: if user remove a lot of items it is slower
0981:                else if (inPagingMold() && (child instanceof  Listitem))
0982:                    _pgi.setTotalSize(getItemCount());
0983:            }
0984:
0985:            public boolean insertBefore(Component newChild, Component refChild) {
0986:                if (newChild instanceof  Listitem) {
0987:                    //first: listhead or auxhead
0988:                    //last two: listfoot and paging
0989:                    if (refChild != null && refChild.getParent() != this )
0990:                        refChild = null; //Bug 1649625: it becomes the last child
0991:                    if (refChild != null
0992:                            && (refChild == _listhead || refChild instanceof  Auxhead))
0993:                        refChild = getChildren().size() > _hdcnt ? (Component) getChildren()
0994:                                .get(_hdcnt)
0995:                                : null;
0996:
0997:                    refChild = fixRefChildBeforeFoot(refChild);
0998:                    final Listitem newItem = (Listitem) newChild;
0999:                    final int jfrom = newItem.getParent() == this  ? newItem
1000:                            .getIndex() : -1;
1001:
1002:                    if (super .insertBefore(newChild, refChild)) {
1003:                        /**	final List children = getChildren(); //Feature #1830886
1004:                        if (_hdcnt > 0 && children.get(_hdcnt) == newChild)
1005:                        	invalidate();*/
1006:                        //we place listhead/auxhead and treeitem at different div, so
1007:                        //this case requires invalidate (because we use insert-after)
1008:                        //Maintain _items
1009:                        final int jto = refChild instanceof  Listitem ? ((Listitem) refChild)
1010:                                .getIndex()
1011:                                : -1, fixFrom = jfrom < 0
1012:                                || (jto >= 0 && jfrom > jto) ? jto : jfrom;
1013:                        //jfrom < 0: use jto
1014:                        //jto < 0: use jfrom
1015:                        //otherwise: use min(jfrom, jto)
1016:                        if (fixFrom < 0)
1017:                            newItem.setIndexDirectly(_items.size() - 1);
1018:                        else
1019:                            fixItemIndices(fixFrom);
1020:
1021:                        //Maintain selected
1022:                        final int newIndex = newItem.getIndex();
1023:                        if (newItem.isSelected()) {
1024:                            if (_jsel < 0) {
1025:                                _jsel = newIndex;
1026:                                if (!inSelectMold())
1027:                                    smartUpdate("z.selId", getSelectedId());
1028:                                _selItems.add(newItem);
1029:                            } else if (_multiple) {
1030:                                if (_jsel > newIndex) {
1031:                                    _jsel = newIndex;
1032:                                    if (!inSelectMold())
1033:                                        smartUpdate("z.selId", getSelectedId());
1034:                                }
1035:                                _selItems.add(newItem);
1036:                            } else { //deselect
1037:                                newItem.setSelectedDirectly(false);
1038:                            }
1039:                        } else {
1040:                            final int oldjsel = _jsel;
1041:                            if (jfrom < 0) { //no existent child
1042:                                if (_jsel >= newIndex)
1043:                                    ++_jsel;
1044:                            } else if (_jsel >= 0) { //any selected
1045:                                if (jfrom > _jsel) { //from below
1046:                                    if (jto >= 0 && jto <= _jsel)
1047:                                        ++_jsel;
1048:                                } else { //from above
1049:                                    if (jto < 0 || jto > _jsel)
1050:                                        --_jsel;
1051:                                }
1052:                            }
1053:
1054:                            if (oldjsel != _jsel && !inSelectMold())
1055:                                smartUpdate("z.selId", getSelectedId());
1056:                        }
1057:                        return true;
1058:                    }
1059:                    return false;
1060:                } else if (newChild instanceof  Listhead) {
1061:                    if (_listhead != null && _listhead != newChild)
1062:                        throw new UiException("Only one listhead is allowed: "
1063:                                + this );
1064:
1065:                    final boolean added = _listhead == null;
1066:                    refChild = fixRefChildForHeader(refChild);
1067:                    _listhead = (Listhead) newChild;
1068:                    if (super .insertBefore(newChild, refChild)) {
1069:                        if (added)
1070:                            ++_hdcnt; //it may be moved, not inserted
1071:                        invalidate(); //required since it might be the first child
1072:                        return true;
1073:                    }
1074:                    return false;
1075:                } else if (newChild instanceof  Auxhead) {
1076:                    final boolean added = newChild.getParent() != this ;
1077:                    refChild = fixRefChildForHeader(refChild);
1078:                    if (super .insertBefore(newChild, refChild)) {
1079:                        if (added)
1080:                            ++_hdcnt; //it may be moved, not inserted
1081:                        //not need to invalidate since auxhead visible only
1082:                        //with _listhead
1083:                        return true;
1084:                    }
1085:                    return false;
1086:                } else if (newChild instanceof  Listfoot) {
1087:                    if (_listfoot != null && _listfoot != newChild)
1088:                        throw new UiException("Only one listfoot is allowed: "
1089:                                + this );
1090:
1091:                    if (inSelectMold())
1092:                        log.warning("Mold select ignores listfoot");
1093:                    invalidate();
1094:                    //we place listfoot and treeitem at different div, so...
1095:                    _listfoot = (Listfoot) newChild;
1096:                    refChild = _paging; //the last two: listfoot and paging
1097:                    return super .insertBefore(newChild, refChild);
1098:                } else if (newChild instanceof  Paging) {
1099:                    if (_paging != null && _paging != newChild)
1100:                        throw new UiException("Only one paging is allowed: "
1101:                                + this );
1102:                    if (_pgi != null)
1103:                        throw new UiException(
1104:                                "External paging cannot coexist with child paging");
1105:                    if (!inPagingMold())
1106:                        throw new UiException(
1107:                                "The child paging is allowed only in the paging mold");
1108:
1109:                    invalidate();
1110:                    _pgi = _paging = (Paging) newChild;
1111:                    refChild = null; //the last: paging
1112:                    return super .insertBefore(newChild, refChild);
1113:                } else {
1114:                    throw new UiException("Unsupported child for Listbox: "
1115:                            + newChild);
1116:                }
1117:            }
1118:
1119:            private Component fixRefChildForHeader(Component refChild) {
1120:                if (refChild != null && refChild.getParent() != this )
1121:                    refChild = null;
1122:
1123:                //try the first listitem
1124:                if (refChild == null
1125:                        || (refChild != _listhead && !(refChild instanceof  Auxhead)))
1126:                    refChild = getChildren().size() > _hdcnt ? (Component) getChildren()
1127:                            .get(_hdcnt)
1128:                            : null;
1129:
1130:                //try listfoot or paging if no listem
1131:                refChild = fixRefChildBeforeFoot(refChild);
1132:                return refChild;
1133:            }
1134:
1135:            private Component fixRefChildBeforeFoot(Component refChild) {
1136:                if (refChild == null) {
1137:                    if (_listfoot != null)
1138:                        refChild = _listfoot;
1139:                    else
1140:                        refChild = _paging;
1141:                } else if (refChild == _paging && _listfoot != null) {
1142:                    refChild = _listfoot;
1143:                }
1144:                return refChild;
1145:            }
1146:
1147:            public boolean removeChild(Component child) {
1148:                if (!super .removeChild(child))
1149:                    return false;
1150:
1151:                if (_listhead == child) {
1152:                    _listhead = null;
1153:                    --_hdcnt;
1154:                } else if (_listfoot == child) {
1155:                    _listfoot = null;
1156:                } else if (child instanceof  Listitem) {
1157:                    //maintain items
1158:                    final Listitem item = (Listitem) child;
1159:                    final int index = item.getIndex();
1160:                    item.setIndexDirectly(-1); //mark
1161:                    fixItemIndices(index);
1162:
1163:                    //Maintain selected
1164:                    if (item.isSelected()) {
1165:                        _selItems.remove(item);
1166:                        if (_jsel == index) {
1167:                            fixSelectedIndex(index);
1168:                            if (!inSelectMold())
1169:                                smartUpdate("z.selId", getSelectedId());
1170:                        }
1171:                    } else {
1172:                        if (_jsel >= index) {
1173:                            --_jsel;
1174:                            if (!inSelectMold())
1175:                                smartUpdate("z.selId", getSelectedId());
1176:                        }
1177:                    }
1178:                    return true;
1179:                } else if (_paging == child) {
1180:                    _paging = null;
1181:                    if (_pgi == child)
1182:                        _pgi = null;
1183:                } else if (child instanceof  Auxhead) {
1184:                    --_hdcnt;
1185:                }
1186:                invalidate();
1187:                return true;
1188:            }
1189:
1190:            /** Fix the selected index, _jsel, assuming there are no selected one
1191:             * before (and excludes) j-the item.
1192:             */
1193:            private void fixSelectedIndex(int j) {
1194:                if (!_selItems.isEmpty()) {
1195:                    for (Iterator it = _items.listIterator(j); it.hasNext(); ++j) {
1196:                        final Listitem item = (Listitem) it.next();
1197:                        if (item.isSelected()) {
1198:                            _jsel = j;
1199:                            return;
1200:                        }
1201:                    }
1202:                }
1203:                _jsel = -1;
1204:            }
1205:
1206:            /** Fix Childitem._index since j-th item. */
1207:            private void fixItemIndices(int j) {
1208:                for (Iterator it = _items.listIterator(j); it.hasNext(); ++j)
1209:                    ((Listitem) it.next()).setIndexDirectly(j);
1210:            }
1211:
1212:            //-- ListModel dependent codes --//
1213:            /** Returns the list model associated with this listbox, or null
1214:             * if this listbox is not associated with any list data model.
1215:             */
1216:            public ListModel getModel() {
1217:                return _model;
1218:            }
1219:
1220:            /** Sets the list model associated with this listbox.
1221:             * If a non-null model is assigned, no matter whether it is the same as
1222:             * the previous, it will always cause re-render.
1223:             *
1224:             * @param model the list model to associate, or null to dis-associate
1225:             * any previous model.
1226:             * @exception UiException if failed to initialize with the model
1227:             */
1228:            public void setModel(ListModel model) {
1229:                if (model != null) {
1230:                    if (_model != model) {
1231:                        if (_model != null) {
1232:                            _model.removeListDataListener(_dataListener);
1233:                        } else {
1234:                            getItems().clear(); //Bug 1807414
1235:                            if (!inSelectMold())
1236:                                smartUpdate("z.model", "true");
1237:                        }
1238:
1239:                        _model = model;
1240:                        initDataListener();
1241:                    }
1242:
1243:                    //Always syncModel because it is easier for user to enfore reload
1244:                    syncModel(-1, -1);
1245:                    postOnInitRender();
1246:                    //Since user might setModel and setRender separately or repeatedly,
1247:                    //we don't handle it right now until the event processing phase
1248:                    //such that we won't render the same set of data twice
1249:                    //--
1250:                    //For better performance, we shall load the first few row now
1251:                    //(to save a roundtrip)
1252:                } else if (_model != null) {
1253:                    _model.removeListDataListener(_dataListener);
1254:                    _model = null;
1255:                    getItems().clear();
1256:                    if (!inSelectMold())
1257:                        smartUpdate("z.model", null);
1258:                }
1259:            }
1260:
1261:            /** Returns the renderer to render each item, or null if the default
1262:             * renderer is used.
1263:             */
1264:            public ListitemRenderer getItemRenderer() {
1265:                return _renderer;
1266:            }
1267:
1268:            /** Sets the renderer which is used to render each item
1269:             * if {@link #getModel} is not null.
1270:             *
1271:             * <p>Note: changing a render will not cause the listbox to re-render.
1272:             * If you want it to re-render, you could assign the same model again 
1273:             * (i.e., setModel(getModel())), or fire an {@link ListDataEvent} event.
1274:             *
1275:             * @param renderer the renderer, or null to use the default.
1276:             * @exception UiException if failed to initialize with the model
1277:             */
1278:            public void setItemRenderer(ListitemRenderer renderer) {
1279:                _renderer = renderer;
1280:            }
1281:
1282:            /** Sets the renderer by use of a class name.
1283:             * It creates an instance automatically.
1284:             */
1285:            public void setItemRenderer(String clsnm)
1286:                    throws ClassNotFoundException, NoSuchMethodException,
1287:                    IllegalAccessException, InstantiationException,
1288:                    java.lang.reflect.InvocationTargetException {
1289:                if (clsnm != null)
1290:                    setItemRenderer((ListitemRenderer) Classes
1291:                            .newInstanceByThread(clsnm));
1292:            }
1293:
1294:            /** Returns the number of items to preload when receiving
1295:             * the rendering request from the client.
1296:             *
1297:             * <p>Default: 7.
1298:             *
1299:             * <p>It is used only if live data ({@link #setModel} and
1300:             * not paging ({@link #getPaging}.
1301:             *
1302:             * @since 2.4.1
1303:             */
1304:            public int getPreloadSize() {
1305:                return _preloadsz;
1306:            }
1307:
1308:            /** Sets the number of items to preload when receiving
1309:             * the rendering request from the client.
1310:             * <p>It is used only if live data ({@link #setModel} and
1311:             * not paging ({@link #getPaging}.
1312:             *
1313:             * @param sz the number of items to preload. If zero, no preload
1314:             * at all.
1315:             * @exception UiException if sz is negative
1316:             * @since 2.4.1
1317:             */
1318:            public void setPreloadSize(int sz) {
1319:                if (sz < 0)
1320:                    throw new UiException("nonnegative is required: " + sz);
1321:                _preloadsz = sz;
1322:            }
1323:
1324:            /** Synchronizes the listbox to be consistent with the specified model.
1325:             * @param min the lower index that a range of invalidated items
1326:             * @param max the higher index that a range of invalidated items
1327:             */
1328:            private void syncModel(int min, int max) {
1329:                ListitemRenderer renderer = null;
1330:                final int newsz = _model.getSize();
1331:                final int oldsz = getItemCount();
1332:                if (oldsz > 0) {
1333:                    if (newsz > 0 && min < oldsz) {
1334:                        if (max < 0 || max >= oldsz)
1335:                            max = oldsz - 1;
1336:                        if (max >= newsz)
1337:                            max = newsz - 1;
1338:                        if (min < 0)
1339:                            min = 0;
1340:
1341:                        //unloadItem() might detach item and add new item, _items must make a copy first
1342:                        for (Iterator it = new ArrayList(_items)
1343:                                .listIterator(min); min <= max && it.hasNext(); ++min) {
1344:                            final Listitem item = (Listitem) it.next();
1345:                            if (item.isLoaded()) {
1346:                                if (renderer == null)
1347:                                    renderer = getRealRenderer();
1348:                                unloadItem(renderer, item);
1349:                            }
1350:                        }
1351:                    }
1352:
1353:                    for (int j = newsz; j < oldsz; ++j)
1354:                        getItemAtIndex(newsz).detach(); //detach and remove
1355:                }
1356:
1357:                for (int j = oldsz; j < newsz; ++j) {
1358:                    if (renderer == null)
1359:                        renderer = getRealRenderer();
1360:                    newUnloadedItem(renderer).setParent(this );
1361:                }
1362:            }
1363:
1364:            /** Creates an new and unloaded listitem. */
1365:            private final Listitem newUnloadedItem(ListitemRenderer renderer) {
1366:                Listitem item = null;
1367:                if (renderer instanceof  ListitemRendererExt)
1368:                    item = ((ListitemRendererExt) renderer).newListitem(this );
1369:
1370:                if (item == null) {
1371:                    item = new Listitem();
1372:                    item.applyProperties();
1373:                }
1374:                item.setLoaded(false);
1375:
1376:                newUnloadedCell(renderer, item);
1377:                return item;
1378:            }
1379:
1380:            private Listcell newUnloadedCell(ListitemRenderer renderer,
1381:                    Listitem item) {
1382:                Listcell cell = null;
1383:                if (renderer instanceof  ListitemRendererExt)
1384:                    cell = ((ListitemRendererExt) renderer).newListcell(item);
1385:
1386:                if (cell == null) {
1387:                    cell = new Listcell();
1388:                    cell.applyProperties();
1389:                }
1390:                cell.setParent(item);
1391:                return cell;
1392:            }
1393:
1394:            /** Clears a listitem as if it is not loaded. */
1395:            private final void unloadItem(ListitemRenderer renderer,
1396:                    Listitem item) {
1397:                if (!(renderer instanceof  ListitemRendererExt)
1398:                        || (((ListitemRendererExt) renderer).getControls() & ListitemRendererExt.DETACH_ON_UNLOAD) == 0) { //re-use (default)
1399:                    final List cells = item.getChildren();
1400:                    if (cells.isEmpty()) {
1401:                        newUnloadedCell(renderer, item);
1402:                    } else {
1403:                        //detach and remove all but the first cell
1404:                        for (Iterator it = cells.listIterator(1); it.hasNext();) {
1405:                            it.next();
1406:                            it.remove();
1407:                        }
1408:
1409:                        final Listcell listcell = (Listcell) cells.get(0);
1410:                        listcell.getChildren().clear(); //another renderer might do diff
1411:                        listcell.setLabel(null);
1412:                        listcell.setImage(null);
1413:                    }
1414:                    item.setLoaded(false);
1415:                } else { //detach
1416:                    item.getParent().insertBefore(newUnloadedItem(renderer),
1417:                            item);
1418:                    item.detach();
1419:                }
1420:            }
1421:
1422:            /** Handles a private event, onInitRender. It is used only for
1423:             * implementation, and you rarely need to invoke it explicitly.
1424:             */
1425:            public void onInitRender() {
1426:                final Renderer renderer = new Renderer();
1427:                try {
1428:                    int pgsz, ofs;
1429:                    if (inPagingMold()) {
1430:                        pgsz = _pgi.getPageSize();
1431:                        ofs = _pgi.getActivePage() * pgsz;
1432:                        final int cnt = getItemCount();
1433:                        if (ofs >= cnt) { //not possible; just in case
1434:                            ofs = cnt - pgsz;
1435:                            if (ofs < 0)
1436:                                ofs = 0;
1437:                        }
1438:                    } else {
1439:                        pgsz = inSelectMold() ? getItemCount()
1440:                                : _rows > 0 ? _rows + 5 : 20;
1441:                        ofs = 0;
1442:                        //we don't know # of visible rows, so a 'smart' guess
1443:                        //It is OK since client will send back request if not enough
1444:                    }
1445:
1446:                    int j = 0;
1447:                    for (Iterator it = getItems().listIterator(ofs); j < pgsz
1448:                            && it.hasNext(); ++j)
1449:                        renderer.render((Listitem) it.next());
1450:                    if (!inPagingMold() && getItemCount() > pgsz)
1451:                        getItemAtIndex(pgsz).setAttribute(
1452:                                Attributes.SKIP_SIBLING, Boolean.TRUE);
1453:                } catch (Throwable ex) {
1454:                    renderer.doCatch(ex);
1455:                } finally {
1456:                    renderer.doFinally();
1457:                }
1458:            }
1459:
1460:            private void postOnInitRender() {
1461:                Events.postEvent("onInitRender", this , null);
1462:                smartUpdate("z.render", true);
1463:            }
1464:
1465:            /** Handles when the list model's content changed.
1466:             */
1467:            private void onListDataChange(ListDataEvent event) {
1468:                if (inSelectMold()) {
1469:                    invalidate();
1470:                    syncModel(-1, -1);
1471:                    postOnInitRender();
1472:                    return;
1473:                }
1474:
1475:                //when this is called _model is never null
1476:                final int newsz = _model.getSize(), oldsz = getItemCount();
1477:                int min = event.getIndex0(), max = event.getIndex1();
1478:                if (min < 0)
1479:                    min = 0;
1480:
1481:                boolean done = false;
1482:                switch (event.getType()) {
1483:                case ListDataEvent.INTERVAL_ADDED:
1484:                    if (max < 0)
1485:                        max = newsz - 1;
1486:                    if ((max - min + 1) != (newsz - oldsz)) {
1487:                        log
1488:                                .warning("Conflict event: number of added items not matched: "
1489:                                        + event);
1490:                        break; //handle it as CONTENTS_CHANGED
1491:                    }
1492:
1493:                    ListitemRenderer renderer = null;
1494:                    final Listitem before = min < oldsz ? getItemAtIndex(min)
1495:                            : null;
1496:                    for (int j = min; j <= max; ++j) {
1497:                        if (renderer == null)
1498:                            renderer = getRealRenderer();
1499:                        insertBefore(newUnloadedItem(renderer), before);
1500:                    }
1501:                    done = true;
1502:                    break;
1503:
1504:                case ListDataEvent.INTERVAL_REMOVED:
1505:                    if (max < 0)
1506:                        max = oldsz - 1;
1507:                    int cnt = max - min + 1;
1508:                    if (cnt != (oldsz - newsz)) {
1509:                        log
1510:                                .warning("Conflict event: number of removed items not matched: "
1511:                                        + event);
1512:                        break; //handle it as CONTENTS_CHANGED
1513:                    }
1514:
1515:                    //detach and remove
1516:                    for (Iterator it = getItems().listIterator(min); --cnt >= 0
1517:                            && it.hasNext();) {
1518:                        it.next();
1519:                        it.remove();
1520:                    }
1521:
1522:                    done = true;
1523:                    break;
1524:                }
1525:
1526:                if (!done) //CONTENTS_CHANGED
1527:                    syncModel(min, max);
1528:
1529:                postOnInitRender();
1530:                //Bug 1823236: though fixed in JS, it improves performance
1531:                //to save one roundtrip
1532:            }
1533:
1534:            private static final ListitemRenderer getDefaultItemRenderer() {
1535:                return _defRend;
1536:            }
1537:
1538:            private static final ListitemRenderer _defRend = new ListitemRenderer() {
1539:                public void render(Listitem item, Object data) {
1540:                    item.setLabel(Objects.toString(data));
1541:                    item.setValue(data);
1542:                }
1543:            };
1544:
1545:            /** Returns the renderer used to render items.
1546:             */
1547:            private ListitemRenderer getRealRenderer() {
1548:                return _renderer != null ? _renderer : getDefaultItemRenderer();
1549:            }
1550:
1551:            /** Used to render listitem if _model is specified. */
1552:            private class Renderer implements  java.io.Serializable {
1553:                private final ListitemRenderer _renderer;
1554:                private boolean _rendered, _ctrled;
1555:
1556:                private Renderer() {
1557:                    _renderer = getRealRenderer();
1558:                }
1559:
1560:                private void render(Listitem item) throws Throwable {
1561:                    if (item.isLoaded())
1562:                        return; //nothing to do
1563:
1564:                    if (!_rendered && (_renderer instanceof  RendererCtrl)) {
1565:                        ((RendererCtrl) _renderer).doTry();
1566:                        _ctrled = true;
1567:                    }
1568:
1569:                    final Listcell cell = (Listcell) item.getFirstChild();
1570:                    if (!(_renderer instanceof  ListitemRendererExt)
1571:                            || (((ListitemRendererExt) _renderer).getControls() & ListitemRendererExt.DETACH_ON_RENDER) != 0) { //detach (default)
1572:                        cell.detach();
1573:                    }
1574:
1575:                    try {
1576:                        _renderer.render(item, _model.getElementAt(item
1577:                                .getIndex()));
1578:                    } catch (Throwable ex) {
1579:                        try {
1580:                            item.setLabel(Exceptions.getMessage(ex));
1581:                        } catch (Throwable t) {
1582:                            log.error(t);
1583:                        }
1584:                        item.setLoaded(true);
1585:                        throw ex;
1586:                    } finally {
1587:                        if (item.getChildren().isEmpty())
1588:                            cell.setParent(item);
1589:                    }
1590:
1591:                    item.setLoaded(true);
1592:                    _rendered = true;
1593:                }
1594:
1595:                private void doCatch(Throwable ex) {
1596:                    if (_ctrled) {
1597:                        try {
1598:                            ((RendererCtrl) _renderer).doCatch(ex);
1599:                        } catch (Throwable t) {
1600:                            throw UiException.Aide.wrap(t);
1601:                        }
1602:                    } else {
1603:                        throw UiException.Aide.wrap(ex);
1604:                    }
1605:                }
1606:
1607:                private void doFinally() {
1608:                    if (_ctrled)
1609:                        ((RendererCtrl) _renderer).doFinally();
1610:                }
1611:            }
1612:
1613:            /** Renders the specified {@link Listitem} if not loaded yet,
1614:             * with {@link #getItemRenderer}.
1615:             *
1616:             * <p>It does nothing if {@link #getModel} returns null.
1617:             * In other words, it is meaningful only if live data model is used.
1618:             *
1619:             * @see #renderItems
1620:             * @see #renderAll
1621:             * @return the list item being passed to this method
1622:             */
1623:            public Listitem renderItem(Listitem li) {
1624:                if (_model != null && !li.isLoaded()) {
1625:                    final Renderer renderer = new Renderer();
1626:                    try {
1627:                        renderer.render(li);
1628:                    } catch (Throwable ex) {
1629:                        renderer.doCatch(ex);
1630:                    } finally {
1631:                        renderer.doFinally();
1632:                    }
1633:                }
1634:                return li;
1635:            }
1636:
1637:            /** Renders all {@link Listitem} if not loaded yet,
1638:             * with {@link #getItemRenderer}.
1639:             *
1640:             * @see #renderItem
1641:             * @see #renderItems
1642:             */
1643:            public void renderAll() {
1644:                if (_model == null)
1645:                    return;
1646:
1647:                final Renderer renderer = new Renderer();
1648:                try {
1649:                    for (Iterator it = getItems().iterator(); it.hasNext();)
1650:                        renderer.render((Listitem) it.next());
1651:                } catch (Throwable ex) {
1652:                    renderer.doCatch(ex);
1653:                } finally {
1654:                    renderer.doFinally();
1655:                }
1656:            }
1657:
1658:            public void renderItems(Set items) {
1659:                if (_model == null)
1660:                    return;
1661:
1662:                if (items.isEmpty())
1663:                    return; //nothing to do
1664:
1665:                final Renderer renderer = new Renderer();
1666:                try {
1667:                    for (Iterator it = items.iterator(); it.hasNext();)
1668:                        renderer.render((Listitem) it.next());
1669:                } catch (Throwable ex) {
1670:                    renderer.doCatch(ex);
1671:                } finally {
1672:                    renderer.doFinally();
1673:                }
1674:            }
1675:
1676:            //-- super --//
1677:            public void setMold(String mold) {
1678:                final String old = getMold();
1679:                if (!Objects.equals(old, mold)) {
1680:                    super .setMold(mold);
1681:
1682:                    if ("paging".equals(old)) { //change from paging
1683:                        if (_paging != null) {
1684:                            removePagingListener(_paging);
1685:                            _paging.detach();
1686:                        } else if (_pgi != null) {
1687:                            removePagingListener(_pgi);
1688:                        }
1689:                    } else if (inPagingMold()) { //change to paging
1690:                        if (_pgi != null)
1691:                            addPagingListener(_pgi);
1692:                        else
1693:                            newInternalPaging();
1694:                    }
1695:                }
1696:            }
1697:
1698:            public String getOuterAttrs() {
1699:                final StringBuffer sb = new StringBuffer(80).append(super 
1700:                        .getOuterAttrs());
1701:
1702:                if (inSelectMold()) {
1703:                    HTMLs.appendAttribute(sb, "name", _name);
1704:                    HTMLs.appendAttribute(sb, "size", getRows());
1705:
1706:                    if (isMultiple())
1707:                        HTMLs.appendAttribute(sb, "multiple", "multiple");
1708:                    if (_disabled)
1709:                        HTMLs.appendAttribute(sb, "disabled", "disabled");
1710:                    if (_tabindex >= 0)
1711:                        HTMLs.appendAttribute(sb, "tabindex", _tabindex);
1712:                } else {
1713:                    HTMLs.appendAttribute(sb, "z.name", _name);
1714:                    HTMLs.appendAttribute(sb, "z.size", _rows);
1715:                    if (_disabled)
1716:                        HTMLs.appendAttribute(sb, "z.disabled", true);
1717:                    if (_multiple)
1718:                        HTMLs.appendAttribute(sb, "z.multiple", true);
1719:                    HTMLs.appendAttribute(sb, "z.selId", getSelectedId());
1720:                    //if (_checkmark)
1721:                    //	HTMLs.appendAttribute(sb, "z.checkmark",  true);
1722:                    if (_vflex)
1723:                        HTMLs.appendAttribute(sb, "z.vflex", true);
1724:                    if (_model != null)
1725:                        HTMLs.appendAttribute(sb, "z.model", true);
1726:
1727:                    if (_scOddRow != null)
1728:                        HTMLs.appendAttribute(sb, "z.scOddRow", _scOddRow);
1729:
1730:                    if (getModel() != null) {
1731:                        int index = getItemCount();
1732:                        for (final ListIterator it = getItems().listIterator(
1733:                                index); it.hasPrevious(); --index)
1734:                            if (((Listitem) it.previous()).isLoaded())
1735:                                break;
1736:                        HTMLs.appendAttribute(sb, "z.lastLoadIdx", index);
1737:                    }
1738:                }
1739:
1740:                appendAsapAttr(sb, Events.ON_SELECT);
1741:                return sb.toString();
1742:            }
1743:
1744:            private class ItemIter implements  ListIterator,
1745:                    java.io.Serializable {
1746:                private ListIterator _it;
1747:                private int _j;
1748:                private boolean _bNxt;
1749:
1750:                private ItemIter(int index) {
1751:                    _j = index;
1752:                }
1753:
1754:                public void add(Object o) {
1755:                    prepare();
1756:                    _it.add(o);
1757:                    ++_j;
1758:                }
1759:
1760:                public boolean hasNext() {
1761:                    return _j < _items.size();
1762:                }
1763:
1764:                public boolean hasPrevious() {
1765:                    return _j > 0;
1766:                }
1767:
1768:                public Object next() {
1769:                    if (!hasNext())
1770:                        throw new NoSuchElementException();
1771:
1772:                    prepare();
1773:                    final Object o = _it.next();
1774:                    ++_j;
1775:                    _bNxt = true;
1776:                    return o;
1777:                }
1778:
1779:                public Object previous() {
1780:                    if (!hasPrevious())
1781:                        throw new NoSuchElementException();
1782:
1783:                    prepare();
1784:                    final Object o = _it.previous();
1785:                    --_j;
1786:                    _bNxt = false;
1787:                    return o;
1788:                }
1789:
1790:                public int nextIndex() {
1791:                    return _j;
1792:                }
1793:
1794:                public int previousIndex() {
1795:                    return _j - 1;
1796:                }
1797:
1798:                public void remove() {
1799:                    if (_it == null)
1800:                        throw new IllegalStateException();
1801:                    _it.remove();
1802:                    if (_bNxt)
1803:                        --_j;
1804:                }
1805:
1806:                public void set(Object o) {
1807:                    if (_it == null)
1808:                        throw new IllegalStateException();
1809:                    _it.set(o);
1810:                }
1811:
1812:                private void prepare() {
1813:                    if (_it == null)
1814:                        _it = getChildren().listIterator(_j + _hdcnt);
1815:                }
1816:            }
1817:
1818:            //Cloneable//
1819:            public Object clone() {
1820:                final Listbox clone = (Listbox) super .clone();
1821:                clone.init();
1822:                clone.afterUnmarshal();
1823:                if (clone._model != null) {
1824:                    //we use the same data model but we have to create a new listener
1825:                    clone._dataListener = null;
1826:                    clone.initDataListener();
1827:                }
1828:                return clone;
1829:            }
1830:
1831:            private void afterUnmarshal() {
1832:                int index = 0;
1833:                for (Iterator it = getChildren().iterator(); it.hasNext();) {
1834:                    final Object child = it.next();
1835:                    if (child instanceof  Listitem) {
1836:                        final Listitem li = (Listitem) child;
1837:                        li.setIndexDirectly(index++); //since Listitem.clone() resets index
1838:                        if (li.isSelected()) {
1839:                            _selItems.add(li);
1840:                        }
1841:                    } else if (child instanceof  Listhead) {
1842:                        _listhead = (Listhead) child;
1843:                    } else if (child instanceof  Listfoot) {
1844:                        _listfoot = (Listfoot) child;
1845:                    } else if (child instanceof  Paging) {
1846:                        _pgi = _paging = (Paging) child;
1847:                    }
1848:                }
1849:            }
1850:
1851:            //-- Serializable --//
1852:            private synchronized void readObject(java.io.ObjectInputStream s)
1853:                    throws java.io.IOException, ClassNotFoundException {
1854:                s.defaultReadObject();
1855:
1856:                init();
1857:
1858:                afterUnmarshal();
1859:                //TODO: how to marshal _pgi if _pgi != _paging
1860:                //TODO: re-register event listener for onPaging
1861:
1862:                if (_model != null)
1863:                    initDataListener();
1864:            }
1865:
1866:            //-- ComponentCtrl --//
1867:            protected Object newExtraCtrl() {
1868:                return new ExtraCtrl();
1869:            }
1870:
1871:            /** A utility class to implement {@link #getExtraCtrl}.
1872:             * It is used only by component developers.
1873:             */
1874:            protected class ExtraCtrl extends XulElement.ExtraCtrl implements 
1875:                    InnerWidth, Selectable, Cropper, RenderOnDemand {
1876:                //InnerWidth//
1877:                public void setInnerWidthByClient(String width) {
1878:                    _innerWidth = width == null ? "100%" : width;
1879:                }
1880:
1881:                //RenderOnDemand//
1882:                public void renderItems(Set items) {
1883:                    int cnt = items.size();
1884:                    if (cnt == 0)
1885:                        return; //nothing to do
1886:                    cnt = 20 - cnt;
1887:
1888:                    if (cnt > 0 && _preloadsz > 0) { //Feature 1740072: pre-load
1889:                        if (cnt > _preloadsz)
1890:                            cnt = _preloadsz; //at most 8 more to load
1891:
1892:                        //1. locate the first item found in items
1893:                        final List toload = new LinkedList();
1894:                        Iterator it = _items.iterator();
1895:                        while (it.hasNext()) {
1896:                            final Listitem li = (Listitem) it.next();
1897:                            if (items.contains(li)) //found
1898:                                break;
1899:                            if (!li.isLoaded())
1900:                                toload.add(0, li); //reverse order
1901:                        }
1902:
1903:                        //2. add unload items before the found one
1904:                        if (!toload.isEmpty()) {
1905:                            int bfcnt = cnt / 3;
1906:                            for (Iterator e = toload.iterator(); bfcnt > 0
1907:                                    && e.hasNext(); --bfcnt, --cnt) {
1908:                                items.add(e.next());
1909:                            }
1910:                        }
1911:
1912:                        //3. add unloaded after the found one
1913:                        while (cnt > 0 && it.hasNext()) {
1914:                            final Listitem li = (Listitem) it.next();
1915:                            if (!li.isLoaded() && items.add(li))
1916:                                --cnt;
1917:                        }
1918:                    }
1919:
1920:                    Listbox.this .renderItems(items);
1921:                }
1922:
1923:                //--Cropper--//
1924:                public boolean isCropper() {
1925:                    return inPagingMold();
1926:                }
1927:
1928:                public Set getAvailableAtClient() {
1929:                    if (!inPagingMold())
1930:                        return null;
1931:
1932:                    final Set avail = new HashSet(37);
1933:                    avail.addAll(_heads);
1934:                    if (_listfoot != null)
1935:                        avail.add(_listfoot);
1936:                    if (_paging != null)
1937:                        avail.add(_paging);
1938:
1939:                    final Paginal pgi = getPaginal();
1940:                    int pgsz = pgi.getPageSize();
1941:                    final int ofs = pgi.getActivePage() * pgsz;
1942:                    for (final Iterator it = getItems().listIterator(ofs); --pgsz >= 0
1943:                            && it.hasNext();)
1944:                        avail.add(it.next());
1945:                    return avail;
1946:                }
1947:
1948:                //-- Selectable --//
1949:                public void selectItemsByClient(Set selItems) {
1950:                    _noSmartUpdate = true;
1951:                    try {
1952:                        final boolean paging = inPagingMold();
1953:                        if (!_multiple
1954:                                || (!paging && (selItems == null || selItems
1955:                                        .size() <= 1))) {
1956:                            final Listitem item = selItems != null
1957:                                    && selItems.size() > 0 ? (Listitem) selItems
1958:                                    .iterator().next()
1959:                                    : null;
1960:                            selectItem(item);
1961:                        } else {
1962:                            int from, to;
1963:                            if (paging) {
1964:                                final Paginal pgi = getPaginal();
1965:                                int pgsz = pgi.getPageSize();
1966:                                from = pgi.getActivePage() * pgsz;
1967:                                to = from + pgsz; //excluded
1968:                            } else {
1969:                                from = to = 0;
1970:                            }
1971:
1972:                            int j = 0;
1973:                            for (Iterator it = _items.iterator(); it.hasNext(); ++j) {
1974:                                final Listitem item = (Listitem) it.next();
1975:                                if (selItems.contains(item)) {
1976:                                    addItemToSelection(item);
1977:                                } else if (!paging) {
1978:                                    removeItemFromSelection(item);
1979:                                } else {
1980:                                    final int index = item.getIndex();
1981:                                    if (index >= from && index < to)
1982:                                        removeItemFromSelection(item);
1983:                                }
1984:                            }
1985:                        }
1986:                    } finally {
1987:                        _noSmartUpdate = false;
1988:                    }
1989:                }
1990:            }
1991:
1992:            /** An iterator used by _heads.
1993:             */
1994:            private class Iter implements  Iterator {
1995:                private final Iterator _it = getChildren().iterator();
1996:                private int _j;
1997:
1998:                public boolean hasNext() {
1999:                    return _j < _hdcnt;
2000:                }
2001:
2002:                public Object next() {
2003:                    final Object o = _it.next();
2004:                    ++_j;
2005:                    return o;
2006:                }
2007:
2008:                public void remove() {
2009:                    throw new UnsupportedOperationException();
2010:                }
2011:            }
2012:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.