1 19 20 package org.netbeans.editor.ext; 21 22 import java.util.List ; 23 import java.util.Iterator ; 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import javax.swing.JLabel ; 27 import javax.swing.JList ; 28 import javax.swing.text.Document ; 29 import javax.swing.text.JTextComponent ; 30 import javax.swing.text.BadLocationException ; 31 import org.netbeans.editor.SyntaxSupport; 32 import org.netbeans.editor.BaseDocument; 33 import org.netbeans.lib.editor.util.CharSequenceUtilities; 34 import org.netbeans.lib.editor.util.swing.DocumentUtilities; 35 36 42 43 public interface CompletionQuery { 44 45 59 public Result query(JTextComponent component, int offset, SyntaxSupport support); 60 61 74 public interface SupportsSpeculativeInvocation { 75 } 77 78 82 public interface Result { 83 84 88 public List getData(); 89 90 91 public String getTitle(); 92 93 102 public boolean substituteText(int dataIndex, boolean shift); 103 104 113 public boolean substituteCommonText(int dataIndex); 114 115 } 116 117 121 public static abstract class AbstractResult implements Result { 122 123 124 private List data; 125 126 127 private String title; 128 129 public AbstractResult(List data, String title) { 130 this.data = data; 131 this.title = title; 132 } 133 134 public List getData() { 135 return data; 136 } 137 138 public String getTitle() { 139 return title; 140 } 141 142 } 143 144 145 148 public static class DefaultResult extends AbstractResult { 149 150 private JTextComponent component; 151 private int offset; 152 private int len; 153 154 164 public DefaultResult(JTextComponent component, String title, List data, int offset, int len ) { 165 super(data, title); 166 this.component = component; 167 this.offset = offset; 168 this.len = len; 169 } 170 171 175 private int getCommonPrefixLength( char[] commonPrefix, int len, String s ) { 176 char[] c = s.toCharArray(); 177 int i=0; 178 if( len > c.length ) len = c.length; 179 for( ; i<len; i++ ) { 180 if( commonPrefix[i] != c[i] ) break; 181 } 182 return i; 183 } 184 185 191 public boolean substituteCommonText( int dataIndex ) { 192 List data = getData(); 193 if( data.size() == 0 ) return false; 194 195 Iterator i = data.iterator(); 196 char[] commonPrefix = ((CompletionQuery.ResultItem)i.next()).getItemText().toCharArray(); 197 int commonLength = commonPrefix.length; 198 199 for( ; i.hasNext(); ) { 200 String second = ((CompletionQuery.ResultItem)i.next()).getItemText(); 201 commonLength = getCommonPrefixLength( commonPrefix, commonLength, second ); 202 } 203 CompletionQuery.ResultItem actData = (CompletionQuery.ResultItem)data.get(dataIndex); 204 return actData.substituteCommonText( component, offset, len, commonLength ); 205 } 206 207 208 211 public boolean substituteText(int dataIndex, boolean shift ) { 212 Object actData = getData().get( dataIndex ); 213 return ((CompletionQuery.ResultItem)actData).substituteText( component, offset, len, shift ); 214 } 215 } 216 217 218 221 public static interface ResultItem { 222 232 public boolean substituteCommonText( JTextComponent c, int offset, int len, int subLen ); 233 234 243 public boolean substituteText( JTextComponent c, int offset, int len, boolean shift ); 244 245 248 public String getItemText(); 249 250 258 public Component getPaintComponent( JList list, boolean isSelected, boolean cellHasFocus); 259 } 260 261 265 public static interface ResultItemAssociatedObject { 266 267 270 Object getAssociatedObject(); 271 272 } 273 274 276 public abstract static class AbstractResultItem implements CompletionQuery.ResultItem { 277 278 protected String text; 279 280 282 public AbstractResultItem( String text ) { 283 this.text = text; 284 } 285 286 291 public boolean substituteCommonText( JTextComponent c, int offset, int len, int subLen ) { 292 BaseDocument doc = (BaseDocument)c.getDocument(); 293 try { 294 doc.atomicLock(); 295 try { 296 doc.remove( offset, len ); 297 doc.insertString( offset, text.substring( 0, subLen ), null); 298 } finally { 299 doc.atomicUnlock(); 300 } 301 } catch( BadLocationException exc ) { 302 return false; } 304 return true; 305 } 306 307 312 public boolean substituteText( JTextComponent c, int offset, int len, boolean shift ) { 313 BaseDocument doc = (BaseDocument)c.getDocument(); 314 try { 315 doc.atomicLock(); 316 try { 317 CharSequence textToReplace = DocumentUtilities.getText(doc, offset, len); 318 if (CharSequenceUtilities.textEquals(text, textToReplace)) return false; 319 doc.remove( offset, len ); 320 doc.insertString( offset, text, null); 321 } finally { 322 doc.atomicUnlock(); 323 } 324 } catch( BadLocationException exc ) { 325 return false; } 327 return true; 328 } 329 330 332 public String getItemText() { 333 return text; 334 } 335 336 } 337 338 public static class DefaultResultItem extends CompletionQuery.AbstractResultItem { 339 343 static JLabel rubberStamp = new JLabel (); 344 345 static { 346 rubberStamp.setOpaque( true ); 347 } 348 349 350 protected Color foreColor; 351 352 public DefaultResultItem( String text, Color foreColor ) { 353 super( text ); 354 this.foreColor = foreColor; 355 } 356 357 public Component getPaintComponent( JList list, boolean isSelected, boolean cellHasFocus ) { 358 rubberStamp.setText( " " + text ); if (isSelected) { 360 rubberStamp.setBackground(list.getSelectionBackground()); 361 rubberStamp.setForeground(list.getSelectionForeground()); 362 } else { 363 rubberStamp.setBackground(list.getBackground()); 364 rubberStamp.setForeground( foreColor ); 365 } 366 return rubberStamp; 367 } 368 } 369 370 } 371 | Popular Tags |