Source Code Cross Referenced for ListSelectionModelMgrImpl.java in  » Ajax » ItsNat » org » itsnat » impl » comp » 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 » ItsNat » org.itsnat.impl.comp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:          ItsNat Java Web Application Framework
003:          Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
004:          Author: Jose Maria Arranz Santamaria
005:
006:          This program is free software: you can redistribute it and/or modify
007:          it under the terms of the GNU Affero General Public License as published by
008:          the Free Software Foundation, either version 3 of the License, or
009:          (at your option) any later version. See the GNU Affero General Public 
010:          License for more details. See the copy of the GNU Affero General Public License
011:          included in this program. If not, see <http://www.gnu.org/licenses/>.
012:         */
013:
014:        package org.itsnat.impl.comp;
015:
016:        import javax.swing.ListSelectionModel;
017:        import javax.swing.event.ListSelectionListener;
018:
019:        /**
020:         *
021:         * @author jmarranz
022:         */
023:        public class ListSelectionModelMgrImpl {
024:            protected ListSelectionModel selectionModel;
025:            protected int size = 0;
026:
027:            /** Creates a new instance of ListSelectionModelMgrImpl */
028:            public ListSelectionModelMgrImpl(ListSelectionModel selectionModel) {
029:                if (selectionModel == null)
030:                    selectionModel = EmptyListSelectionModelImpl.SINGLETON;
031:
032:                this .selectionModel = selectionModel;
033:
034:                //syncWithDataModel();
035:            }
036:
037:            public static ListSelectionModelMgrImpl newListSelectionModelMgr(
038:                    ListSelectionModel selectionModel, int size) {
039:                ListSelectionModelMgrImpl selModelMgr = new ListSelectionModelMgrImpl(
040:                        selectionModel);
041:
042:                selModelMgr.syncWithDataModel(size);
043:
044:                return selModelMgr;
045:            }
046:
047:            public void dispose() {
048:                removeAllUpdateModel();
049:            }
050:
051:            public int getSize() {
052:                return size;
053:            }
054:
055:            public void setSize(int size) {
056:                int oldSize = this .size;
057:                int diff = size - oldSize;
058:                if (diff > 0) // Han sido añadidas al final               
059:                {
060:                    insertElementUpdateModel(oldSize, diff);
061:                } else if (diff < 0) // Han sido eliminadas del final
062:                {
063:                    diff = -diff; // lo ponemos como positivo
064:                    removeRangeUpdateModel(oldSize - diff, oldSize - 1);
065:                }
066:            }
067:
068:            public ListSelectionModel getListSelectionModel() {
069:                return selectionModel;
070:            }
071:
072:            public void syncWithDataModel(int size) {
073:                if (this .size > 0) // Se ha cambiado el data model
074:                    removeAllUpdateModel();
075:
076:                this .size = 0;
077:
078:                // Iniciando el selection model, el data model es el que manda
079:                // porque si no hay datos nos da igual como esté definido el selectionModel
080:                // dado como argumento.
081:                // Es usado cuando se define el SelectionModel existiendo ya
082:                // un data model que puede contener ya datos.
083:
084:                insertElementUpdateModel(0, size);
085:
086:                // Por si acaso hubiera elementos seleccionados en el modelo usado por el usuario
087:                ListSelectionModel selectionModel = getListSelectionModel();
088:                selectionModel.clearSelection();
089:            }
090:
091:            public void insertElementUpdateModel(int index) {
092:                insertElementUpdateModel(index, 1);
093:            }
094:
095:            public void insertElementUpdateModel(int index, int length) {
096:                if (length == 0)
097:                    return;
098:
099:                this .size += length;
100:
101:                ListSelectionModel selectionModel = getListSelectionModel();
102:
103:                /*        
104:                 boolean oldAdjusting = selectionModel.getValueIsAdjusting();
105:                 selectionModel.setValueIsAdjusting(true); // Evita procesar muchos eventos para procesar al final todos en uno        
106:                 try
107:                 {
108:                 */
109:                selectionModel.insertIndexInterval(index, length, true);
110:                // Por defecto pone los nuevos índices seleccionados en ciertos casos
111:                // (cuando hay selección múltiple) el caso es que no genera evento o si lo genera no incluye los índices de los nuevos elementos seleccionados
112:
113:                // Se ha detectado el extraño caso de selection model vacío (anteriormente con algo) 
114:                // pero que al añadir un primer elemento (index = 0, length = 0) el caso es que genera
115:                // un evento con índices 0 y 1 existiendo un único elemento en teoría (size es 1).
116:                /*
117:                 if (selectionModel.isSelectedIndex(index))
118:                 {
119:                 // Fueron seleccionados, los quitamos, no queremos que el nuevo elemento añadido esté seleccionado:        
120:                 selectionModel.removeSelectionInterval(index,index + length - 1);
121:                 }
122:                 */
123:                /*            
124:                 }
125:                 finally
126:                 {
127:                 selectionModel.setValueIsAdjusting(false); // Envía un evento con todos los cambios
128:                 selectionModel.setValueIsAdjusting(oldAdjusting); // Restaura                        
129:                 }
130:                 */
131:            }
132:
133:            public void removeRangeUpdateModel(int fromIndex, int toIndex) {
134:                getListSelectionModel().removeIndexInterval(fromIndex, toIndex);
135:                this .size -= toIndex - fromIndex + 1;
136:            }
137:
138:            public void removeAllUpdateModel() {
139:                int last = this .size - 1;
140:                if (last >= 0)
141:                    removeRangeUpdateModel(0, last);
142:                this .size = 0; // redundante pero para que quede claro
143:            }
144:
145:            public void changeSelectionModel(int index, boolean toggle,
146:                    boolean extend, boolean selected) {
147:                ListSelectionModel sm = getListSelectionModel();
148:
149:                // Es como está en JTable (1.4/1.5) y similar a http://developer.classpath.org/doc/javax/swing/JTable-source.html#line.4945   
150:                // pero el comportamiento también es válido para los List (con selección múltiple sobre todo)
151:                if (extend && toggle) // shift+ctrl-click
152:                {
153:                    sm.setAnchorSelectionIndex(index);
154:                } else if (toggle) // ctrl-click
155:                {
156:                    if (selected)
157:                        sm.removeSelectionInterval(index, index);
158:                    else
159:                        addSelectionIntervalWithContigous(index, index);
160:                    // sm.addSelectionInterval(index, index); Si fuera 1.5 valdría esta llamada pero en 1.4 no funciona bien en SINGLE_INTERVAL_SELECTION
161:                } else if (extend) // shift-click
162:                {
163:                    //sm.setLeadSelectionIndex(index); 
164:                    sm
165:                            .setSelectionInterval(sm.getAnchorSelectionIndex(),
166:                                    index); // Como en JTable 1.5           
167:                    // Si index es menor que el anchor el propio selection model hace el cambio            
168:                } else // click (sin teclas)
169:                {
170:                    sm.setSelectionInterval(index, index);
171:                }
172:            }
173:
174:            public int[] getSelectedIndices() {
175:                ListSelectionModel selModel = getListSelectionModel();
176:
177:                int iMin = selModel.getMinSelectionIndex();
178:                int iMax = selModel.getMaxSelectionIndex();
179:
180:                if ((iMin < 0) || (iMax < 0))
181:                    return new int[0];
182:
183:                int[] indices = new int[1 + (iMax - iMin)];
184:                int n = 0;
185:                for (int i = iMin; i <= iMax; i++) {
186:                    // No todos en el rango están seleccionados
187:                    if (selModel.isSelectedIndex(i)) {
188:                        indices[n] = i;
189:                        n++;
190:                    }
191:                }
192:                int[] indicesFinal = new int[n];
193:                System.arraycopy(indices, 0, indicesFinal, 0, n);
194:                return indicesFinal;
195:            }
196:
197:            public void addSelectionIntervalWithContigous(int first, int end) {
198:                ListSelectionModel selModel = getListSelectionModel();
199:                int mode = selModel.getSelectionMode();
200:                if (mode == ListSelectionModel.SINGLE_INTERVAL_SELECTION) {
201:                    // El DefaultSelectionModel de la JVM 1.4 tiene un penoso error
202:                    // conceptual en addSelectionInterval en el caso SINGLE_INTERVAL_SELECTION,
203:                    // pues en este caso debería ver si hay seleccionados adjacentes para formar
204:                    // un intervalo más grande, pues no es así lo que hace es un setSelectionInterval,
205:                    // según la documentación de setSelectionMode(int) los métodos setSelectionInterval
206:                    // y addSelectionInterval son idénticos en este modo, esto se mantiene en la documentación
207:                    // de la 1.5 pero no es verdad, en la 1.5 forma un nuevo conjunto con los adjacentes.
208:                    // setSelectionInterval que viene a ser una substitución de seleccionados haya lo que haya más que un "añadir".
209:                    // En el caso JVM 1.5 funciona correctamente.
210:                    // Para hacer que funcione en ambos casos extendemos first y end
211:                    // a los contiguos por defecto y por exceso seleccionados.
212:
213:                    for (int i = first - 1; (i >= 0)
214:                            && selModel.isSelectedIndex(i); i--)
215:                        first = i;
216:
217:                    int max = selModel.getMaxSelectionIndex();
218:                    for (int i = end + 1; (i <= max)
219:                            && selModel.isSelectedIndex(i); i++)
220:                        end = i;
221:                }
222:
223:                selModel.addSelectionInterval(first, end);
224:            }
225:
226:            public void setSelectedIndices(int[] indices) {
227:                // Este método es muy útil para procesar el evento "change" en el SELECT en el navegador 
228:                // El <select multiple="multiple"> permite múltiple selección
229:                // pero es el ListSelectionModel el que en última instancia
230:                // debe imponer cuales están seleccionados o no, por ello
231:                // detectamos los cambios que han habido en el cliente y los
232:                // notificamos al selection model que decida.
233:
234:                // NO hacemos setServerUpdatingFromClient(true) porque necesitamos
235:                // que el servidor propague al cliente los que verdaderamente han de quedar seleccionados
236:                // que puede diferir de lo que hay en el cliente cuando se genera el evento        
237:
238:                // Ej. si el selection model está en modo selección única, al seleccionar
239:                // otro en el cliente habrá dos seleccionados, detectaremos que el nuevo item seleccionado
240:                // es el que ha cambiado su estado y notificaremos al selection model,
241:                // el selection model decidirá que el previamente seleccionado debe de dejar de estarlo.        
242:
243:                // Todo esto también evita hacer un clearSelection()
244:                // que mandaría un montón de código al cliente
245:                // Si la selección no cambia no se generan eventos.        
246:
247:                boolean[] newState = new boolean[size];
248:                for (int i = 0; i < indices.length; i++) {
249:                    int index = indices[i];
250:                    newState[index] = true;
251:                }
252:
253:                // Obtenemos la "foto" de los cambiados antes de hacer algún cambio en la selección
254:                // pues el cambio en uno puede cambiar a otros segun el modo de selección
255:                ListSelectionModel selModel = getListSelectionModel();
256:                boolean[] changed = new boolean[size];
257:                for (int i = 0; i < size; i++) {
258:                    boolean selected = newState[i];
259:                    changed[i] = (selected != selModel.isSelectedIndex(i));
260:                }
261:
262:                boolean oldAdjusting = selModel.getValueIsAdjusting();
263:                selModel.setValueIsAdjusting(true); // Evita procesar muchos eventos para procesar al final todos en uno
264:
265:                boolean isSelectionInterval = false;
266:                int first = -1;
267:                int end = -1;
268:                try {
269:                    // Agrupamos los cambios en intervalos pues en el modo de selección
270:                    // de un sólo intervalo necesitamos pasarlo en una sóla llamada
271:                    // pues si pasamos de uno en uno el selecion model detectará huecos que pueden no existir quitando
272:                    // un intervalo existente que podría verdaderamente estar seguido del nuevo             
273:                    for (int i = 0; i < size; i++) {
274:                        if (changed[i]) // Ha cambiado
275:                        {
276:                            boolean selected = newState[i];
277:                            if (selected) {
278:                                if (first >= 0) // hay un intervalo ya abierto                         
279:                                {
280:                                    if (isSelectionInterval) {
281:                                        end = i; // Uno más al intervalo continuo
282:                                    } else {
283:                                        // Cerramos el intervalo de no seleccionados primero
284:                                        selModel.removeSelectionInterval(first,
285:                                                end);
286:                                        // Iniciamos el nuevo intervalo de seleccionados
287:                                        isSelectionInterval = true;
288:                                        first = i;
289:                                        end = i;
290:                                    }
291:                                } else {
292:                                    // Iniciamos el nuevo intervalo de seleccionados
293:                                    isSelectionInterval = true;
294:                                    first = i;
295:                                    end = i;
296:                                }
297:                            } else {
298:                                if (first >= 0) // hay un intervalo ya abierto                         
299:                                {
300:                                    if (!isSelectionInterval) {
301:                                        end = i; // Uno más al intervalo continuo
302:                                    } else {
303:                                        // Cerramos el intervalo de seleccionados primero 
304:                                        addSelectionIntervalWithContigous(
305:                                                first, end);
306:                                        // Iniciamos el nuevo intervalo de NO seleccionados
307:                                        isSelectionInterval = false;
308:                                        first = i;
309:                                        end = i;
310:                                    }
311:                                } else {
312:                                    // Iniciamos el nuevo intervalo de NO seleccionados
313:                                    isSelectionInterval = false;
314:                                    first = i;
315:                                    end = i;
316:                                }
317:                            }
318:                        } else // No ha cambiado
319:                        {
320:                            // Este elemento no ha cambiado por tanto 
321:                            // no vamos ni añadir ni a quitar de la selección
322:                            // por ello hemos de cerrar el intervalo que haya pendiente pues ya no hay continuidad
323:                            if (first >= 0) // Hay un intervalo pendiente
324:                            {
325:                                if (isSelectionInterval)
326:                                    addSelectionIntervalWithContigous(first,
327:                                            end);
328:                                else
329:                                    selModel
330:                                            .removeSelectionInterval(first, end);
331:                            }
332:                            first = -1;
333:                            end = -1;
334:                        }
335:                    } // Fin del for
336:
337:                    // Cerramos el intervalo que haya quedado pendiente de añadir/quitar
338:                    if (first >= 0) // Hay un intervalo pendiente
339:                    {
340:                        if (isSelectionInterval)
341:                            addSelectionIntervalWithContigous(first, end);
342:                        else
343:                            selModel.removeSelectionInterval(first, end);
344:                    }
345:                } finally {
346:                    selModel.setValueIsAdjusting(false); // Envía un evento con todos los cambios
347:                    selModel.setValueIsAdjusting(oldAdjusting); // Restaura            
348:                }
349:            }
350:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.