Source Code Cross Referenced for TreeSelectionModelMgrImpl.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 org.itsnat.comp.ui.ItsNatTreeUI;
017:        import org.itsnat.core.ItsNatException;
018:        import javax.swing.DefaultListSelectionModel;
019:        import javax.swing.ListSelectionModel;
020:        import javax.swing.event.ListSelectionEvent;
021:        import javax.swing.event.ListSelectionListener;
022:        import javax.swing.event.TreeSelectionEvent;
023:        import javax.swing.event.TreeSelectionListener;
024:        import javax.swing.tree.TreeModel;
025:        import javax.swing.tree.TreePath;
026:        import javax.swing.tree.TreeSelectionModel;
027:
028:        /**
029:         * El modelo de selección de los nodos de un árbol es como una lista
030:         * considerando los nodos como filas (rows)
031:         *
032:         * @author jmarranz
033:         */
034:        public class TreeSelectionModelMgrImpl implements 
035:                TreeSelectionListener, ListSelectionListener {
036:            protected ItsNatTreeImpl tree;
037:            protected TreeSelectionModel treeSelection;
038:            protected ListSelectionModelMgrImpl listSelMgr = new ListSelectionModelMgrImpl(
039:                    new DefaultListSelectionModel()); // Es interno no debe usarse fuera de la clase
040:            protected boolean synchTreeModelFromListModel = false; // temporalmente puede estar a true pero debe devolverse a false
041:            protected boolean synchListModelFromTreeModel = true; // idem pero al revés  
042:            protected int currentMode = -1;
043:
044:            /**
045:             * Creates a new instance of TreeSelectionModelMgrImpl
046:             */
047:            public TreeSelectionModelMgrImpl(ItsNatTreeImpl tree,
048:                    TreeSelectionModel treeSelection) {
049:                if (treeSelection == null)
050:                    treeSelection = EmptyTreeSelectionModelImpl.SINGLETON;
051:
052:                this .tree = tree;
053:                this .treeSelection = treeSelection;
054:
055:                treeSelection.addTreeSelectionListener(this );
056:                listSelMgr.getListSelectionModel().addListSelectionListener(
057:                        this );
058:
059:                syncSelectionMode();
060:
061:                //syncSelectionModelWithDataModel();
062:            }
063:
064:            public void dispose() {
065:                treeSelection.removeTreeSelectionListener(this );
066:                listSelMgr.dispose();
067:            }
068:
069:            public TreeSelectionModel getTreeSelectionModel() {
070:                return treeSelection;
071:            }
072:
073:            private ListSelectionModelMgrImpl getListSelectionModelMgr() {
074:                // NO usar el ListSelectionModel fuera de esta clase
075:
076:                syncSelectionMode();
077:
078:                return listSelMgr;
079:            }
080:
081:            private void syncSelectionMode() {
082:                int newMode = treeSelection.getSelectionMode();
083:                if (currentMode != newMode) {
084:                    this .currentMode = newMode;
085:                    int newListMode;
086:                    switch (newMode) {
087:                    case TreeSelectionModel.SINGLE_TREE_SELECTION:
088:                        newListMode = ListSelectionModel.SINGLE_SELECTION;
089:                        break;
090:                    case TreeSelectionModel.CONTIGUOUS_TREE_SELECTION:
091:                        newListMode = ListSelectionModel.SINGLE_INTERVAL_SELECTION;
092:                        break;
093:                    case TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION:
094:                        newListMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
095:                        break;
096:                    default:
097:                        throw new ItsNatException("INTERNAL ERROR");
098:                    }
099:
100:                    listSelMgr.getListSelectionModel().setSelectionMode(
101:                            newListMode);
102:                }
103:            }
104:
105:            public void syncSelectionModelWithDataModel() {
106:                removeAllUpdateModel();
107:
108:                int size = tree.getRowCount();
109:                // synchTreeModelFromListModel debe ser false  
110:
111:                getListSelectionModelMgr().syncWithDataModel(size);
112:            }
113:
114:            public boolean isRowSelected(int row) {
115:                return getListSelectionModelMgr().getListSelectionModel()
116:                        .isSelectedIndex(row);
117:            }
118:
119:            public void changeSelectionModel(int row, boolean toggle,
120:                    boolean extend, boolean selected) {
121:                // A través del list model actualizaremos después el tree model
122:
123:                // El comportamiento de la selección en un JList/JTable es básicamente
124:                // el mismo que en un JTree:
125:                // BasicTreeUI.selectPathForEvent(TreePath path, MouseEvent event)
126:                this .synchTreeModelFromListModel = true;
127:                // los cambios se notificarán a través de eventos
128:                getListSelectionModelMgr().changeSelectionModel(row, toggle,
129:                        extend, selected);
130:                this .synchTreeModelFromListModel = false;
131:            }
132:
133:            public void valueChanged(TreeSelectionEvent e) {
134:                if (tree.isExpandsSelectedPaths()) {
135:                    TreePath[] paths = e.getPaths();
136:                    for (int i = 0; i < paths.length; i++)
137:                        tree.expandPath(paths[i]);
138:                }
139:
140:                // Actualizar el list sel. model con los cambios en el modelo      
141:                if (!synchListModelFromTreeModel)
142:                    return;
143:
144:                boolean oldState = synchTreeModelFromListModel;
145:                this .synchTreeModelFromListModel = false; // por si acaso (actualización recursiva al cambiar el list selection)     
146:
147:                ListSelectionModelMgrImpl listSelModelMgr = getListSelectionModelMgr();
148:                ListSelectionModel listSelection = listSelModelMgr
149:                        .getListSelectionModel();
150:
151:                TreePath[] paths = e.getPaths();
152:                int[] rows = tree.getRowsForPaths(paths);
153:
154:                boolean oldAdjusting = listSelection.getValueIsAdjusting();
155:                listSelection.setValueIsAdjusting(true); // Evita procesar muchos eventos para procesar al final todos en uno        
156:                try {
157:                    for (int i = 0; i < paths.length; i++) {
158:                        int row = rows[i];
159:
160:                        if (row >= 0) {
161:                            if (e.isAddedPath(i)) // es más eficiente que pasar el TreePath 
162:                            {
163:                                listSelModelMgr
164:                                        .addSelectionIntervalWithContigous(row,
165:                                                row);
166:                                //listSelection.addSelectionInterval(row,row);
167:                            } else {
168:                                listSelection.removeSelectionInterval(row, row);
169:                            }
170:                        } else // No se visualiza por tanto no puede estar seleccionado
171:                        {
172:                            throw new ItsNatException(
173:                                    "A hidden node can not be selected/unselected");
174:                        }
175:                    }
176:                } finally {
177:                    listSelection.setValueIsAdjusting(false); // Envía un único evento con todos los cambios
178:                    listSelection.setValueIsAdjusting(oldAdjusting); // Restaura            
179:                }
180:
181:                this .synchTreeModelFromListModel = oldState;
182:            }
183:
184:            public void valueChanged(ListSelectionEvent e) {
185:                // Actualizar el tree sel. model con los cambios
186:                if (!synchTreeModelFromListModel)
187:                    return;
188:
189:                ListSelectionModel listSelection = getListSelectionModelMgr()
190:                        .getListSelectionModel();
191:                if (listSelection.getValueIsAdjusting())
192:                    return;
193:
194:                boolean oldState = synchListModelFromTreeModel;
195:                this .synchListModelFromTreeModel = false; // por si acaso (actualización recursiva al cambiar el tree selection)     
196:
197:                if (listSelection.isSelectionEmpty())
198:                    treeSelection.clearSelection();
199:                else {
200:                    if (treeSelection.getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) {
201:                        // En este caso no podemos ir uno a uno porque al quitar uno podemos
202:                        // quitar otro recién añadido al romperse temporalmente la continuidad (cuando un posible siguiente también será removido)
203:                        if (listSelection.isSelectionEmpty())
204:                            treeSelection.clearSelection();
205:                        else {
206:                            int first = listSelection.getMinSelectionIndex();
207:                            int last = listSelection.getMaxSelectionIndex();
208:                            TreePath[] paths = new TreePath[last - first + 1];
209:                            for (int i = first; i <= last; i++) {
210:                                TreePath path = tree.getTreePathForRow(i);
211:                                paths[i - first] = path;
212:                            }
213:                            treeSelection.setSelectionPaths(paths); // Así si apenas cambia uno será lo suficientemente inteligente para notificar sólo ese cambio
214:                        }
215:                    } else {
216:                        // Resto de los casos (single, multiple no continuo)
217:                        int firstRow = e.getFirstIndex();
218:                        int lastRow = e.getLastIndex();
219:                        for (int i = firstRow; i <= lastRow; i++) {
220:                            TreePath path = tree.getTreePathForRow(i);
221:                            // No debe ser null path, pues sería un signo de desincronización
222:                            boolean selected = listSelection.isSelectedIndex(i);
223:                            if (selected)
224:                                treeSelection.addSelectionPath(path);
225:                            else
226:                                treeSelection.removeSelectionPath(path);
227:                        }
228:                    }
229:                }
230:
231:                this .synchListModelFromTreeModel = oldState;
232:            }
233:
234:            public void insertElementUpdateModel(int i, TreePath parentPath) {
235:                TreePath path = tree.toTreePath(i, parentPath);
236:                insertElementUpdateModel(path);
237:            }
238:
239:            public void insertElementUpdateModel(TreePath path) {
240:                int row = tree.getRowForPath(path);
241:                if (row >= 0) {
242:                    getListSelectionModelMgr().insertElementUpdateModel(row);
243:                    // Ahora los hijos del nuevo nodo
244:                    insertAllChildElementsUpdateModel(path);
245:                }
246:            }
247:
248:            public void insertAllChildElementsUpdateModel(TreePath parentPath) {
249:                Object parentNode = parentPath.getLastPathComponent();
250:                TreeModel dataModel = tree.getTreeModel();
251:                int len = dataModel.getChildCount(parentNode);
252:                for (int i = 0; i < len; i++) {
253:                    Object childNode = dataModel.getChild(parentNode, i);
254:                    //TreePath childPath = parentPath.pathByAddingChild(childNode);
255:                    insertElementUpdateModel(i, parentPath);
256:                }
257:            }
258:
259:            public void removeElementUpdateModel(int i, Object childNode,
260:                    TreePath parentPath) {
261:                int parentRow = tree.getRowForPath(parentPath);
262:                if (parentRow == -1)
263:                    return;
264:                TreePath childPath = parentPath.pathByAddingChild(childNode);
265:                int rows = tree.getRowCountSubTree(childPath);
266:                if (rows == 0)
267:                    return; // Si es 0 es que el nodo que se borra no se ve
268:
269:                int rowStart = parentRow + i + 1;
270:                int rowEnd = rowStart + rows - 1; // quitamos 1 pues se incluye el propio nodo en la cuenta de getRowCountSubTree()            
271:
272:                removeRangeUpdateModel(rowStart, rowEnd);
273:            }
274:
275:            private void removeRangeUpdateModel(int rowStart, int rowEnd) {
276:                getListSelectionModelMgr().removeRangeUpdateModel(rowStart,
277:                        rowEnd);
278:            }
279:
280:            public void removeAllChildElementsUpdateModel(TreePath path) {
281:                // Esta es la situación: los nodos por debajo de path
282:                // han cambiado profundamente, puede que esté vacío o tenga
283:                // nodos que no tienen nada que ver con lo que el selection
284:                // recordaba, por lo que no tiene sentido 
285:                // recorrerlos, tenemos que quitar las rows que ocupaban los antiguos
286:                // nodos como si path no tuviera hijos.
287:                // Lo que hacemos es averiguar el row del nodo anterior
288:                // y el posterior al path y así sabemos cuantos rows
289:                // ocupaban tanto el propio path como los hijos
290:
291:                if (path == null) // Es el caso del propio root
292:                {
293:                    removeRootUpdateModel();
294:                } else {
295:                    TreePath prevPath = tree.getPreviousPath(path);
296:
297:                    int rowStart, rowEnd;
298:                    if (prevPath == null) // es el root pues no hay hijo anterior ni padre (no hay nodo "antes")
299:                    {
300:                        int rootRow = tree.getRowForPath(path);
301:                        if (rootRow == -1)
302:                            return; // No es visible
303:                        rowStart = 1;
304:                        int rows = getListSelectionModelMgr().getSize();
305:                        rowEnd = rows - 1;
306:                        if (rowStart > rowEnd) // no tuvo hijos
307:                            return;
308:                    } else {
309:                        int rowPrev = tree.getRowForPath(prevPath);
310:                        if (rowPrev == -1) // Si el nodo anterior o el padre no tiene row (no se ve) el siguiente o el hijo tampoco, nada que hacer
311:                            return;
312:                        rowStart = rowPrev + 2; // pues el propio nodo no hay que quitarlo
313:
314:                        TreePath nextPath = tree.getNextPath(path, false); // los hijos no se incluyen
315:                        if (nextPath != null) {
316:                            int rowNext = tree.getRowForPath(nextPath);
317:                            // En este contexto rowNext no puede ser -1 aunque sea el siguiente del padre (o del padre del padre etc) pues path tiene row por tanto es visible (pensar)
318:                            rowEnd = rowNext - 1;
319:                        } else // Es el último, pero pudo tener hijos los cuales cuentan como rows
320:                        {
321:                            int rows = getListSelectionModelMgr().getSize();
322:                            rowEnd = rows - 1;
323:                            if (rowStart > rowEnd) // no tuvo hijos
324:                                return;
325:                        }
326:                    }
327:
328:                    removeRangeUpdateModel(rowStart, rowEnd);
329:                }
330:            }
331:
332:            public void removeRootUpdateModel() {
333:                boolean syncTreeOld = this .synchTreeModelFromListModel;
334:                this .synchTreeModelFromListModel = false;
335:
336:                getListSelectionModelMgr().removeAllUpdateModel();
337:
338:                this .synchTreeModelFromListModel = syncTreeOld;
339:
340:                boolean syncListOld = this .synchListModelFromTreeModel;
341:                this .synchListModelFromTreeModel = false;
342:
343:                treeSelection.clearSelection();
344:
345:                this .synchListModelFromTreeModel = syncListOld;
346:            }
347:
348:            public void removeAllUpdateModel() {
349:                // getListSelectionModelMgr().removeAllUpdateModel();    
350:                treeSelection.clearSelection(); // Yo creo que sobra pero por si acaso
351:            }
352:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.