1 23 24 package org.netbeans.swing.tabcontrol.plaf; 25 26 import java.util.ArrayList ; 27 import javax.swing.event.ChangeListener ; 28 import org.netbeans.swing.tabcontrol.TabDataModel; 29 import org.netbeans.swing.tabcontrol.event.ArrayDiff; 30 import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent; 31 import org.netbeans.swing.tabcontrol.event.ComplexListDataListener; 32 import org.netbeans.swing.tabcontrol.event.VeryComplexListDataEvent; 33 34 import javax.swing.*; 35 import javax.swing.event.ChangeEvent ; 36 import javax.swing.event.ListDataEvent ; 37 import java.util.Iterator ; 38 import java.util.Set ; 39 40 48 final class DefaultTabSelectionModel implements SingleSelectionModel, 49 ComplexListDataListener { 50 TabDataModel dataModel; 51 int sel = -1; 52 55 private transient ArrayList <ChangeListener > changeListenerList; 56 57 60 public DefaultTabSelectionModel(TabDataModel tdm) { 61 dataModel = tdm; 62 attach(); 63 } 64 65 public void attach() { 66 dataModel.addComplexListDataListener(this); 67 } 68 69 public void detach() { 70 dataModel.removeComplexListDataListener(this); 71 } 72 73 public void clearSelection() { 74 sel = -1; 75 fireStateChanged(); 76 } 77 78 public int getSelectedIndex() { 79 return sel; 80 } 81 82 public boolean isSelected() { 83 return sel != -1; 84 } 85 86 public void setSelectedIndex(int index) { 87 if (index != sel) { 88 int oldIndex = sel; 89 if ((index < -1) || (index >= dataModel.size())) { 90 throw new IllegalArgumentException ("Selected index set to " 91 + index 92 + " but model size is only " + dataModel.size()); 93 } 94 sel = index; 95 fireStateChanged(); 96 } 97 } 98 99 private void adjustSelectionForEvent(ListDataEvent e) { 100 if (e.getType() == e.CONTENTS_CHANGED || sel == -1) { 101 return; 102 } 103 int start = e.getIndex0(); 104 int end = e.getIndex1() + 1; 105 if (e.getType() == e.INTERVAL_REMOVED) { 106 if (sel < start) { 107 return; 108 } else { 109 if (sel >= start) { 110 if (sel > end) { 111 sel -= end - start; 112 } else { 113 sel = start; 114 if (sel >= dataModel.size()) { 115 sel = dataModel.size() - 1; 116 } 117 } 118 fireStateChanged(); 119 } 120 } 121 } else { 122 if (sel < start) { 123 return; 125 } 126 if (sel >= start) { 127 if (end - 1 == start) { 128 sel++; 129 } else if (sel < end) { 130 sel = (end + (sel - start)) - 1; 131 } else { 132 sel += (end - start) - 1; 133 } 134 fireStateChanged(); 135 } 136 } 137 } 138 139 public void contentsChanged(ListDataEvent e) { 140 adjustSelectionForEvent(e); 141 } 142 143 public void intervalAdded(ListDataEvent e) { 144 adjustSelectionForEvent(e); 145 } 146 147 public void intervalRemoved(ListDataEvent e) { 148 adjustSelectionForEvent(e); 149 } 150 151 public void indicesAdded(ComplexListDataEvent e) { 152 if (sel < 0) return; 153 int[] indices = e.getIndices(); 154 java.util.Arrays.sort(indices); 155 int offset = 0; 156 for (int i = 0; i < indices.length; i++) { 157 if (sel >= indices[i]) { 158 offset++; 159 } else { 160 break; 161 } 162 } 163 if (offset > 0) { 164 sel += offset; 165 fireStateChanged(); 166 } 167 } 168 169 public void indicesRemoved(ComplexListDataEvent e) { 170 if (sel < 0) return; 171 int[] indices = e.getIndices(); 172 java.util.Arrays.sort(indices); 173 int offset = -1; 174 for (int i = 0; i < indices.length; i++) { 175 if (sel > indices[i]) { 176 offset--; 177 } else { 178 break; 179 } 180 } 181 if (sel == dataModel.size()) { 182 sel -= 1; 183 fireStateChanged(); 184 return; 185 } 186 if (dataModel.size() == 0) { 187 sel = -1; 188 fireStateChanged(); 189 } else if (offset != 0) { 190 sel = Math.max( -1, Math.min (sel + offset, -1)); 191 fireStateChanged(); 192 } 193 } 194 195 public void indicesChanged(ComplexListDataEvent e) { 196 if (sel < 0) return; 197 if (e instanceof VeryComplexListDataEvent) { 199 ArrayDiff dif = ((VeryComplexListDataEvent) e).getDiff(); 200 201 boolean changed = false; 202 203 if (dif == null) { 204 return; 206 } 207 208 Set <Integer > deleted = dif.getDeletedIndices(); 210 Set <Integer > added = dif.getAddedIndices(); 211 212 Integer idx = new Integer (getSelectedIndex()); 214 215 if (dataModel.size() == 0) { 217 sel = -1; 218 fireStateChanged(); 219 return; 220 } 221 222 Iterator <Integer > i = deleted.iterator(); 226 int offset = 0; 227 Integer curr; 228 while (i.hasNext()) { 229 curr = i.next(); 230 if (curr.compareTo(idx) <= 0) { 231 offset++; 232 } 233 } 234 235 i = added.iterator(); 239 while (i.hasNext()) { 240 curr = i.next(); 241 if (curr.compareTo(idx) >= 0) { 242 offset--; 243 } 244 } 245 246 sel -= offset; 247 if (sel < 0) { 248 sel = dataModel.size() > 0 ? 0 : -1; 251 } 252 253 if (sel >= dataModel.size()) { 256 sel = dataModel.size() - 1; 257 } 258 259 if (offset != 0) { 260 fireStateChanged(); 261 } 262 } 263 } 265 266 public synchronized void addChangeListener(ChangeListener listener) { 267 if (changeListenerList == null) { 268 changeListenerList = new ArrayList <ChangeListener >(); 269 } 270 changeListenerList.add(listener); 271 } 272 273 public synchronized void removeChangeListener(ChangeListener listener) { 274 if (changeListenerList != null) { 275 changeListenerList.remove(listener); 276 } 277 } 278 279 ChangeEvent ce = new ChangeEvent (this); 280 281 private void fireStateChanged() { 282 ArrayList <ChangeListener > list; 283 synchronized (this) { 284 if (changeListenerList == null) { 285 return; 286 } 287 list = new ArrayList <ChangeListener >( changeListenerList ); 288 } 289 for( ChangeListener l : list ) { 290 l.stateChanged(ce); 291 } 292 } 293 294 } 295 | Popular Tags |