001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.settings.support;
017    
018    import javax.swing.JTree;
019    
020    import org.springframework.richclient.settings.Settings;
021    import org.springframework.util.Assert;
022    import org.springframework.util.StringUtils;
023    
024    /**
025     * @author Peter De Bruycker
026     */
027    public class TreeMemento implements Memento {
028    
029            private static final String EXPANSION_STATE = "expansionState";
030    
031            private static final String SELECTED_ROWS = "selectedRows";
032    
033            private String key;
034    
035            private JTree tree;
036    
037            public TreeMemento(JTree tree) {
038                    this(tree, null);
039            }
040    
041            public TreeMemento(JTree tree, String key) {
042                    Assert.notNull(tree, "tree cannot be null");
043                    Assert.isTrue(StringUtils.hasText(key) || StringUtils.hasText(tree.getName()),
044                                    "Key is empty or tree has no name");
045    
046                    if (!StringUtils.hasText(key)) {
047                            key = tree.getName();
048                    }
049    
050                    this.tree = tree;
051                    this.key = key;
052            }
053    
054            public JTree getTree() {
055                    return tree;
056            }
057    
058            public String getKey() {
059                    return key;
060            }
061    
062            public void restoreState(Settings settings) {
063                    restoreExpansionState(settings);
064                    restoreSelectionState(settings);
065            }
066    
067            public void saveState(Settings settings) {
068                    saveExpansionState(settings);
069                    saveSelectionState(settings);
070            }
071    
072            void saveExpansionState(Settings settings) {
073                    int rowCount = tree.getRowCount();
074                    StringBuffer sb = new StringBuffer();
075                    for (int i = 0; i < rowCount; i++) {
076                            sb.append(tree.isExpanded(i) ? 1 : 0);
077                            if (i < rowCount - 1) {
078                                    sb.append(",");
079                            }
080                    }
081                    settings.setString(key + "." + EXPANSION_STATE, sb.toString());
082            }
083    
084            void restoreExpansionState(Settings settings) {
085                    String expansionKey = key + "." + EXPANSION_STATE;
086                    if (settings.contains(expansionKey)) {
087                            String[] states = settings.getString(expansionKey).split(",");
088    
089                            try {
090                                    int[] expansionStates = ArrayUtil.toIntArray(states);
091    
092                                    for (int i = 0; i < expansionStates.length; i++) {
093                                            if (expansionStates[i] == 1) {
094                                                    tree.expandRow(i);
095                                            }
096                                    }
097                            } catch (IllegalArgumentException e) {
098                                    // TODO log this
099                            }
100                    }
101            }
102    
103            /**
104             * TODO store lead and anchor selection
105             */
106            void saveSelectionState(Settings settings) {
107                    String selectionKey = key + "." + SELECTED_ROWS;
108                    if (settings.contains(selectionKey)) {
109                            settings.remove(selectionKey);
110                    }
111    
112                    if (tree.getSelectionCount() > 0) {
113                            String selectionString = ArrayUtil.asIntervalString(tree.getSelectionRows());
114                            if (selectionString.length() > 0) {
115                                    settings.setString(selectionKey, selectionString);
116                            }
117                    }
118            }
119    
120            void restoreSelectionState(Settings settings) {
121                    tree.getSelectionModel().clearSelection();
122    
123                    String selectionKey = key + "." + SELECTED_ROWS;
124                    if (settings.contains(selectionKey)) {
125                            String selection = settings.getString(selectionKey);
126                            if (StringUtils.hasText(selection)) {
127                                    String[] parts = selection.split(",");
128                                    for (int i = 0; i < parts.length; i++) {
129                                            if (parts[i].indexOf('-') >= 0) {
130                                                    String[] tmp = parts[i].split("-");
131                                                    tree.addSelectionInterval(Integer.parseInt(tmp[0]), Integer.parseInt(tmp[1]));
132                                            } else {
133                                                    int index = Integer.parseInt(parts[i]);
134                                                    tree.addSelectionRow(index);
135                                            }
136                                    }
137                            }
138                    }
139            }
140    }