📄 listbox.java
字号:
public void setName(String name) { if (name != null && name.length() == 0) name = null; if (!Objects.equals(_name, name)) { _name = name; if (inSelectMold()) smartUpdate("name", _name); else if (_name != null) smartUpdate("z.name", _name); else invalidate(); //1) generate _value; 2) add submit listener } } /** Returns a live list of all {@link Listitem}. * By live we mean you can add or remove them directly with * the List interface. In other words, you could add or remove * an item by manipulating the returned list directly. */ public List getItems() { return _items; } /** Returns the number of items. */ public int getItemCount() { return _items.size(); } /** Returns the item at the specified index. * * <p>Note: if live data is used ({@link #getModel} is not null), * the returned item might NOT be loaded yet. * To ensure it is loaded, you have to invoke {@link #renderItem}. */ public Listitem getItemAtIndex(int index) { return (Listitem)_items.get(index); } /** Returns the index of the specified item, or -1 if not found. */ public int getIndexOfItem(Listitem item) { return item == null ? -1: item.getIndex(); } /** Returns the index of the selected item (-1 if no one is selected). */ public int getSelectedIndex() { return _jsel; } /** Deselects all of the currently selected items and selects * the item with the given index. */ public void setSelectedIndex(int jsel) { if (jsel >= _items.size()) throw new UiException("Out of bound: "+jsel+" while size="+_items.size()); if (jsel < -1) jsel = -1; if (jsel < 0) { //unselct all clearSelection(); } else if (jsel != _jsel || (_multiple && _selItems.size() > 1)) { for (Iterator it = _selItems.iterator(); it.hasNext();) { final Listitem item = (Listitem)it.next(); item.setSelectedDirectly(false); } _selItems.clear(); _jsel = jsel; final Listitem item = getItemAtIndex(_jsel); item.setSelectedDirectly(true); _selItems.add(item); if (inSelectMold()) smartUpdate("selectedIndex", Integer.toString(_jsel)); else smartUpdate("select", item.getUuid()); //Bug 1734950: don't count on index (since it may change) //On the other hand, it is OK with select-mold since //it invalidates if items are added or removed } } /** Deselects all of the currently selected items and selects * the given item. * <p>It is the same as {@link #setSelectedItem}. * @param item the item to select. If null, all items are deselected. */ public void selectItem(Listitem item) { if (item == null) { setSelectedIndex(-1); } else { if (item.getParent() != this) throw new UiException("Not a child: "+item); if (_multiple || !item.isSelected()) setSelectedIndex(item.getIndex()); } } /** Selects the given item, without deselecting any other items * that are already selected.. */ public void addItemToSelection(Listitem item) { if (item.getParent() != this) throw new UiException("Not a child: "+item); if (!item.isSelected()) { if (!_multiple) { selectItem(item); } else { if (item.getIndex() < _jsel || _jsel < 0) { _jsel = item.getIndex(); if (!inSelectMold()) smartUpdate("z.selId", getSelectedId()); } item.setSelectedDirectly(true); _selItems.add(item); if (inSelectMold()) { item.smartUpdate("selected", true); } else { smartUpdateSelection(); } } } } /** Deselects the given item without deselecting other items. */ public void removeItemFromSelection(Listitem item) { if (item.getParent() != this) throw new UiException("Not a child: "+item); if (item.isSelected()) { if (!_multiple) { clearSelection(); } else { final int oldSel = _jsel; item.setSelectedDirectly(false); _selItems.remove(item); fixSelectedIndex(0); if (inSelectMold()) { item.smartUpdate("selected", false); } else { smartUpdateSelection(); if (oldSel != _jsel) smartUpdate("z.selId", getSelectedId()); } } } } /** Note: we have to update all selection at once, since addItemToSelection * and removeItemFromSelection might be called interchangeably. */ private void smartUpdateSelection() { final StringBuffer sb = new StringBuffer(80); for (Iterator it = _selItems.iterator(); it.hasNext();) { if (sb.length() > 0) sb.append(','); sb.append(((Listitem)it.next()).getUuid()); } smartUpdate("chgSel", sb.toString()); } /** If the specified item is selected, it is deselected. * If it is not selected, it is selected. Other items in the list box * that are selected are not affected, and retain their selected state. */ public void toggleItemSelection(Listitem item) { if (item.isSelected()) removeItemFromSelection(item); else addItemToSelection(item); } /** Clears the selection. */ public void clearSelection() { if (!_selItems.isEmpty()) { for (Iterator it = _selItems.iterator(); it.hasNext();) { final Listitem item = (Listitem)it.next(); item.setSelectedDirectly(false); } _selItems.clear(); _jsel = -1; if (inSelectMold()) smartUpdate("selectedIndex", "-1"); else smartUpdate("select", ""); //Bug 1734950: don't count on index (since it may change) } } /** Selects all items. */ public void selectAll() { if (!_multiple) throw new UiException("Appliable only to the multiple seltype: "+this); if (_items.size() != _selItems.size()) { for (Iterator it = _items.iterator(); it.hasNext();) { final Listitem item = (Listitem)it.next(); _selItems.add(item); item.setSelectedDirectly(true); } _jsel = _items.isEmpty() ? -1: 0; smartUpdate("selectAll", "true"); } } /** Returns the selected item. * * <p>Note: if live data is used ({@link #getModel} is not null), * the returned item might NOT be loaded yet. * To ensure it is loaded, you have to invoke {@link #renderItem}. */ public Listitem getSelectedItem() { return _jsel >= 0 ? _jsel > 0 && _selItems.size() == 1 ? //optimize for performance (Listitem)_selItems.iterator().next(): getItemAtIndex(_jsel): null; } /** Deselects all of the currently selected items and selects * the given item. * <p>It is the same as {@link #selectItem}. */ public void setSelectedItem(Listitem item) { selectItem(item); } /** Returns all selected items. * * <p>Note: if live data is used ({@link #getModel} is not null), * the returned item might NOT be loaded yet. * To ensure it is loaded, you have to invoke {@link #renderItem}. */ public Set getSelectedItems() { return _roSelItems; } /** Returns the number of items being selected. */ public int getSelectedCount() { return _selItems.size(); } /** Appends an item. * * <p>Note: if live data is used ({@link #getModel} is not null), * the returned item might NOT be loaded yet. * To ensure it is loaded, you have to invoke {@link #renderItem}. */ public Listitem appendItem(String label, String value) { final Listitem item = new Listitem(label, value); item.applyProperties(); item.setParent(this); return item; } /** Removes the child item in the list box at the given index. * * <p>Note: if live data is used ({@link #getModel} is not null), * the returned item might NOT be loaded yet. * To ensure it is loaded, you have to invoke {@link #renderItem}. * * @return the removed item. */ public Listitem removeItemAt(int index) { final Listitem item = getItemAtIndex(index); removeChild(item); return item; } //--Paging--// /** Returns the paging controller, or null if not available. * Note: the paging controller is used only if {@link #getMold} is "paging". * * <p>If mold is "paging", this method never returns null, because * a child paging controller is created automcatically (if not specified * by developers with {@link #setPaginal}). * * <p>If a paging controller is specified (either by {@link #setPaginal}, * or by {@link #setMold} with "paging"), * the listbox will rely on the paging controller to handle long-content * instead of scrolling. */ public Paginal getPaginal() { return _pgi; } /* Specifies the paging controller. * Note: the paging controller is used only if {@link #getMold} is "paging". * * <p>It is OK, though without any effect, to specify a paging controller * even if mold is not "paging". * * @param pgi the paging controller. If null and {@link #getMold} is "paging", * a paging controller is created automatically as a child component * (see {@link #getPaging}). */ public void setPaginal(Paginal pgi) { if (!Objects.equals(pgi, _pgi)) { final Paginal old = _pgi; _pgi = pgi; if (inPagingMold()) { if (old != null) removePagingListener(old); if (_pgi == null) { if (_paging != null) _pgi = _paging; else newInternalPaging(); } else { //_pgi != null if (_pgi != _paging) { if (_paging != null) _paging.detach(); _pgi.setTotalSize(getItemCount()); addPagingListener(_pgi); } } } } } /** Creates the internal paging component. */ private void newInternalPaging() { assert D.OFF || inPagingMold(): "paging mold only"; assert D.OFF || (_paging == null && _pgi == null); final Paging paging = new Paging(); paging.setAutohide(true); paging.setDetailed(true); paging.setTotalSize(getItemCount()); paging.setParent(this); addPagingListener(_pgi); } /** Adds the event listener for the onPaging event. */ private void addPagingListener(Paginal pgi) { if (_pgListener == null) _pgListener = new EventListener() { public void onEvent(Event event) { final PagingEvent evt = (PagingEvent)event; Events.postEvent( new PagingEvent(evt.getName(), Listbox.this, evt.getPageable(), evt.getActivePage())); } }; pgi.addEventListener(ZulEvents.ON_PAGING, _pgListener); if (_pgImpListener == null) _pgImpListener = new EventListener() { public void onEvent(Event event) { if (_model != null && inPagingMold()) { final Renderer renderer = new Renderer(); try { final Paginal pgi = getPaginal(); int pgsz = pgi.getPageSize(); final int ofs = pgi.getActivePage() * pgsz; for (final Iterator it = getItems().listIterator(ofs); --pgsz >= 0 && it.hasNext();) renderer.render((Listitem)it.next()); } catch (Throwable ex) { renderer.doCatch(ex); } finally { renderer.doFinally(); } } invalidate(); } }; pgi.addEventListener("onPagingImpl", _pgImpListener); } /** Removes the event listener for the onPaging event. */ private void removePagingListener(Paginal pgi) { pgi.removeEventListener(ZulEvents.ON_PAGING, _pgListener); pgi.removeEventListener("onPagingImpl", _pgImpListener); } /** Returns the child paging controller that is created automatically, * or null if mold is not "paging", or the controller is specified externally * by {@link #setPaginal}. */ public Paging getPaging() { return _paging; } /** Returns the page size, aka., the number items per page. * @exception IllegalStateException if {@link #getPaginal} returns null, * i.e., mold is not "paging" and no external controller is specified. */ public int getPageSize() { if (_pgi == null) throw new IllegalStateException("Available only the paging mold"); return _pgi.getPageSize(); } /** Sets the page size, aka., the number items per page. * @exception IllegalStateException if {@link #getPaginal} returns null, * i.e., mold is not "paging" and no external controller is specified. */ public void setPageSize(int pgsz) { if (_pgi == null) throw new IllegalStateException("Available only the paging mold"); _pgi.setPageSize(pgsz); } /** Returns whether this listbox is in the paging mold. */ /*package*/ boolean inPagingMold() { return "paging".equals(getMold()); } /** Returns the index of the first visible child. * <p>Used only for component development, not for application developers. */ public int getVisibleBegin() { if (!inPagingMold()) return 0; final Paginal pgi = getPaginal(); return pgi.getActivePage() * pgi.getPageSize(); } /** Returns the index of the last visible child. * <p>Used only for component development, not for application developers. */ public int getVisibleEnd() { if (!inPagingMold()) return Integer.MAX_VALUE; final Paginal pgi = getPaginal(); return (pgi.getActivePage() + 1) * pgi.getPageSize() - 1; //inclusive } /** Returns the style class for the odd rows. * <p>Default: odd. * @since 3.0.0 */ public String getOddRowSclass() { return _scOddRow; } /** Sets the style class for the odd rows. * If the style class doesn't exist, the striping effect disappears. * You can provide different effects by providing the proper style * classes. * @since 3.0.0 */ public void setOddRowSclass(String scls) { if (scls != null && scls.length() == 0) scls = null; if (!Objects.equals(_scOddRow, scls)) { _scOddRow = scls; smartUpdate("z.scOddRow", scls); } } //-- Component --// public void smartUpdate(String attr, String value) { if (!_noSmartUpdate) super.smartUpdate(attr, value); } public void onChildAdded(Component child) { super.onChildAdded(child); if (inSelectMold()) invalidate(); //Both IE and Mozilla are buggy if we insert options by innerHTML else if(inPagingMold() && (child instanceof Listitem)) _pgi.setTotalSize(getItemCount()); } public void onChildRemoved(Component child) { super.onChildRemoved(child); if (inSelectMold()) invalidate(); //Both IE and Mozilla are buggy if we remove options by outerHTML //CONSIDER: use special command to remove items //Cons: if user remove a lot of items it is slower else if(inPagingMold() && (child instanceof Listitem)) _pgi.setTotalSize(getItemCount()); } public boolean insertBefore(Component newChild, Component refChild) { if (newChild instanceof Listitem) { //first: listhead or auxhead //last two: listfoot and paging if (refChild != null && refChild.getParent() != this) refChild = null; //Bug 1649625: it becomes the last child if (refChild != null && (refChild == _listhead || refChild instanceof Auxhead)) refChild = getChildren().size() > _hdcnt ? (Component)getChildren().get(_hdcnt): null; refChild = fixRefChildBeforeFoot(refChild);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -