1 19 20 package org.netbeans.modules.editor.java; 21 22 import com.sun.source.tree.Tree; 23 import com.sun.source.util.SourcePositions; 24 import com.sun.source.util.TreePath; 25 import java.awt.event.ActionEvent ; 26 import java.io.IOException ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import java.util.MissingResourceException ; 30 import javax.swing.Action ; 31 import javax.swing.event.CaretEvent ; 32 import javax.swing.event.CaretListener ; 33 import javax.swing.text.Caret ; 34 import javax.swing.text.JTextComponent ; 35 import org.netbeans.api.java.source.CancellableTask; 36 import org.netbeans.api.java.source.CompilationController; 37 import org.netbeans.api.java.source.JavaSource; 38 import org.netbeans.api.java.source.JavaSource.Phase; 39 import org.netbeans.editor.BaseAction; 40 import org.openide.ErrorManager; 41 import org.openide.util.NbBundle; 42 43 50 final class SelectCodeElementAction extends BaseAction { 51 52 private boolean selectNext; 53 54 66 public SelectCodeElementAction(String name, boolean selectNext) { 67 super(name); 68 this.selectNext = selectNext; 69 String desc = getShortDescription(); 70 if (desc != null) { 71 putValue(SHORT_DESCRIPTION, desc); 72 } 73 } 74 75 public String getShortDescription(){ 76 String name = (String )getValue(Action.NAME); 77 if (name == null) return null; 78 String shortDesc; 79 try { 80 shortDesc = NbBundle.getBundle(JavaKit.class).getString(name); }catch (MissingResourceException mre){ 82 shortDesc = name; 83 } 84 return shortDesc; 85 } 86 87 public void actionPerformed(ActionEvent evt, JTextComponent target) { 88 if (target != null) { 89 int selectionStartOffset = target.getSelectionStart(); 90 int selectionEndOffset = target.getSelectionEnd(); 91 if (selectionEndOffset > selectionStartOffset || selectNext) { 92 SelectionHandler handler = (SelectionHandler)target.getClientProperty(SelectionHandler.class); 93 if (handler == null) { 94 handler = new SelectionHandler(target); 95 target.addCaretListener(handler); 96 target.putClientProperty(SelectionHandler.class, handler); 99 } 100 101 if (selectNext) { handler.selectNext(); 103 } else { handler.selectPrevious(); 105 } 106 } 107 } 108 } 109 110 private static final class SelectionHandler implements CaretListener , CancellableTask<CompilationController>, Runnable { 111 112 private JTextComponent target; 113 private SelectionInfo[] selectionInfos; 114 private int selIndex = -1; 115 private boolean ignoreNextCaretUpdate; 116 117 SelectionHandler(JTextComponent target) { 118 this.target = target; 119 } 120 121 public void selectNext() { 122 if (selectionInfos == null) { 123 JavaSource js = JavaSource.forDocument(target.getDocument()); 124 try { 125 js.runUserActionTask(this, true); 126 } catch (IOException ex) { 127 ErrorManager.getDefault().notify(ex); 128 } 129 } 130 131 run(); 132 } 133 134 public synchronized void selectPrevious() { 135 if (selIndex > 0) { 136 select(selectionInfos[--selIndex]); 137 } 138 } 139 140 private void select(SelectionInfo selectionInfo) { 141 Caret caret = target.getCaret(); 142 markIgnoreNextCaretUpdate(); 143 caret.setDot(selectionInfo.getStartOffset()); 144 markIgnoreNextCaretUpdate(); 145 caret.moveDot(selectionInfo.getEndOffset()); 146 } 147 148 private void markIgnoreNextCaretUpdate() { 149 ignoreNextCaretUpdate = true; 150 } 151 152 public void caretUpdate(CaretEvent e) { 153 if (!ignoreNextCaretUpdate) { 154 synchronized (this) { 155 selectionInfos = null; 156 selIndex = -1; 157 } 158 } 159 ignoreNextCaretUpdate = false; 160 } 161 162 public void cancel() { 163 } 164 165 public void run(CompilationController cc) { 166 try { 167 cc.toPhase(Phase.RESOLVED); 168 selectionInfos = initSelectionPath(target, cc); 169 } catch (IOException ex) { 170 ErrorManager.getDefault().notify(ex); 171 } 172 } 173 174 private SelectionInfo[] initSelectionPath(JTextComponent target, CompilationController ci) { 175 List <SelectionInfo> positions = new ArrayList <SelectionInfo>(); 176 SourcePositions sp = ci.getTrees().getSourcePositions(); 177 TreePath tp = ci.getTreeUtilities().pathFor(target.getCaretPosition()); 178 for (Tree tree: tp) { 179 int startPos = (int)sp.getStartPosition(tp.getCompilationUnit(), tree); 180 int endPos = (int)sp.getEndPosition(tp.getCompilationUnit(), tree); 181 positions.add(new SelectionInfo(startPos, endPos)); 182 } 183 return positions.toArray(new SelectionInfo[positions.size()]); 184 } 185 186 public void run() { 187 if (selIndex < selectionInfos.length - 1) { 188 select(selectionInfos[++selIndex]); 189 } 190 } 191 192 } 193 194 private static final class SelectionInfo { 195 196 private int startOffset; 197 private int endOffset; 198 199 SelectionInfo(int startOffset, int endOffset) { 200 this.startOffset = startOffset; 201 this.endOffset = endOffset; 202 } 203 204 public int getStartOffset() { 205 return startOffset; 206 } 207 208 public int getEndOffset() { 209 return endOffset; 210 } 211 212 } 213 } 214 | Popular Tags |