1 19 20 package org.netbeans.modules.junit; 21 22 import javax.swing.JTextField ; 23 import javax.swing.event.ChangeEvent ; 24 import javax.swing.event.ChangeListener ; 25 import javax.swing.event.DocumentEvent ; 26 import javax.swing.event.DocumentListener ; 27 import javax.swing.text.BadLocationException ; 28 29 62 public final class ClassNameTextField extends JTextField { 63 64 65 public static final int STATUS_VALID = 0; 66 67 public static final int STATUS_EMPTY = 1; 68 69 public static final int STATUS_INVALID = 2; 70 71 public static final int STATUS_VALID_NOT_DEFAULT = 3; 72 73 78 static final int STATUS_BEFORE_PART = 3; 79 80 81 private TextListener documentListener; 82 83 private int externalStatus = 0; 84 85 private boolean externalStatusValid = false; 86 87 private ChangeListener changeListener; 88 89 private ChangeEvent changeEvent; 90 91 private String defaultText; 92 93 96 public ClassNameTextField() { 97 this((String ) null); 98 setupDocumentListener(); 99 } 100 101 108 public ClassNameTextField(String text) { 109 super(text == null ? "" : text); setupDocumentListener(); 111 } 112 113 115 public void setDefaultText(String defaultText) { 116 if ((defaultText == null) && (this.defaultText == null) 117 || (defaultText != null) && defaultText.equals(this.defaultText)) { 118 return; 119 } 120 121 this.defaultText = defaultText; 122 123 if ((defaultText != null) 124 || (externalStatusValid 125 && (externalStatus == STATUS_VALID_NOT_DEFAULT))) { 126 statusMaybeChanged(); 127 } 128 } 129 130 132 private void setupDocumentListener() { 133 getDocument().addDocumentListener( 134 documentListener = new TextListener()); 135 } 136 137 145 int determineStatus() { 146 String text = getText(); 147 148 int status = STATUS_BEFORE_PART; 149 char[] chars = text.toCharArray(); 150 for (int i = 0; i < chars.length; i++) { 151 char c = chars[i]; 152 switch (status) { 153 case STATUS_BEFORE_PART: 154 if (!Character.isJavaIdentifierStart(c)) { 155 return STATUS_INVALID; 156 } 157 status = STATUS_VALID; 158 break; 159 case STATUS_VALID: 160 if (c == '.') { 161 status = STATUS_BEFORE_PART; 162 } else if (Character.isJavaIdentifierPart(c)) { 163 status = STATUS_VALID; 164 } else { 165 return STATUS_INVALID; 166 } 167 break; 168 default: 169 assert false; 170 } 171 } 172 return status; 173 } 174 175 182 public int getStatus() { 183 if (!externalStatusValid) { 184 updateExternalStatus(); 185 } 186 return externalStatus; 187 } 188 189 191 private void updateExternalStatus() { 192 assert externalStatusValid == false; 193 194 int internalStatus = documentListener.status; 195 switch (internalStatus) { 196 case STATUS_VALID: 197 externalStatus = (defaultText == null) 198 || defaultText.equals(getText()) 199 ? STATUS_VALID 200 : STATUS_VALID_NOT_DEFAULT; 201 break; 202 case STATUS_BEFORE_PART: 203 externalStatus = (getText().length() == 0) ? STATUS_EMPTY 204 : STATUS_INVALID; 205 break; 206 case STATUS_INVALID: 207 externalStatus = STATUS_INVALID; 208 break; 209 default: 210 assert false; 211 externalStatus = STATUS_INVALID; 212 break; 213 } 214 externalStatusValid = true; 215 } 216 217 228 public void setChangeListener(ChangeListener listener) { 229 changeEvent = new ChangeEvent (this); 230 this.changeListener = listener; 231 } 232 233 235 private void statusMaybeChanged() { 236 externalStatusValid = false; 237 238 if (changeListener != null) { 239 final int prevExternalStatus = externalStatus; 240 externalStatus = getStatus(); 241 if (externalStatus != prevExternalStatus) { 242 changeListener.stateChanged(changeEvent); 243 } 244 } 245 } 246 247 249 private final class TextListener implements DocumentListener { 250 251 252 private int status; 253 254 private int length; 255 256 258 public TextListener() { 259 status = determineStatus(); 260 length = ClassNameTextField.this.getText().length(); 261 } 262 263 265 public void changedUpdate(DocumentEvent documentEvent) { 266 length = documentEvent.getDocument().getLength(); 267 int newStatus = determineStatus(); 268 269 if (newStatus != status) { 270 status = newStatus; 271 statusMaybeChanged(); 272 } else if ((status == STATUS_VALID) && (defaultText != null)) { 273 statusMaybeChanged(); } 275 276 assert length == getDocument().getLength(); 277 } 278 279 281 public void insertUpdate(DocumentEvent documentEvent) { 282 int newStatus; 283 boolean wasEmpty = (length == 0); 284 285 if (documentEvent.getLength() != 1 286 || (documentEvent.getOffset() != length)) { 287 length += documentEvent.getLength(); 288 newStatus = determineStatus(); 289 } else { 290 char c; 291 292 293 try { 294 c = documentEvent.getDocument().getText(length++, 1) 295 .charAt(0); 296 switch (status) { 297 case STATUS_VALID: 298 newStatus = (c == '.') 299 ? newStatus = STATUS_BEFORE_PART 300 : (Character.isJavaIdentifierPart(c)) 301 ? STATUS_VALID 302 : STATUS_INVALID; 303 break; 304 case STATUS_BEFORE_PART: 305 newStatus = (Character.isJavaIdentifierStart(c)) 306 ? STATUS_VALID 307 : STATUS_INVALID; 308 break; 309 case STATUS_INVALID: 310 newStatus = determineStatus(); 311 break; 312 default: 313 assert false; 314 newStatus = determineStatus(); 315 break; 316 } 317 } catch (BadLocationException ex) { 318 assert false; 319 320 length = documentEvent.getDocument().getLength(); 321 newStatus = determineStatus(); 322 } 323 } 324 325 330 if ((newStatus != status) || wasEmpty) { 331 status = newStatus; 332 statusMaybeChanged(); 333 } else if ((status == STATUS_VALID) && (defaultText != null)) { 334 statusMaybeChanged(); } 336 337 assert length == getDocument().getLength(); 338 } 339 340 342 public void removeUpdate(DocumentEvent documentEvent) { 343 int newStatus; 344 345 if (documentEvent.getLength() != 1 346 || (documentEvent.getOffset() != (length - 1))) { 347 length -= documentEvent.getLength(); 348 newStatus = determineStatus(); 349 } else { 350 351 355 length--; 356 switch (status) { 357 case STATUS_VALID: 358 try { 359 newStatus = ((length == 0) 360 || (documentEvent.getDocument() 361 .getText(length - 1, 1)) 362 .charAt(0) == '.') 363 ? STATUS_BEFORE_PART 364 : STATUS_VALID; 365 } catch (BadLocationException ex) { 366 assert false; 367 368 newStatus = determineStatus(); 369 length = documentEvent.getDocument().getLength(); 370 } 371 break; 372 case STATUS_BEFORE_PART: 373 newStatus = STATUS_VALID; break; 375 case STATUS_INVALID: 376 newStatus = (length == 0) ? STATUS_VALID 377 : determineStatus(); 378 break; 379 default: 380 assert false; 381 newStatus = determineStatus(); 382 break; 383 } 384 } 385 386 387 392 if ((newStatus != status) || (length == 0)) { 393 status = newStatus; 394 statusMaybeChanged(); 395 } else if ((status == STATUS_VALID) && (defaultText != null)) { 396 statusMaybeChanged(); } 398 399 assert length == getDocument().getLength(); 400 } 401 402 } 403 404 } 405 | Popular Tags |