1 19 20 package org.netbeans.modules.editor.lib2; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyChangeSupport ; 25 import javax.swing.text.Document ; 26 import javax.swing.text.JTextComponent ; 27 import javax.swing.text.BadLocationException ; 28 import javax.swing.text.Caret ; 29 import javax.swing.text.Position ; 30 31 39 public class DocumentsJumpList { 40 41 44 private static final int MAX_SIZE = 50; 45 46 49 private static final int CHECK_COUNT = 10; 50 51 52 private static Entry currentEntry; 53 54 private static int checkCnt; 55 private static final PropertyChangeSupport support = new PropertyChangeSupport (DocumentsJumpList.class);; 56 private static boolean dotAtCurrentEntry = false; 57 58 private static PropertyChangeListener registryListener = new PropertyChangeListener () { 59 public void propertyChange(PropertyChangeEvent e) { 60 support.firePropertyChange(null, null, null); 61 } 62 }; 63 64 static { 65 DocumentsRegistry.addPropertyChangeListener(registryListener); 66 } 67 68 public static void addPropertyChangeListener(PropertyChangeListener listener) { 69 support.addPropertyChangeListener(listener); 70 } 71 72 public static void removePropertyChangeListener(PropertyChangeListener listener) { 73 support.removePropertyChangeListener(listener); 74 } 75 76 public static void dotMoved(JTextComponent c, int offset) { 77 if (dotAtCurrentEntry && currentEntry != null && (currentEntry.getComponent() != c || currentEntry.getPosition() != offset)) { 78 support.firePropertyChange(null, null, null); 79 dotAtCurrentEntry = false; 80 } else { 81 dotAtCurrentEntry = currentEntry != null && currentEntry.getComponent() == c && currentEntry.getPosition() == offset; 82 } 83 } 84 85 public static void checkAddEntry() { 86 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 87 if (c != null) { 88 checkAddEntry(c, c.getCaret().getDot()); 89 } 90 } 91 92 public static void checkAddEntry(JTextComponent c) { 93 checkAddEntry(c, c.getCaret().getDot()); 94 } 95 96 public static void checkAddEntry(JTextComponent c, int pos) { 97 if (currentEntry == null 98 || currentEntry.getComponent() != c 99 || currentEntry.getPosition() != pos 100 ) { 101 addEntry(c, pos); 102 } 103 } 104 105 public static void addEntry(JTextComponent c, int pos) { 106 try { 107 Entry e = new Entry(c, pos, currentEntry); 108 currentEntry = e; 109 if (++checkCnt >= CHECK_COUNT) { sizeCheck(); 111 } 112 dotAtCurrentEntry = true; 113 } catch (BadLocationException e) { 114 } 116 } 117 118 122 public static void jumpPrev(JTextComponent c) { 123 int dotPos = c.getCaret().getDot(); 124 if (currentEntry != null) { 125 while (true) { 126 int entryPos = currentEntry.getPosition(); 127 JTextComponent entryComp = currentEntry.getComponent(); 128 if (entryComp != null && (entryComp != c || (entryPos >= 0 && entryPos != dotPos))) { 129 if (currentEntry.setDot()) { 130 support.firePropertyChange(null, null, null); 131 break; 132 } 133 } 134 if (currentEntry.prev != null) { currentEntry = currentEntry.prev; 136 } else { 137 break; } 139 } 140 } 141 } 142 143 public static boolean hasPrev() { 144 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 145 Caret caret = c != null ? c.getCaret() : null; 146 if (caret != null) { 147 Entry e = currentEntry; 148 if (e != null) { 149 while (true) { 150 int entryPos = e.getPosition(); 151 JTextComponent entryComp = e.getComponent(); 152 int dotPos = caret.getDot(); 153 if (entryComp != null && (entryComp != c || (entryPos >= 0 && entryPos != dotPos))) { 154 if (entryPos >= 0 && entryPos <= entryComp.getDocument().getLength()) { 155 return true; 156 } 157 } 158 if (e.prev != null) { e = e.prev; 160 } else { 161 break; } 163 } 164 } 165 } 166 return false; 167 } 168 169 173 public static void jumpNext(JTextComponent c) { 174 int dotPos = c.getCaret().getDot(); 175 if (currentEntry != null) 176 currentEntry = currentEntry.next; 177 if (currentEntry != null) { 178 while (true) { 179 int entryPos = currentEntry.getPosition(); 180 JTextComponent entryComp = currentEntry.getComponent(); 181 if (entryComp != null && (entryComp != c || (entryPos >= 0 && entryPos != dotPos))) { 182 if (currentEntry.setDot()) { 183 support.firePropertyChange(null, null, null); 184 break; 185 } 186 } 187 if (currentEntry.next != null) { currentEntry = currentEntry.next; 189 } else { 190 break; } 192 } 193 } 194 } 195 196 public static boolean hasNext() { 197 JTextComponent c = DocumentsRegistry.getMostActiveComponent(); 198 if (c != null) { 199 int dotPos = c.getCaret().getDot(); 200 Entry e = currentEntry != null ? currentEntry.next : currentEntry; 201 if (e != null) { 202 while (true) { 203 int entryPos = e.getPosition(); 204 JTextComponent entryComp = e.getComponent(); 205 if (entryComp != null && (entryComp != c || (entryPos >= 0 && entryPos != dotPos))) { 206 if (entryPos >= 0 && entryPos <= entryComp.getDocument().getLength()) { 207 return true; 208 } 209 } 210 if (e.next!= null) { e = e.next; 212 } else { 213 break; } 215 } 216 } 217 } 218 return false; 219 } 220 221 225 public static void jumpPrevComponent(JTextComponent c) { 226 if (currentEntry != null) { 227 while (true) { 228 JTextComponent entryComp = currentEntry.getComponent(); 229 if (entryComp != null && entryComp != c) { 230 if (currentEntry.setDot()) { 231 break; 232 } 233 } 234 if (currentEntry.prev != null) { currentEntry = currentEntry.prev; 236 } else { 237 break; } 239 } 240 } 241 } 242 243 247 public static void jumpNextComponent(JTextComponent c) { 248 if (currentEntry != null) { 249 while (true) { 250 JTextComponent entryComp = currentEntry.getComponent(); 251 if (entryComp != null && entryComp != c) { 252 if (currentEntry.setDot()) { 253 break; 254 } 255 } 256 if (currentEntry.next != null) { currentEntry = currentEntry.next; 258 } else { 259 break; } 261 } 262 } 263 } 264 265 public static String dump() { 266 StringBuffer sb = new StringBuffer (); 267 int i = 0; 268 Entry e = currentEntry; 269 if (e != null) { 270 while (true) { 271 if (e.prev != null) { 272 e = e.prev; 273 i--; 274 } else { 275 break; 276 } 277 } 278 279 while (e != null) { 280 JTextComponent comp = e.getComponent(); 281 String docStr = (comp != null) ? 282 (String )comp.getDocument().getProperty(Document.TitleProperty) 283 : "<Invalid document>"; if (docStr == null) { docStr = "Untitled"; } 287 sb.append("[" + i++ + "]=" + docStr + ", " + e.getPosition() + "\n"); e = e.next; 289 } 290 } else { sb.append("Empty list"); } 293 return sb.toString(); 294 } 295 296 private static void sizeCheck() { 297 int cnt = MAX_SIZE; 298 Entry e = currentEntry; 299 while (e != null && cnt > 0) { 300 e = e.prev; 301 cnt--; } 303 if (e != null) { e.makeFirst(); 305 } 306 } 307 308 public static class Entry { 309 310 311 private int componentID; 312 313 314 private Position pos; 315 316 317 private Entry prev; 318 319 320 private Entry next; 321 322 private Entry(JTextComponent component, int offset, Entry last) throws BadLocationException { 323 componentID = DocumentsRegistry.getID(component); 324 pos = component.getDocument().createPosition(offset); 327 if (last != null) { last.next = this; 329 this.prev = last; 330 } 331 } 332 333 public int getPosition() { 334 return pos.getOffset(); 335 } 336 337 public JTextComponent getComponent() { 338 return DocumentsRegistry.getComponent(componentID); 339 } 340 341 345 public boolean setDot() { 346 JTextComponent c = getComponent(); 347 if (c != null) { 348 if (DocumentsRegistry.getMostActiveComponent() != c) { 349 350 ComponentUtils.requestFocus(c); DocumentsRegistry.activate(c); 352 } 353 354 int pos = getPosition(); 355 if (pos >= 0 && pos <= c.getDocument().getLength()) { 356 c.getCaret().setDot(pos); return true; 358 } 359 } 360 return false; 361 } 362 363 void makeLast() { 364 if (next != null) { 365 next.prev = null; 366 next = null; 367 } 368 } 369 370 void makeFirst() { 371 if (prev != null) { 372 prev.next = null; 373 prev = null; 374 } 375 } 376 377 } 386 } 387 | Popular Tags |