Source Code Cross Referenced for ListView.java in  » J2EE » wicket » org » apache » wicket » markup » html » list » 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 » J2EE » wicket » org.apache.wicket.markup.html.list 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.wicket.markup.html.list;
018:
019:        import java.io.Serializable;
020:        import java.util.Collections;
021:        import java.util.Iterator;
022:        import java.util.List;
023:
024:        import org.apache.wicket.Component;
025:        import org.apache.wicket.markup.html.link.Link;
026:        import org.apache.wicket.markup.repeater.AbstractRepeater;
027:        import org.apache.wicket.model.IModel;
028:        import org.apache.wicket.model.Model;
029:        import org.apache.wicket.util.collections.ReadOnlyIterator;
030:        import org.apache.wicket.version.undo.Change;
031:
032:        /**
033:         * A ListView is a repeater that makes it easy to display/work with {@link List}s.
034:         * However, there are situations where it is necessary to work with other
035:         * collection types, for repeaters that might work better with non-list or
036:         * database-driven collections see the org.apache.wicket.markup.repeater
037:         * package.
038:         * 
039:         * Also notice that in a list the item's uniqueness/primary key/id is identified
040:         * as its index in the list. If this is not the case you should either override
041:         * {@link #getListItemModel(IModel, int)} to return a model that will work with
042:         * the item's true primary key, or use a different repeater that does not rely
043:         * on the list index.
044:         * 
045:         * 
046:         * A ListView holds ListItem children. Items can be re-ordered and deleted,
047:         * either one at a time or many at a time.
048:         * <p>
049:         * Example:
050:         * 
051:         * <pre>
052:         *                      &lt;tbody&gt;
053:         *                        &lt;tr wicket:id=&quot;rows&quot; class=&quot;even&quot;&gt;
054:         *                            &lt;td&gt;&lt;span wicket:id=&quot;id&quot;&gt;Test ID&lt;/span&gt;&lt;/td&gt;
055:         *                        ...    
056:         * </pre>
057:         * 
058:         * <p>
059:         * Though this example is about a HTML table, ListView is not at all limited to
060:         * HTML tables. Any kind of list can be rendered using ListView.
061:         * <p>
062:         * The related Java code:
063:         * 
064:         * <pre>
065:         * add(new ListView(&quot;rows&quot;, listData)
066:         * {
067:         * 	public void populateItem(final ListItem item)
068:         * 	{
069:         * 		final UserDetails user = (UserDetails)item.getModelObject();
070:         * 		item.add(new Label(&quot;id&quot;, user.getId()));
071:         * 	}
072:         * });
073:         * </pre>
074:         * 
075:         * <p>
076:         * <strong>NOTE:</strong>
077:         * 
078:         * When you want to change the default generated markup it is important to
079:         * realise that the ListView instance itself does not correspond to any markup,
080:         * however, the generated ListItems do.<br/>
081:         * 
082:         * This means that methods like {@link #setRenderBodyOnly(boolean)} and
083:         * {@link #add(org.apache.wicket.behavior.IBehavior)} should be invoked on the
084:         * {@link ListItem} that is given in {@link #populateItem(ListItem)} method.
085:         * </p>
086:         * 
087:         * <p>
088:         * <strong>WARNING:</strong> though you can nest ListViews within Forms, you
089:         * HAVE to set the setReuseItems property to true in order to have validation
090:         * work properly. By default, setReuseItems is false, which has the effect that
091:         * ListView replaces all child components by new instances. The idea behind this
092:         * is that you always render the fresh data, and as people usually use ListViews
093:         * for displaying read-only lists (at least, that's what we think), this is good
094:         * default behavior. <br />
095:         * However, as the components are replaced before the rendering starts, the
096:         * search for specific messages for these components fails as they are replaced
097:         * with other instances. Another problem is that 'wrong' user input is kept as
098:         * (temporary) instance data of the components. As these components are replaced
099:         * by new ones, your user will never see the wrong data when setReuseItems is
100:         * false.
101:         * </p>
102:         * 
103:         * @author Jonathan Locke
104:         * @author Juergen Donnerstag
105:         * @author Johan Compagner
106:         * @author Eelco Hillenius
107:         */
108:        public abstract class ListView extends AbstractRepeater {
109:            /** Index of the first item to show */
110:            private int firstIndex = 0;
111:
112:            /**
113:             * If true, re-rendering the list view is more efficient if the window
114:             * doesn't get changed at all or if it gets scrolled (compared to paging).
115:             * But if you modify the listView model object, than you must manually call
116:             * listView.removeAll() in order to rebuild the ListItems. If you nest a
117:             * ListView in a Form, ALWAYS set this property to true, as otherwise
118:             * validation will not work properly.
119:             */
120:            private boolean reuseItems = false;
121:
122:            /** Max number (not index) of items to show */
123:            private int viewSize = Integer.MAX_VALUE;
124:
125:            /**
126:             * @see org.apache.wicket.Component#Component(String)
127:             */
128:            public ListView(final String id) {
129:                super (id);
130:            }
131:
132:            /**
133:             * @see org.apache.wicket.Component#Component(String, IModel)
134:             */
135:            public ListView(final String id, final IModel model) {
136:                super (id, model);
137:
138:                if (model == null) {
139:                    throw new IllegalArgumentException(
140:                            "Null models are not allowed. If you have no model, you may prefer a Loop instead");
141:                }
142:
143:                // A reasonable default for viewSize can not be determined right now,
144:                // because list items might be added or removed until ListView
145:                // gets rendered.
146:            }
147:
148:            /**
149:             * @param id
150:             *            See Component
151:             * @param list
152:             *            List to cast to Serializable
153:             * @see org.apache.wicket.Component#Component(String, IModel)
154:             */
155:            public ListView(final String id, final List list) {
156:                this (id, new Model((Serializable) list));
157:            }
158:
159:            /**
160:             * Gets the list of items in the listView. This method is final because it
161:             * is not designed to be overridden. If it were allowed to be overridden,
162:             * the values returned by getModelObject() and getList() might not coincide.
163:             * 
164:             * @return The list of items in this list view.
165:             */
166:            public final List getList() {
167:                final List list = (List) getModelObject();
168:                if (list == null) {
169:                    return Collections.EMPTY_LIST;
170:                }
171:                return list;
172:            }
173:
174:            /**
175:             * If true re-rendering the list view is more efficient if the windows
176:             * doesn't get changed at all or if it gets scrolled (compared to paging).
177:             * But if you modify the listView model object, than you must manually call
178:             * listView.removeAll() in order to rebuild the ListItems. If you nest a
179:             * ListView in a Form, ALLWAYS set this property to true, as otherwise
180:             * validation will not work properly.
181:             * 
182:             * @return Whether to reuse items
183:             */
184:            public boolean getReuseItems() {
185:                return reuseItems;
186:            }
187:
188:            /**
189:             * Get index of first cell in page. Default is: 0.
190:             * 
191:             * @return Index of first cell in page. Default is: 0
192:             */
193:            public final int getStartIndex() {
194:                return firstIndex;
195:            }
196:
197:            /**
198:             * Based on the model object's list size, firstIndex and view size,
199:             * determine what the view size really will be. E.g. default for viewSize is
200:             * Integer.MAX_VALUE, if not set via setViewSize(). If the underlying list
201:             * has 10 elements, the value returned by getViewSize() will be 10 if
202:             * startIndex = 0.
203:             * 
204:             * @return The number of items to be populated and rendered.
205:             */
206:            public int getViewSize() {
207:                int size = viewSize;
208:
209:                final Object modelObject = getModelObject();
210:                if (modelObject == null) {
211:                    return size == Integer.MAX_VALUE ? 0 : size;
212:                }
213:
214:                // Adjust view size to model object's list size
215:                final int modelSize = getList().size();
216:                if (firstIndex > modelSize) {
217:                    return 0;
218:                }
219:
220:                if ((size == Integer.MAX_VALUE)
221:                        || ((firstIndex + size) > modelSize)) {
222:                    size = modelSize - firstIndex;
223:                }
224:
225:                // firstIndex + size must be smaller than Integer.MAX_VALUE
226:                if ((Integer.MAX_VALUE - size) < firstIndex) {
227:                    throw new IllegalStateException(
228:                            "firstIndex + size must be smaller than Integer.MAX_VALUE");
229:                }
230:
231:                return size;
232:            }
233:
234:            /**
235:             * Returns a link that will move the given item "down" (towards the end) in
236:             * the listView.
237:             * 
238:             * @param id
239:             *            Name of move-down link component to create
240:             * @param item
241:             * @return The link component
242:             */
243:            public final Link moveDownLink(final String id, final ListItem item) {
244:                return new Link(id) {
245:                    private static final long serialVersionUID = 1L;
246:
247:                    /**
248:                     * @see org.apache.wicket.markup.html.link.Link#onClick()
249:                     */
250:                    public void onClick() {
251:                        final int index = getList().indexOf(
252:                                item.getModelObject());
253:                        if (index != -1) {
254:                            addStateChange(new Change() {
255:                                private static final long serialVersionUID = 1L;
256:
257:                                final int oldIndex = index;
258:
259:                                public void undo() {
260:                                    Collections.swap(getList(), oldIndex + 1,
261:                                            oldIndex);
262:                                }
263:
264:                            });
265:
266:                            // Swap list items and invalidate listView
267:                            Collections.swap(getList(), index, index + 1);
268:                            ListView.this .removeAll();
269:                        }
270:                    }
271:
272:                    /**
273:                     * @see org.apache.wicket.Component#onBeforeRender()
274:                     */
275:                    protected void onBeforeRender() {
276:                        super .onBeforeRender();
277:                        setAutoEnable(false);
278:                        if (getList().indexOf(item.getModelObject()) == (getList()
279:                                .size() - 1)) {
280:                            setEnabled(false);
281:                        }
282:                    }
283:                };
284:            }
285:
286:            /**
287:             * Returns a link that will move the given item "up" (towards the beginning)
288:             * in the listView.
289:             * 
290:             * @param id
291:             *            Name of move-up link component to create
292:             * @param item
293:             * @return The link component
294:             */
295:            public final Link moveUpLink(final String id, final ListItem item) {
296:                return new Link(id) {
297:                    private static final long serialVersionUID = 1L;
298:
299:                    /**
300:                     * @see org.apache.wicket.markup.html.link.Link#onClick()
301:                     */
302:                    public void onClick() {
303:                        final int index = getList().indexOf(
304:                                item.getModelObject());
305:                        if (index != -1) {
306:
307:                            addStateChange(new Change() {
308:                                private static final long serialVersionUID = 1L;
309:
310:                                final int oldIndex = index;
311:
312:                                public void undo() {
313:                                    Collections.swap(getList(), oldIndex - 1,
314:                                            oldIndex);
315:                                }
316:
317:                            });
318:
319:                            // Swap items and invalidate listView
320:                            Collections.swap(getList(), index, index - 1);
321:                            ListView.this .removeAll();
322:                        }
323:                    }
324:
325:                    /**
326:                     * @see org.apache.wicket.Component#onBeforeRender()
327:                     */
328:                    protected void onBeforeRender() {
329:                        super .onBeforeRender();
330:                        setAutoEnable(false);
331:                        if (getList().indexOf(item.getModelObject()) == 0) {
332:                            setEnabled(false);
333:                        }
334:                    }
335:                };
336:            }
337:
338:            /**
339:             * Returns a link that will remove this ListItem from the ListView that
340:             * holds it.
341:             * 
342:             * @param id
343:             *            Name of remove link component to create
344:             * @param item
345:             * @return The link component
346:             */
347:            public final Link removeLink(final String id, final ListItem item) {
348:                return new Link(id) {
349:                    private static final long serialVersionUID = 1L;
350:
351:                    /**
352:                     * @see org.apache.wicket.markup.html.link.Link#onClick()
353:                     */
354:                    public void onClick() {
355:                        addStateChange(new Change() {
356:                            private static final long serialVersionUID = 1L;
357:
358:                            final int oldIndex = getList().indexOf(
359:                                    item.getModelObject());
360:                            final Object removedObject = item.getModelObject();
361:
362:                            public void undo() {
363:                                getList().add(oldIndex, removedObject);
364:                            }
365:
366:                        });
367:
368:                        item.modelChanging();
369:
370:                        // Remove item and invalidate listView
371:                        getList().remove(item.getModelObject());
372:
373:                        ListView.this .modelChanged();
374:                        ListView.this .removeAll();
375:                    }
376:                };
377:            }
378:
379:            /**
380:             * Sets the model as the provided list and removes all children, so that the
381:             * next render will be using the contents of the model.
382:             * 
383:             * @param list
384:             *            The list for the new model. The list must implement
385:             *            {@link Serializable}.
386:             * @return This for chaining
387:             */
388:            public Component setList(List list) {
389:                return setModel(new Model((Serializable) list));
390:            }
391:
392:            /**
393:             * Sets the model and removes all current children, so that the next render
394:             * will be using the contents of the model.
395:             * 
396:             * @param model
397:             *            The new model
398:             * @return This for chaining
399:             * 
400:             * @see org.apache.wicket.MarkupContainer#setModel(org.apache.wicket.model.IModel)
401:             */
402:            public Component setModel(IModel model) {
403:                return super .setModel(model);
404:            }
405:
406:            /**
407:             * If true re-rendering the list view is more efficient if the windows
408:             * doesn't get changed at all or if it gets scrolled (compared to paging).
409:             * But if you modify the listView model object, than you must manually call
410:             * listView.removeAll() in order to rebuild the ListItems. If you nest a
411:             * ListView in a Form, ALLWAYS set this property to true, as otherwise
412:             * validation will not work properly.
413:             * 
414:             * @param reuseItems
415:             *            Whether to reuse the child items.
416:             * @return this
417:             */
418:            public ListView setReuseItems(boolean reuseItems) {
419:                this .reuseItems = reuseItems;
420:                return this ;
421:            }
422:
423:            /**
424:             * Set the index of the first item to render
425:             * 
426:             * @param startIndex
427:             *            First index of model object's list to display
428:             * @return This
429:             */
430:            public ListView setStartIndex(final int startIndex) {
431:                firstIndex = startIndex;
432:
433:                if (firstIndex < 0) {
434:                    firstIndex = 0;
435:                } else if (firstIndex > getList().size()) {
436:                    firstIndex = 0;
437:                }
438:
439:                return this ;
440:            }
441:
442:            /**
443:             * Define the maximum number of items to render. Default: render all.
444:             * 
445:             * @param size
446:             *            Number of items to display
447:             * @return This
448:             */
449:            public ListView setViewSize(final int size) {
450:                viewSize = size;
451:
452:                if (viewSize < 0) {
453:                    viewSize = Integer.MAX_VALUE;
454:                }
455:
456:                return this ;
457:            }
458:
459:            /**
460:             * Subclasses may provide their own ListItemModel with extended
461:             * functionality. The default ListItemModel works fine with mostly static
462:             * lists where index remains valid. In cases where the underlying list
463:             * changes a lot (many users using the application), it may not longer be
464:             * appropriate. In that case your own ListItemModel implementation should
465:             * use an id (e.g. the database' record id) to identify and load the list
466:             * item model object.
467:             * 
468:             * @param listViewModel
469:             *            The ListView's model
470:             * @param index
471:             *            The list item index
472:             * @return The ListItemModel created
473:             */
474:            protected IModel getListItemModel(final IModel listViewModel,
475:                    final int index) {
476:                return new ListItemModel(this , index);
477:            }
478:
479:            /**
480:             * Create a new ListItem for list item at index.
481:             * 
482:             * @param index
483:             * @return ListItem
484:             */
485:            protected ListItem newItem(final int index) {
486:                return new ListItem(index, getListItemModel(getModel(), index));
487:            }
488:
489:            /**
490:             * @see org.apache.wicket.MarkupContainer#onBeforeRender()
491:             */
492:            protected void onBeforeRender() {
493:                if (isVisibleInHierarchy()) {
494:                    // Get number of items to be displayed
495:                    final int size = getViewSize();
496:                    if (size > 0) {
497:                        if (getReuseItems()) {
498:                            // Remove all ListItems no longer required
499:                            final int maxIndex = firstIndex + size;
500:                            for (final Iterator iterator = iterator(); iterator
501:                                    .hasNext();) {
502:                                // Get next child component
503:                                final ListItem child = (ListItem) iterator
504:                                        .next();
505:                                if (child != null) {
506:                                    final int index = child.getIndex();
507:                                    if (index < firstIndex || index >= maxIndex) {
508:                                        iterator.remove();
509:                                    }
510:                                }
511:                            }
512:                        } else {
513:                            // Automatically rebuild all ListItems before rendering the
514:                            // list view
515:                            removeAll();
516:                        }
517:
518:                        // Loop through the markup in this container for each item
519:                        for (int i = 0; i < size; i++) {
520:                            // Get index
521:                            final int index = firstIndex + i;
522:
523:                            // If this component does not already exist, populate it
524:                            ListItem item = (ListItem) get(Integer
525:                                    .toString(index));
526:                            if (item == null) {
527:                                // Create item for index
528:                                item = newItem(index);
529:
530:                                // Add list item
531:                                add(item);
532:
533:                                // Populate the list item
534:                                onBeginPopulateItem(item);
535:                                populateItem(item);
536:                            }
537:                        }
538:                    } else {
539:                        removeAll();
540:                    }
541:
542:                }
543:                super .onBeforeRender();
544:            }
545:
546:            /**
547:             * Comes handy for ready made ListView based components which must implement
548:             * populateItem() but you don't want to lose compile time error checking
549:             * reminding the user to implement abstract populateItem().
550:             * 
551:             * @param item
552:             */
553:            protected void onBeginPopulateItem(final ListItem item) {
554:            }
555:
556:            /**
557:             * Populate a given item.
558:             * <p>
559:             * <b>be carefull</b> to add any components to the list item. So, don't do:
560:             * 
561:             * <pre>
562:             * add(new Label(&quot;foo&quot;, &quot;bar&quot;));
563:             * </pre>
564:             * 
565:             * but:
566:             * 
567:             * <pre>
568:             * item.add(new Label(&quot;foo&quot;, &quot;bar&quot;));
569:             * </pre>
570:             * 
571:             * </p>
572:             * 
573:             * @param item
574:             *            The item to populate
575:             */
576:            protected abstract void populateItem(final ListItem item);
577:
578:            /**
579:             * @see org.apache.wicket.markup.repeater.AbstractRepeater#renderChild(org.apache.wicket.Component)
580:             */
581:            protected final void renderChild(Component child) {
582:                renderItem((ListItem) child);
583:            }
584:
585:            /**
586:             * Render a single item.
587:             * 
588:             * @param item
589:             *            The item to be rendered
590:             */
591:            protected void renderItem(final ListItem item) {
592:                item.render(getMarkupStream());
593:            }
594:
595:            /**
596:             * @see org.apache.wicket.markup.repeater.AbstractRepeater#renderIterator()
597:             */
598:            protected Iterator renderIterator() {
599:
600:                final int size = size();
601:                return new ReadOnlyIterator() {
602:                    private int index = 0;
603:
604:                    public boolean hasNext() {
605:                        return index < size;
606:                    }
607:
608:                    public Object next() {
609:                        final String id = Integer.toString(firstIndex + index);
610:                        index++;
611:                        Component c = get(id);
612:                        return c;
613:                    }
614:                };
615:            }
616:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.