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


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