1 19 package org.netbeans.modules.editor.retouche; 20 21 import java.awt.Color ; 22 import java.awt.event.KeyEvent ; 23 import java.awt.event.KeyListener ; 24 import java.util.ArrayList ; 25 import java.util.Collections ; 26 import java.util.List ; 27 import java.util.Set ; 28 import javax.swing.event.CaretEvent ; 29 import javax.swing.event.DocumentEvent ; 30 import javax.swing.event.DocumentListener ; 31 import javax.swing.text.BadLocationException ; 32 import javax.swing.text.Document ; 33 import javax.swing.text.JTextComponent ; 34 import javax.swing.text.Position ; 35 import javax.swing.text.Position.Bias; 36 import org.netbeans.editor.BaseDocument; 37 import org.netbeans.editor.BaseKit; 38 import org.netbeans.editor.Coloring; 39 import org.netbeans.lib.editor.codetemplates.SyncDocumentRegion; 40 import org.netbeans.lib.editor.util.swing.MutablePositionRegion; 41 import org.netbeans.lib.editor.util.swing.PositionRegion; 42 import org.netbeans.modules.editor.highlights.spi.Highlight; 43 import org.netbeans.modules.editor.highlights.spi.Highlighter; 44 import org.openide.filesystems.FileObject; 45 import org.openide.loaders.DataObject; 46 import org.openide.text.NbDocument; 47 48 56 public class InstantRenamePerformer implements DocumentListener , KeyListener { 57 58 private SyncDocumentRegion region; 59 private Document doc; 60 private JTextComponent target; 61 private MutablePositionRegion mainRegion; 62 63 64 private InstantRenamePerformer(JTextComponent target, Set <Highlight> highlights, int caretOffset) throws BadLocationException { 65 this.target = target; 66 doc = target.getDocument(); 67 68 MutablePositionRegion mainRegion = null; 69 List <MutablePositionRegion> regions = new ArrayList <MutablePositionRegion>(); 70 List <Highlight> newHighlights = new ArrayList <Highlight>(); 71 72 for (Highlight h : highlights) { 73 Position start = NbDocument.createPosition(doc, h.getStart(), Bias.Backward); 74 Position end = NbDocument.createPosition(doc, h.getEnd(), Bias.Forward); 75 MutablePositionRegion current = new MutablePositionRegion(start, end); 76 77 if (isIn(current, caretOffset)) { 78 mainRegion = current; 79 } else { 80 regions.add(current); 81 } 82 83 newHighlights.add(new RenameHighlight(current)); 84 } 85 86 if (mainRegion == null) { 87 throw new IllegalArgumentException ("No highlight contains the caret."); 88 } 89 90 regions.add(0, mainRegion); 91 92 region = new SyncDocumentRegion(doc, regions); 93 94 if (doc instanceof BaseDocument) { 95 ((BaseDocument) doc).setPostModificationDocumentListener(this); 96 } 97 98 target.addKeyListener(this); 99 100 target.putClientProperty(InstantRenamePerformer.class, this); 101 102 Highlighter.getDefault().setHighlights(getFileObject(), "instant-rename", newHighlights); 103 104 target.select(mainRegion.getStartOffset(), mainRegion.getEndOffset()); 105 } 106 107 private FileObject getFileObject() { 108 DataObject od = (DataObject) doc.getProperty(Document.StreamDescriptionProperty); 109 110 if (od == null) 111 return null; 112 113 return od.getPrimaryFile(); 114 } 115 116 public static void performInstantRename(JTextComponent target, Set <Highlight> highlights, int caretOffset) throws BadLocationException { 117 new InstantRenamePerformer(target, highlights, caretOffset); 118 } 119 120 private boolean isIn(MutablePositionRegion region, int caretOffset) { 121 return region.getStartOffset() <= caretOffset && caretOffset <= region.getEndOffset(); 122 } 123 124 private boolean inSync; 125 126 public synchronized void insertUpdate(DocumentEvent e) { 127 if (inSync) 128 return ; 129 130 inSync = true; 131 region.sync(0); 132 inSync = false; 133 target.repaint(); 134 } 135 136 public synchronized void removeUpdate(DocumentEvent e) { 137 if (inSync) 138 return ; 139 140 if (doc.getProperty(BaseKit.DOC_REPLACE_SELECTION_PROPERTY) != null) { 144 return ; 145 } 146 147 inSync = true; 148 region.sync(0); 149 inSync = false; 150 target.repaint(); 151 } 152 153 public void changedUpdate(DocumentEvent e) { 154 } 155 156 public void caretUpdate(CaretEvent e) { 157 } 158 159 public void keyTyped(KeyEvent e) { 160 } 161 162 public void keyPressed(KeyEvent e) { 163 if ( (e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) 164 || (e.getKeyCode() == KeyEvent.VK_ENTER && e.getModifiers() == 0)) { 165 release(); 166 e.consume(); 167 } 168 } 169 170 public void keyReleased(KeyEvent e) { 171 } 172 173 private void release() { 174 target.putClientProperty(InstantRenamePerformer.class, null); 175 if (doc instanceof BaseDocument) { 176 ((BaseDocument) doc).setPostModificationDocumentListener(null); 177 } 178 target.removeKeyListener(this); 179 Highlighter.getDefault().setHighlights(getFileObject(), "instant-rename", Collections.emptyList()); 180 181 region = null; 182 doc = null; 183 target = null; 184 mainRegion = null; 185 } 186 187 private static final class RenameHighlight implements Highlight { 188 189 private PositionRegion region; 190 private static final Coloring COLORING = new Coloring(null, null, new Color (138, 191, 236)); 191 192 public RenameHighlight(PositionRegion region) { 193 this.region = region; 194 } 195 196 public int getStart() { 197 return region.getStartOffset(); 198 } 199 200 public int getEnd() { 201 return region.getEndOffset(); 202 } 203 204 public Coloring getColoring() { 205 return COLORING; 206 } 207 } 208 209 } 210 | Popular Tags |