1 19 20 package org.openide.explorer.propertysheet; 21 22 import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; 23 import java.awt.BorderLayout ; 24 import java.awt.Color ; 25 import java.awt.Component ; 26 import java.awt.Container ; 27 import java.awt.Dimension ; 28 import java.awt.DisplayMode ; 29 import java.awt.FlowLayout ; 30 import java.awt.Graphics ; 31 import java.awt.Graphics2D ; 32 import java.awt.GraphicsEnvironment ; 33 import java.awt.Image ; 34 import java.awt.KeyboardFocusManager ; 35 import java.awt.Point ; 36 import java.awt.Transparency ; 37 import java.awt.event.FocusEvent ; 38 import java.awt.event.FocusListener ; 39 import java.awt.event.KeyEvent ; 40 import java.awt.event.MouseEvent ; 41 import java.awt.event.WindowAdapter ; 42 import java.awt.event.WindowEvent ; 43 import java.awt.image.BufferedImage ; 44 import java.awt.image.ColorModel ; 45 import java.beans.PropertyEditor ; 46 import java.beans.PropertyEditorSupport ; 47 import java.lang.reflect.InvocationTargetException ; 48 import java.util.Hashtable ; 49 import java.util.Iterator ; 50 import javax.swing.Icon ; 51 import javax.swing.ImageIcon ; 52 import javax.swing.JButton ; 53 import javax.swing.JCheckBox ; 54 import javax.swing.JComboBox ; 55 import javax.swing.JComponent ; 56 import javax.swing.JDialog ; 57 import javax.swing.JFrame ; 58 import javax.swing.JLabel ; 59 import javax.swing.JPanel ; 60 import javax.swing.JRadioButton ; 61 import javax.swing.KeyStroke ; 62 import javax.swing.SwingUtilities ; 63 import javax.swing.event.ChangeEvent ; 64 import javax.swing.event.ChangeListener ; 65 import javax.swing.text.JTextComponent ; 66 import org.netbeans.junit.NbTestCase; 67 import org.netbeans.modules.openide.explorer.UIException; 68 import org.openide.ErrorManager; 69 import org.openide.nodes.AbstractNode; 70 import org.openide.nodes.Children; 71 import org.openide.nodes.Node; 72 import org.openide.nodes.PropertySupport; 73 import org.openide.nodes.Sheet; 74 import org.openide.util.Utilities; 75 76 77 public class EditableDisplayerTest extends NbTestCase { 78 79 static { 80 ComboTest.registerPropertyEditors(); 81 } 82 83 public EditableDisplayerTest(String name) { 84 super(name); 85 } 86 91 92 EditablePropertyDisplayer basicRen; 93 EditablePropertyDisplayer tagsRen1; 94 EditablePropertyDisplayer tagsRen2; 95 EditablePropertyDisplayer tagsRen3; 96 EditablePropertyDisplayer boolRen; 97 EditablePropertyDisplayer custRen; 98 EditablePropertyDisplayer custRen2; 99 EditablePropertyDisplayer exRen; 100 EditablePropertyDisplayer numRen; 101 EditablePropertyDisplayer edRen; 102 EditablePropertyDisplayer stringRen; 103 104 private TNode tn; 105 private BasicProperty basicProp; 106 private TagsProperty tags1; 107 private TagsProperty tags2; 108 private TagsProperty tags3; 109 private BooleanProperty booleanProp; 110 private CustomProperty customProp; 111 private CustomProperty customProp2; 112 private BasicEditor te; 113 private StringProperty stringProp; 114 private JFrame jf=null; 115 private JPanel jp=null; 116 private int SLEEP_LENGTH=120; 117 118 private static boolean setup=false; 119 120 protected void tearDown() { 121 129 } 130 131 static final boolean canRun = ExtTestCase.canSafelyRunFocusTests() && GraphicsTestCase.canSafelyRunPixelTests(); 132 protected void setUp() throws Exception { 133 134 PropUtils.forceRadioButtons=false; 137 try { 138 basicProp= new BasicProperty("basicProp", true); 140 System.err.println("Created basicProp at " + System.currentTimeMillis() + " - " + basicProp); 141 142 tags1 = new TagsProperty("tags1", true, new String [] {"What","is","the","meaning","of","life"}); 143 tags2 = new TagsProperty("tags2", true, new String [] {"Austrolopithecines","automatically","engender","every","one"}); 144 tags3 = new TagsProperty("tags3", true, new String [] {"Behold","the","power","of","cheese"}); 145 booleanProp = new BooleanProperty("booleanProp", true); 146 customProp = new CustomProperty("CustomProp", true); 147 customProp2 = new CustomProperty("CustomProp2", true); 148 ExceptionProperty exProp = new ExceptionProperty("Exception prop", true); 149 NumProperty numProp = new NumProperty("Int prop", true); 150 EditableNumProperty edProp = new EditableNumProperty("Editable", true); 151 stringProp = new StringProperty("stringProp",true); 152 153 te = new BasicEditor(); 155 tn = new TNode(); 157 158 System.err.println("Crating frame"); 159 jf = new JFrame (); 160 jf.getContentPane().setLayout(new BorderLayout ()); 161 jp = new JPanel (); 162 jp.setLayout(new FlowLayout ()); 163 jf.getContentPane().add(jp, BorderLayout.CENTER); 164 jf.setLocation(20,20); 165 jf.setSize(600, 200); 166 167 synchronized (jp.getTreeLock()) { 168 System.err.println("BasicProp = " + basicProp); 169 170 basicRen = new EditablePropertyDisplayer(basicProp); 171 tagsRen1 = new EditablePropertyDisplayer(tags1); 172 tagsRen2 = new EditablePropertyDisplayer(tags2); 173 tagsRen3 = new EditablePropertyDisplayer(tags3); 174 boolRen = new EditablePropertyDisplayer(booleanProp); 175 custRen = new EditablePropertyDisplayer(customProp); 176 custRen2 = new EditablePropertyDisplayer(customProp2); 177 exRen = new EditablePropertyDisplayer(exProp); 178 numRen = new EditablePropertyDisplayer(numProp); 179 edRen = new EditablePropertyDisplayer(edProp); 180 stringRen = new EditablePropertyDisplayer(stringProp); 181 182 tagsRen2.setRadioButtonMax(10); 183 184 jp.add(basicRen); 185 jp.add(tagsRen1); 186 jp.add(tagsRen2); 187 jp.add(tagsRen3); 188 jp.add(boolRen); 189 jp.add(custRen); 190 jp.add(custRen2); 191 jp.add(numRen); 192 jp.add(edRen); 193 jp.add(stringRen); 194 } 195 196 System.err.println("Waiting for window"); 197 new WaitWindow(jf); System.err.println("Window shown"); 199 } catch (Exception e) { 200 e.printStackTrace(); 201 } finally { 202 setup = true; 203 } 204 } 205 206 public void testRadioButtonThreshold() throws Exception { 207 if (!canRun) return; 208 209 System.err.println("running"); 210 clickOn(basicRen); 211 tagsRen2.setRadioButtonMax(2); 212 213 clickOn(tagsRen2); 214 Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 215 assertTrue("after setting radio max below threshold, click on the renderer should focus a combo box, not " + c, c instanceof JComboBox ); 216 217 clickOn(basicRen); 218 tagsRen2.setRadioButtonMax(10); 219 sleep(); 220 221 clickOn(tagsRen2, 80, 25); 222 tagsRen2.requestFocus(); 223 sleep(); 224 225 c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 226 assertTrue("after setting radio button max > threshold, focus owner should be a radio button, not " + c, c instanceof JRadioButton ); 227 } 228 229 public void testBooleanEditor() throws Exception { 230 if (!canRun) return; 231 232 boolRen.setUpdatePolicy(boolRen.UPDATE_ON_CONFIRMATION); 233 requestFocus(boolRen); 234 sleep(); 235 sleep(); 236 Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 237 assertTrue("After requesting focus on a boolean property, focus owner should be a checkbox, not " + c, c instanceof JCheckBox ); 238 239 Boolean b = (Boolean ) booleanProp.getValue(); 240 pressKey(boolRen, KeyEvent.VK_SPACE); 241 releaseKey(boolRen, KeyEvent.VK_SPACE); 242 Boolean b2 = (Boolean ) booleanProp.getValue(); 243 assertNotSame("Clicking on a checkbox with policy UPDATE_ON_CONFIRMATION should change the property value",b, b2); 244 245 boolRen.setUpdatePolicy(boolRen.UPDATE_ON_EXPLICIT_REQUEST); 246 Boolean b3 = (Boolean ) booleanProp.getValue(); 247 pressKey(boolRen, KeyEvent.VK_SPACE); 248 releaseKey(boolRen, KeyEvent.VK_SPACE); 249 Boolean b4 = (Boolean ) booleanProp.getValue(); 250 assertEquals("Clicking on a checkbox with policy UPDATE_ON_EXPLICIT_REQUEST should not change the underlying property", b3, b4); 251 252 Boolean b5 = (Boolean ) boolRen.getEnteredValue(); 253 assertNotSame("Clicking on a checkbox wiith policy UDPATE_ON_EXPLICIT_REQUEST should mean that the value returned by the editor and the value returned by the property are different until commit() is called", 254 b4, b5); 255 256 boolean rslt = boolRen.commit(); 257 assertTrue("Should have been able to update boolean property", rslt); 258 259 Boolean b6 = (Boolean ) booleanProp.getValue(); 260 assertEquals("After commit, bool editor value should eqaul bool property value", b6, boolRen.getEnteredValue()); 261 262 pressKey(boolRen, KeyEvent.VK_SPACE); 263 releaseKey(boolRen, KeyEvent.VK_SPACE); 264 265 SwingUtilities.invokeAndWait(new Runnable () { 266 public void run() { 267 jf.getContentPane().remove(boolRen); 268 } 269 }); 270 sleep(); 271 272 boolean val = boolRen.commit(); 273 assertTrue("Should still be able to commit after removal from a parent", val); 274 275 assertNotSame("Commit should update value even if called when no parent is present", b6, booleanProp.getValue()); 276 } 277 278 public void testEditableCombo() throws Exception { 279 if (!canRun) return; 280 281 edRen.setUpdatePolicy(edRen.UPDATE_ON_CONFIRMATION); 282 clickOn(edRen); 283 requestFocus(edRen); 284 sleep(); 285 sleep(); 286 JComponent c = (JComponent )KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 287 288 289 Object o = edRen.getProperty().getValue(); 290 String nuVal = "FOO"; 291 292 typeKey(c, KeyEvent.VK_F); 293 typeKey(c, KeyEvent.VK_O); 294 typeKey(c, KeyEvent.VK_O); 295 assertEquals("After typing into editable combo, value should match the typed value", nuVal, edRen.getEnteredValue()); 296 297 assertNotSame("After typing into editable combo with policy UPDATE_ON_CONFIRMATION, the property should not have the value typed", 298 nuVal, edRen.getProperty().getValue()); 299 300 pressKey(c, KeyEvent.VK_ENTER); 301 302 assertEquals("After pressing enter on an editable combo, value should be updated", nuVal, edRen.getProperty().getValue()); 303 } 304 305 public void testEnv() throws Exception { 306 if (!canRun) return; 307 308 try { 309 custRen.setUpdatePolicy(custRen.UPDATE_ON_EXPLICIT_REQUEST); 310 311 requestFocus(custRen); 312 JComponent c = (JComponent )KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 313 typeKey(c, KeyEvent.VK_W); 314 typeKey(c, KeyEvent.VK_O); 315 typeKey(c, KeyEvent.VK_W); 316 pressKey(c, KeyEvent.VK_ENTER); 317 318 EditorCustom ec = (EditorCustom) custRen.getPropertyEditor(); 319 PropertyEnv env = ec.env; 320 assertSame(" The PropertyEnv the editor is attached to should be the same as the one the component posesses", 321 custRen.getPropertyEnv(), env); 322 323 assertTrue(" After pressing enter with a new value with policy UPDATE_ON_EXPLICIT_REQUEST, the property value should not be the typed value", 324 !custRen.getProperty().getValue().equals("WOW")); 325 326 assertTrue(" After pressing enter with a new value with policy UPDATE_ON_EXPLICIT_REQUEST, isValueModified() should return true", 327 custRen.isValueModified()); 328 329 env = ec.env; 330 assertSame(" Calling isValueModified attached a different PropertyEnv to the editor and didn't call attachEnv again with the one it listens on for changes", 331 custRen.getPropertyEnv(), env); 332 333 334 String legality = custRen.isModifiedValueLegal(); 335 assertNull("After pressing enter with a new value with policy UPDATE_ON_EXPLICIT_REQUEST with a valid value, isModifiedValueLegal should return null, not " + legality, 336 legality); 337 338 env = ec.env; 339 340 env = ec.env; 341 assertSame(" Calling isModifiedValueLegal attached a different PropertyEnv to the editor and didn't call attachEnv again with the one it listens on for changes", 342 custRen.getPropertyEnv(), env); 343 } catch (Exception e) { 344 e.printStackTrace(); 345 throw e; 346 } 347 348 requestFocus(basicRen); 349 350 SwingUtilities.invokeLater(new Runnable () { 351 public void run() { 352 custRen.setEnteredValue(""); 353 } 354 }); 355 sleep(); 356 sleep(); 357 sleep(); 358 359 requestFocus(custRen); 360 361 typeKey(custRen, KeyEvent.VK_V); 362 typeKey(custRen, KeyEvent.VK_A); 363 typeKey(custRen, KeyEvent.VK_L); 364 typeKey(custRen, KeyEvent.VK_U); 365 typeKey(custRen, KeyEvent.VK_E); 366 367 pressKey(custRen, KeyEvent.VK_ENTER); 368 369 assertEquals("After entering a value, getEnteredValue should return it", "VALUE", custRen.getEnteredValue()); 370 371 372 String legality = custRen.isModifiedValueLegal(); 373 assertNotNull("After entering a value that will put the env in STATE_INVALID, a localized message should be returned by isModifiedValueLegal", legality); 374 375 } 376 377 378 public void testPropertyMarking() throws Exception { 379 if (!canRun) return; 380 381 if (!checkGraphicsEnvironment()) { 382 System.err.println(" Cannot run this test in a < 16 bit graphics environment"); 383 } 384 custRen.setUpdatePolicy(custRen.UPDATE_ON_CONFIRMATION); 385 SwingUtilities.invokeLater(new Runnable () { 386 public void run() { 387 try { 388 throwMe = null; 389 custRen.getProperty().setValue("Value"); 390 custRen.refresh(); 391 } catch (Exception e) { 392 throwMe = e; 393 } 394 } 395 }); 396 397 if (throwMe != null) { 398 Exception exc = throwMe; 399 throwMe = null; 400 throw exc; 401 } 402 403 404 requestFocus(custRen); 405 406 typeKey(custRen, KeyEvent.VK_S); 407 typeKey(custRen, KeyEvent.VK_N); 408 typeKey(custRen, KeyEvent.VK_O); 409 typeKey(custRen, KeyEvent.VK_R); 410 typeKey(custRen, KeyEvent.VK_K); 411 typeKey(custRen, KeyEvent.VK_E); 412 typeKey(custRen, KeyEvent.VK_L); 413 414 Image i = Utilities.loadImage("org/openide/resources/propertysheet/invalid.gif"); 416 ImageIcon icon = new ImageIcon (i); 417 int yOffset = (custRen.getHeight() / 2) - (icon.getIconHeight()/2); 418 419 assertImageMatch("Error icon should be painted for invalid value", i, custRen, 0, yOffset); 421 422 requestFocus(custRen); 423 424 sleep(); 426 typeKey(custRen, KeyEvent.VK_M); 427 typeKey(custRen, KeyEvent.VK_R); 428 typeKey(custRen, KeyEvent.VK_F); 429 typeKey(custRen, KeyEvent.VK_ENTER); 430 pressKey(custRen, KeyEvent.VK_ENTER); 431 pressKey(custRen, KeyEvent.VK_ENTER); 432 custRen.commit(); 433 sleep(); 434 sleep(); 435 436 Icon icon2 = new ValueIcon(); 437 int yOffset2 = (custRen.getHeight() / 2) - (icon2.getIconHeight()/2); 438 439 assertPixel("Supplied value icon should be drawn on panel, not the error marking icon, after committing a valid value.", 440 custRen, Color.BLUE, icon2.getIconWidth() / 2, (icon2.getIconHeight() / 2) + yOffset2); 441 442 requestFocus(custRen); 443 444 typeKey(custRen, KeyEvent.VK_V); 445 typeKey(custRen, KeyEvent.VK_A); 446 typeKey(custRen, KeyEvent.VK_L); 447 typeKey(custRen, KeyEvent.VK_U); 448 typeKey(custRen, KeyEvent.VK_E); 449 custRen.setEnteredValue("VALUE"); 450 pressKey(custRen, KeyEvent.VK_ENTER); 451 custRen.commit(); 452 sleep(); 453 sleep(); 454 sleep(); 455 custRen.paintImmediately(0,0,custRen.getWidth(),custRen.getHeight()); 456 assertImageMatch("After reentering an invalid value, the icon should change back to the error icon", i, custRen, 0, yOffset); 457 } 458 459 460 461 public void testControlSpaceInvokesCustomEditor() throws Exception { 462 if (!canRun) return; 463 464 requestFocus(custRen2); 465 final Component focusOwner = 466 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 467 assertTrue("Requesting focus on an enabled renderer should set focus to it or its child", custRen2 == focusOwner || custRen2.isAncestorOf(focusOwner)); 468 469 System.err.println("CONTROL PRESS KEY"); 470 SwingUtilities.invokeLater(new Runnable () { 471 public void run() { 472 try { 473 throwMe = null; 474 ctrlPressKey(focusOwner, KeyEvent.VK_SPACE); 475 } catch (Exception e) { 476 throwMe = e; 477 } 478 } 479 }); 480 if (throwMe != null) { 481 Exception e1 = throwMe; 482 throwMe = null; 483 throw throwMe; 484 } 485 486 sleep(); 487 sleep(); 488 sleep(); 489 sleep(); 490 sleep(); 491 sleep(); 492 493 Component newOwner = 494 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 495 496 assertNotSame("Pressing ctrl-space should move focus to a dialog", focusOwner, newOwner); 497 498 pressKey(newOwner, KeyEvent.VK_ESCAPE); 499 sleep(); 500 501 Component owner = 502 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 503 504 if (owner == null) { 505 sleep(); 506 sleep(); 507 owner = 508 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 509 } 510 511 assertNotSame("Pressing escape on custom editor dialog should dismiss it", owner, newOwner); 512 assertSame("Focus should return to the editor if lost from a custom editor dialog", focusOwner, owner); 513 514 if (newOwner != null) { 515 Container c = ((JComponent ) newOwner).getTopLevelAncestor(); 516 if (c != null) { 517 c.hide(); 518 } 519 } 520 } 521 522 public void testRenderersPaintIndentically() throws Exception { 523 if (!canRun) return; 524 if (!checkGraphicsEnvironment()) { 525 System.err.println("Cannot run test in < 16 bit graphics environment"); 526 } 527 Component [] c = jp.getComponents(); 528 Hashtable map = new Hashtable (); 529 synchronized (jp.getTreeLock()) { 530 for (int i=0; i < c.length; i++) { 531 System.err.println(" Checking " + c[i]); 532 if (c[i] instanceof EditablePropertyDisplayer) { 533 System.err.println(" CREATE A RENDERER AND ADD IT"); 534 EditablePropertyDisplayer curr = (EditablePropertyDisplayer) c[i]; 535 try { 536 curr.commit(); 537 } catch (Exception e) { 538 curr.reset(); 539 } 540 541 RendererPropertyDisplayer rpd = new RendererPropertyDisplayer(curr.getProperty()); 542 rpd.setRadioButtonMax(curr.getRadioButtonMax()); 543 rpd.setProperty(curr.getProperty()); 544 map.put(curr, rpd); 545 jp.add(rpd); 546 } 547 } 548 } 549 550 jp.repaint(); 551 552 553 Iterator i = map.keySet().iterator(); 554 while (i.hasNext()) { 555 EditablePropertyDisplayer editable = (EditablePropertyDisplayer) i.next(); 556 RendererPropertyDisplayer renderer = (RendererPropertyDisplayer) map.get(editable); 557 assertPaintIdentically("Painting was not a pixel-for-pixel match between " + editable + " and " + renderer, editable, renderer); 558 } 560 561 } 562 563 564 public void testCustomEditor() throws Exception { 565 if (!canRun) return; 566 567 requestFocus(stringRen); 568 Runnable run = new Runnable () { 569 public void run() { 570 try { 571 doCtrlPressKey(stringRen, KeyEvent.VK_SPACE); 572 } catch (Exception e) {} 573 } 574 }; 575 new Thread (run).start(); 576 577 Thread.currentThread().sleep(1000); 578 579 sleep(); 580 Component owner = 581 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 582 583 assertNotNull("After invoking custom editor, focus owner should not be null", owner); 584 585 assertTrue("Control press should invoke custom editor", ((JComponent ) owner).getTopLevelAncestor() != 586 stringRen.getTopLevelAncestor()); 587 588 assertTrue("String custom editor should be a JTextComponent", owner instanceof JTextComponent ); 589 590 final JTextComponent jtc = (JTextComponent ) owner; 591 592 jtc.setText("Wuggle buggle"); 593 594 sleep(); 595 sleep(); 596 597 doCtrlPressKey(owner, KeyEvent.VK_TAB); 598 599 sleep(); 600 sleep(); 601 602 Component okbutton = 603 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 604 605 assertTrue("Button after editor in string renderer should be ok button", okbutton instanceof JButton ); 606 607 ((JButton ) okbutton).doClick(); 608 sleep(); 609 sleep(); 610 sleep(); 611 612 assertEquals("After clicking ok on custom editor, property should be updated", "Wuggle buggle", stringRen.getProperty().getValue()); 613 sleep(); 614 assertEquals("After clicking ok button, inline editor should have the custom editor value", stringRen.getProperty().getValue(), stringRen.getEnteredValue()); 615 616 } 617 618 public void testCustomEditorTitle() throws Exception { 619 if (!canRun) return; 620 621 requestFocus(custRen); 622 Runnable run = new Runnable () { 623 public void run() { 624 try { 625 doCtrlPressKey(stringRen, KeyEvent.VK_SPACE); 626 } catch (Exception e) {} 627 } 628 }; 629 new Thread (run).start(); 630 631 Thread.currentThread().sleep(1000); 632 633 sleep(); 634 Component owner = 635 KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 636 637 assertTrue("Control press should invoke custom editor", ((JComponent ) owner).getTopLevelAncestor() != 638 stringRen.getTopLevelAncestor()); 639 640 Container c = ((JComponent ) owner).getTopLevelAncestor(); 641 System.err.println("CLASS: " + c.getClass()); 642 643 if (c instanceof JDialog ) { 644 assertEquals("Custom editor supplying a title via client properties should be shown in a dialog with that title", 645 ((JDialog ) c).getTitle(), "Don't panic"); 646 } 647 } 648 649 private Dimension dim=null; 650 653 private Dimension getPreferredSize(final JComponent jc) throws Exception { 654 SwingUtilities.invokeAndWait(new Runnable () { 655 public void run() { 656 dim = null; 657 throwMe = null; 658 try { 659 dim = jc.getPreferredSize(); 660 } catch (Exception e) { 661 throwMe = e; 662 } 663 } 664 }); 665 Dimension result = dim; 666 dim = null; 667 if (throwMe != null) { 668 Exception exc = throwMe; 669 throwMe = null; 670 throw throwMe; 671 } 672 return result; 673 } 674 675 private void assertPaintIdentically(String msg, JComponent a, JComponent b) throws Exception { 676 677 if (true) return; 679 KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); 681 682 final Dimension d = getPreferredSize(a); 683 684 if (d.width < 0 || d.height < 0) { 685 StringBuffer sb = new StringBuffer (); 686 Container con = a; 687 while (con != null && con.getComponentCount() != 0) { 688 sb.append(con.getClass().getName() + " - preferred size: " + con.getPreferredSize() + "\n"); 689 if (con.getComponent(0) instanceof Container ) { 690 con = (Container ) con.getComponent(0); 691 } else { 692 con = null; 693 } 694 } 695 fail("Got a negative preferred size: " + d + " from tree " + sb.toString()); 696 } 697 698 final BufferedImage bia = new BufferedImage (d.width, d.height, BufferedImage.TYPE_INT_RGB); 699 final BufferedImage bib = new BufferedImage (d.width, d.height, BufferedImage.TYPE_INT_RGB); 700 System.err.println("Created an image of size " + d); 701 702 Graphics2D ga = (Graphics2D ) bia.getGraphics(); 703 704 a.setBounds(0, 0, d.width, d.height); 705 if (a.getLayout() != null) { 706 a.getLayout().layoutContainer(a); 707 } 708 709 sleep(); 710 sleep(); 711 try { 712 a.paint(ga); 713 } catch (Exception e) { 714 SwingUtilities.paintComponent(ga, a, jp, 0, 0, d.width, d.height); 715 } 716 717 Graphics2D gb = (Graphics2D ) bib.getGraphics(); 718 b.setBounds(0,0,d.width,d.height); 719 if (b.getLayout() != null) { 720 b.getLayout().layoutContainer(a); 721 } 722 sleep(); 723 sleep(); 724 try { 725 b.paint(gb); 726 } catch (Exception e) { 727 SwingUtilities.paintComponent(gb, b, jp, 0, 0, d.width, d.height); 728 } 729 730 final BufferedImage diff = new BufferedImage (d.width, d.height, BufferedImage.TYPE_INT_RGB); 731 732 boolean match = true; 733 734 for (int x=0; x < d.width; x++) { 735 for (int y=0; y < d.height; y++) { 736 int pixa = bia.getRGB(x, y); 737 int pixb = bib.getRGB(x, y); 738 boolean matches = pixa == pixb; 739 if (!matches) { 740 System.err.println("Non match: " + x + "," + y); 741 diff.setRGB(x, y, 0); 742 } else { 743 diff.setRGB(x, y, 1239847103); 744 } 745 match &= matches; 746 } 747 } 748 749 final String classa = a.getClass().getName(); 750 final String classb = b.getClass().getName(); 751 752 753 if (!match) { 754 JFrame jf = new JFrame ("assertPaintIdentically diff") { 755 public void paint(Graphics g) { 756 new ImageIcon (diff).paintIcon(this, g, 25, 25); 757 new ImageIcon (bia).paintIcon(this, g, 25, d.height+25); 758 new ImageIcon (bib).paintIcon(this, g, 25, d.height+d.height+25); 759 g.setColor(Color.BLUE); 760 g.drawString(classa, d.width + 10, 57); 761 g.drawString(classb, d.width + 10, 82); 762 } 763 }; 764 jf.setLocation(500, 20); 765 jf.setSize(d.width + 20, (d.height*3)+20); 766 new WaitWindow(jf); 767 } 769 } 770 771 static boolean checkGraphicsEnvironment() { 772 if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadless()) { 773 System.err.println("Cannot run test in a headless environment"); 774 } 775 DisplayMode dm = 776 GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); 777 int i = dm.getBitDepth(); 778 if (i == dm.BIT_DEPTH_MULTI || i >= 16) { 779 return true; 780 } 781 return false; 782 } 783 784 787 private void assertImageMatch(String msg, Image i, JComponent comp, int xpos, int ypos) throws Exception { 788 ImageIcon ic = new ImageIcon (i); 789 int width = ic.getIconWidth(); 790 int height = ic.getIconHeight(); 791 792 for (int x=2; x < 5; x++) { 793 for (int y=2; y < 5; y++) { 794 int posX = width / x; 795 int posY = height / y; 796 System.err.println(" Check " + posX + "," + posY); 797 assertPixelFromImage(msg, i, comp, posX, posY, xpos + posX, ypos + posY); 798 } 799 } 800 801 } 802 803 804 private void requestFocus(final JComponent jc) throws Exception { 805 SwingUtilities.invokeAndWait(new Runnable () { 806 public void run() { 807 jc.requestFocus(); 808 } 809 }); 810 sleep(); 811 } 812 813 private class FL implements FocusListener { 814 private FocusEvent gainedEvent=null; 815 private FocusEvent lostEvent=null; 816 private int gainedCount=0; 817 private int lostCount=0; 818 public void assertGained() { 819 assertNotNull("No focus gained received after clicking on an editable renderer", gainedEvent); 820 assertTrue("Received wrong number of focus gained events for a single click on a renderer " + gainedCount, gainedCount == 1); 821 } 822 823 public void assertLost() { 824 assertNotNull("No focus lost event received after clicking away from a focused, editable renderer", lostEvent); 825 assertTrue("Received wrong number of focus lost events for a single click away from a focused renderer" + lostCount, lostCount == 1); 826 } 827 828 public void focusGained(FocusEvent e) { 829 gainedEvent = e; 830 gainedCount++; 831 } 832 833 public void focusLost(FocusEvent e) { 834 lostEvent = e; 835 lostCount++; 836 } 837 } 838 839 private class CL implements ChangeListener { 840 841 private ChangeEvent e; 842 public void assertEvent(String msg) { 843 sleep(); assertNotNull(msg, e); 845 e = null; 846 } 847 848 public void assertNoEvent(String msg) { 849 sleep(); 850 assertNull(e); 851 e = null; 852 } 853 854 public void stateChanged(ChangeEvent e) { 855 this.e = e; 856 } 857 858 } 859 860 private static class TestGCVal extends Object { 861 public String toString() { 862 return "TestGCVal"; 863 } 864 } 865 866 private static class WaitWindow extends WindowAdapter { 867 boolean shown=false; 868 public WaitWindow(JFrame f) { 869 f.addWindowListener(this); 870 f.show(); 871 if (!shown) { 872 synchronized(this) { 873 try { 874 wait(5000); 876 } catch (Exception e) {} 877 } 878 } 879 } 880 881 public void windowOpened(WindowEvent e) { 882 shown = true; 883 synchronized(this) { 884 notifyAll(); 886 ((JFrame ) e.getSource()).removeWindowListener(this); 887 } 888 } 889 } 890 891 private void sleep() { 892 894 try { 895 Thread.currentThread().sleep(SLEEP_LENGTH); 896 } catch (InterruptedException ie) { 897 } 899 900 try { 901 SwingUtilities.invokeAndWait(new Runnable () { 903 public void run() { 904 System.currentTimeMillis(); 905 } 906 }); 907 SwingUtilities.invokeAndWait(new Runnable () { 909 public void run() { 910 System.currentTimeMillis(); 911 } 912 }); 913 } catch (Exception e) { 914 } 915 } 916 917 private static Color checkColor=null; 918 private static int count=0; 919 921 private synchronized void assertPixelFromImage(String msg, final Image i, final Component c, final int imageX, final int imageY, final int compX, final int compY) throws Exception { 922 final BufferedImage bi = i instanceof BufferedImage ? (BufferedImage ) i : toBufferedImage(i); 923 throwMe = null; 924 sleep(); 925 926 int rgb = bi.getRGB(imageX, imageY); 927 Color color = new Color (rgb); 928 929 930 JFrame jf = new JFrame ("assertPixelFromImage " + count + " (look for the yellow line)") { 933 public void paint(Graphics g) { 934 new ImageIcon (bi).paintIcon(this, g, 25, 25); 935 g.setColor(Color.YELLOW); 936 g.drawLine(imageX+20, imageY+25, imageX+25, imageY+25); 937 } 938 }; 939 jf.setLocation(500,500); 940 jf.setSize(100,100); 941 jf.show(); 942 943 try { 944 assertPixel(msg, c, color, compX, compY); 945 } catch (Exception e) { 946 throwMe = e; 947 } 948 if (throwMe != null) { 949 throw throwMe; 950 } 951 } 952 953 private Exception throwMe2=null; 954 956 private synchronized void assertPixel(final String msg, final Component c, final Color toMatch, final int x, final int y) throws Exception { 957 sleep(); 958 throwMe2 = null; 959 if (true) { 960 doAssertPixel(msg, c, toMatch, x, y); 961 return; 962 } 963 SwingUtilities.invokeAndWait(new Runnable () { 964 public void run() { 965 try { 966 doAssertPixel(msg, c, toMatch, x, y); 967 } catch (Exception e) { 968 throwMe2 = e; 969 } 970 } 971 }); 972 if (throwMe2 != null) { 973 throw throwMe2; 974 } 975 } 976 977 978 private synchronized void doAssertPixel(final String msg, final Component c, final Color toMatch, final int x, final int y) throws Exception { 979 final BufferedImage bi = new BufferedImage (700, 700, BufferedImage.TYPE_INT_RGB); 980 981 sleep(); 982 ((JComponent ) c).paintAll(bi.getGraphics()); 983 sleep(); 984 int[] cArr = new int[3]; 985 bi.getData().getPixel(x, y, cArr); 986 checkColor = new Color (cArr[0], cArr[1], cArr[2]); 987 988 989 JFrame jf = new JFrame ("Assert pixel test " + count + " (look for the yellow line)") { 992 public void paint(Graphics g) { 993 new ImageIcon (bi).paintIcon(this, g, 25, 25); 994 g.setColor(Color.YELLOW); 995 g.drawLine(x+20, y+25, x+25, y+25); 996 } 997 }; 998 jf.setLocation(400,400); 999 jf.setSize(500,500); 1000 jf.show(); 1001 count++; 1002 1003 assertEquals("Pixel test " + (count-1) + " " + msg + " - Color at " + x + "," + y + " does not match", toMatch, checkColor); 1004 } 1005 1006 1007 1008 private void changeProperty(final PropertyDisplayer_Mutable ren, final Node.Property newProp) throws Exception { 1009 SwingUtilities.invokeAndWait(new Runnable () { 1010 public void run() { 1011 ren.setProperty(newProp); 1012 } 1013 }); 1014 } 1015 1016 private void clickOn(final EditablePropertyDisplayer ren, final int fromRight, final int fromTop) throws Exception { 1017 SwingUtilities.invokeAndWait(new Runnable () { 1018 public void run() { 1019 Point toClick = new Point (ren.getWidth() - fromRight, fromTop); 1020 Component target=ren.getComponentAt(toClick); 1021 if (target == null) target = ren; 1022 toClick = SwingUtilities.convertPoint(ren, toClick, target); 1023 System.err.println("Target component is " + target.getClass().getName() + " - " + target + " clicking at " + toClick); 1024 1025 MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 1026 target.dispatchEvent(me); 1027 me = new MouseEvent (target, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 1028 target.dispatchEvent(me); 1029 me = new MouseEvent (target, MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 1030 } 1031 }); 1032 sleep(); 1033 } 1034 1035 private void clickOn(final EditablePropertyDisplayer ren) throws Exception { 1036 SwingUtilities.invokeAndWait(new Runnable () { 1037 public void run() { 1038 Point toClick = new Point (5,5); 1039 Component target=ren.getComponentAt(toClick); 1040 System.err.println("Clicking on " + target); 1041 MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 1042 target.dispatchEvent(me); 1043 } 1044 }); 1045 sleep(); 1046 } 1047 1048 private void setEnabled(final EditablePropertyDisplayer ren,final boolean val) throws Exception { 1049 SwingUtilities.invokeAndWait(new Runnable () { 1050 public void run() { 1051 ren.setEnabled(val); 1052 } 1053 }); 1054 sleep(); 1055 } 1056 1057 private Exception throwMe = null; 1058 private String flushResult = null; 1059 private String flushValue(final EditablePropertyDisplayer ren) throws Exception { 1060 SwingUtilities.invokeAndWait(new Runnable () { 1061 public void run() { 1062 try { 1063 } catch (Exception e) { 1065 throwMe = e; 1066 flushResult = null; 1067 } 1068 } 1069 }); 1070 if (throwMe != null) { 1071 try { 1072 throw throwMe; 1073 } finally { 1074 throwMe = null; 1075 } 1076 } 1077 return flushResult; 1078 } 1079 1080 1081 private void releaseKey(final Component target, final int key) throws Exception { 1082 SwingUtilities.invokeAndWait(new Runnable () { 1083 public void run() { 1084 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), 0, key, (char) key); 1085 target.dispatchEvent(ke); 1086 } 1087 }); 1088 sleep(); 1089 } 1090 1091 private void pressKey(final Component target, final int key) throws Exception { 1092 SwingUtilities.invokeAndWait(new Runnable () { 1093 public void run() { 1094 System.err.println(" pressKey: " + KeyStroke.getKeyStroke(key, 0).getKeyChar()); 1095 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, key, (char) key); 1096 target.dispatchEvent(ke); 1097 } 1098 }); 1099 sleep(); 1100 } 1101 1102 private void shiftPressKey(final Component target, final int key) throws Exception { 1103 SwingUtilities.invokeAndWait(new Runnable () { 1104 public void run() { 1105 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.SHIFT_MASK, key, (char) key); 1106 target.dispatchEvent(ke); 1107 } 1108 }); 1109 sleep(); 1110 } 1111 1112 private void ctrlPressKey(final Component target, final int key) throws Exception { 1113 if (SwingUtilities.isEventDispatchThread()) { 1114 KeyEvent k = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.CTRL_MASK, key, (char) key); 1115 target.dispatchEvent(k); 1116 } else { 1117 1118 SwingUtilities.invokeAndWait(new Runnable () { 1119 public void run() { 1120 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.CTRL_MASK, key, (char) key); 1121 target.dispatchEvent(ke); 1122 } 1123 }); 1124 sleep(); 1125 } 1126 } 1127 1128 private void doCtrlPressKey(final Component target, final int key) throws Exception { 1129 1130 KeyEvent k = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.CTRL_MASK, key, (char) key); 1131 target.dispatchEvent(k); 1132 } 1133 1134 1135 private void typeKey(final Component target, final int key) throws Exception { 1136 SwingUtilities.invokeAndWait(new Runnable () { 1137 public void run() { 1138 System.err.println(" typeKey: " + KeyStroke.getKeyStroke(key, 0).getKeyChar()); 1139 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, (char) key); 1140 target.dispatchEvent(ke); 1141 } 1142 }); 1143 sleep(); 1144 } 1145 1146 public class TNode extends AbstractNode { 1148 public TNode() { 1150 super(Children.LEAF); 1151 setName("TNode"); setDisplayName("TNode"); 1153 createSheet(); 1154 } 1155 public Node cloneNode() { 1157 return new TNode(); 1158 } 1159 1160 public void addProp(Node.Property p) { 1161 props.put(p); 1162 this.firePropertyChange(PROP_PROPERTY_SETS, null, null); 1163 this.firePropertySetsChange(null, null); 1164 } 1165 1166 Sheet sheet=null; 1167 Sheet.Set props=null; 1168 protected Sheet createSheet() { 1170 sheet = super.createSheet(); 1171 props = sheet.get(Sheet.PROPERTIES); 1173 if (props == null) { 1174 props = Sheet.createPropertiesSet(); 1175 sheet.put(props); 1176 } 1177 props.put(basicProp); 1178 props.put(tags1); 1179 props.put(tags2); 1180 props.put(tags3); 1181 props.put(booleanProp); 1182 props.put(customProp); 1183 1184 return sheet; 1185 } 1186 public void fireMethod(String s, Object o1, Object o2) { 1188 firePropertyChange(s,o1,o2); 1189 } 1190 } 1191 1192 public class BasicProperty extends PropertySupport { 1194 private Object myValue = "Value"; 1195 public BasicProperty(String name, boolean isWriteable) { 1197 super(name, Object .class, name, "", true, isWriteable); 1198 } 1199 public Object getValue() { 1201 return myValue; 1202 } 1203 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1205 Object oldVal = myValue; 1206 myValue = value; 1207 tn.fireMethod(getName(), oldVal, myValue); 1208 } 1209 public PropertyEditor getPropertyEditor() { 1211 return te; 1212 } 1213 } 1214 1215 public class BasicEditor extends PropertyEditorSupport implements ExPropertyEditor { 1217 PropertyEnv env; 1218 1219 public BasicEditor() { 1221 } 1222 1223 1227 public void attachEnv(PropertyEnv env) { 1228 this.env = env; 1229 } 1230 1231 public boolean supportsCustomEditor() { 1233 return false; 1234 } 1235 1236 public void setValue(Object newValue) { 1238 super.setValue(newValue); 1239 } 1240 1241 public String getAsText() { 1242 return getValue() == null ? "null" : getValue().toString(); 1243 } 1244 } 1245 1246 1247 private static class PseudoWindowsLookAndFeel extends WindowsLookAndFeel { 1248 public boolean isSupportedLookAndFeel() { 1249 return true; 1250 } 1251 } 1252 1253 public class TagsEditor extends PropertyEditorSupport implements ExPropertyEditor { 1254 PropertyEnv env; 1255 String [] tags; 1256 public TagsEditor(String [] tags) { 1257 this.tags = tags; 1258 } 1259 1260 public String [] getTags() { 1261 return tags; 1262 } 1263 1264 public void attachEnv(PropertyEnv env) { 1265 this.env = env; 1266 } 1267 1268 public boolean supportsCustomEditor() { 1269 return false; 1270 } 1271 1272 public void setValue(Object newValue) { 1273 super.setValue(newValue); 1274 } 1275 1276 1277 } 1278 1279 public class TagsProperty extends PropertySupport { 1281 private Object myValue = "Value"; 1282 private String [] tags; 1283 public TagsProperty(String name, boolean isWriteable, String [] tags) { 1285 super(name, Object .class, name, "", true, isWriteable); 1286 this.tags = tags; 1287 } 1288 public Object getValue() { 1290 return myValue; 1291 } 1292 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1294 Object oldVal = myValue; 1295 myValue = value; 1296 tn.fireMethod(getName(), oldVal, myValue); 1297 } 1298 public PropertyEditor getPropertyEditor() { 1300 return new TagsEditor(tags); 1301 } 1302 1303 public String getShortDescription() { 1304 return "I have tags!"; 1305 } 1306 } 1307 1308 public class BooleanProperty extends PropertySupport { 1310 private Boolean myValue = Boolean.FALSE; 1311 public BooleanProperty(String name, boolean isWriteable) { 1313 super(name, Boolean .class, name, "", true, isWriteable); 1314 } 1315 public Object getValue() { 1317 System.err.println("GetValue of boolean property returning " + myValue); 1318 if (myValue == null) { 1319 throw new IllegalStateException (); 1320 } 1321 return myValue; 1322 } 1323 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1325 Object oldVal = myValue; 1326 myValue = (Boolean ) value; 1327 tn.fireMethod(getName(), oldVal, myValue); 1328 } 1329 public Object getValue(String key) { 1330 if ("valueIcon".equals(key)) { 1331 return new ValueIcon(); 1332 } else { 1333 return super.getValue(key); 1334 } 1335 } 1336 } 1337 1338 public class CustomProperty extends PropertySupport { 1339 private Object myValue = "Value"; 1340 public CustomProperty(String name, boolean isWriteable) { 1342 super(name, Object .class, name, "", true, isWriteable); 1343 } 1344 public Object getValue() { 1346 return myValue; 1347 } 1348 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1350 Object oldVal = myValue; 1351 myValue = value; 1352 tn.fireMethod(getName(), oldVal, myValue); 1353 } 1354 1356 private PropertyEditor editor=null; 1357 public PropertyEditor getPropertyEditor() { 1358 if (editor == null) { 1359 editor = new EditorCustom(); 1360 } 1361 return editor; 1362 } 1363 1364 public Object getValue(String key) { 1365 if ("valueIcon".equals(key)) { 1366 return new ValueIcon(); 1367 } else { 1368 return super.getValue(key); 1369 } 1370 } 1371 } 1372 1373 public class ExceptionProperty extends PropertySupport { 1374 private Object myValue = "Value"; 1375 public ExceptionProperty(String name, boolean isWriteable) { 1377 super(name, Object .class, name, "", true, isWriteable); 1378 } 1379 public Object getValue() { 1381 return myValue; 1382 } 1383 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1385 Object oldVal = myValue; 1386 myValue = value; 1387 tn.fireMethod(getName(), oldVal, myValue); 1388 } 1389 public PropertyEditor getPropertyEditor() { 1391 return exed; 1392 } 1393 } 1394 1395 private ExEditor exed = new ExEditor(); 1396 public static class ExEditor extends PropertyEditorSupport { 1397 private Object myVal="Value"; 1398 public ExEditor() {} 1399 public void setAsText(String val) { 1400 if (val.equals("Value") || val.equals("VALUE")) { 1402 myVal = val; 1403 } else { 1404 IllegalArgumentException iae = new IllegalArgumentException ("No!"); 1405 UIException.annotateUser(iae, "NoNo!", "Localized message", null, 1406 null); 1407 throw iae; 1408 } 1409 } 1410 1411 public void setValue(Object newValue) { 1412 myVal = newValue; 1413 firePropertyChange(); 1414 } 1415 1416 public Object getValue() { 1417 return "Value"; 1418 } 1419 } 1420 1421 1422 public class EditorCustom extends PropertyEditorSupport implements ExPropertyEditor { 1424 PropertyEnv env; 1425 1426 public EditorCustom() { 1428 } 1429 1430 1434 public void attachEnv(PropertyEnv env) { 1435 this.env = env; 1436 if ("Value".equals(getValue()) || "VALUE".equals(getValue())) { 1437 env.setState(env.STATE_INVALID); 1438 } else { 1439 env.setState(env.STATE_VALID); 1440 } 1441 } 1442 1443 public boolean supportsCustomEditor() { 1445 return true; 1446 } 1447 1448 public void setValue(Object newValue) { 1450 super.setValue(newValue); 1451 } 1452 1453 public String getAsText() { 1454 return getValue() == null ? "null" : getValue().toString(); 1455 } 1456 1457 public Component getCustomEditor() { 1458 JLabel result = new JLabel ("Everything is exactly as it should be. Relax."); 1459 result.putClientProperty("title","Don't panic"); 1460 return result; 1461 } 1462 1463 public void setAsText(String s) { 1464 super.setValue(s); 1465 if (!"Value".equals(s) && !"VALUE".equals(s)) { 1466 env.setState(env.STATE_VALID); 1467 } else { 1468 env.setState(env.STATE_INVALID); 1469 } 1470 } 1471 } 1472 1473 public class NumProperty extends PropertySupport { 1474 private Integer myValue = new Integer (4); 1475 public NumProperty(String name, boolean isWriteable) { 1477 super(name, Integer .class, name, "", true, isWriteable); 1478 } 1479 public Object getValue() { 1481 return myValue; 1482 } 1483 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1485 if (!(value instanceof Integer )) { 1486 throw new IllegalArgumentException ("Not an integer - " + value); 1487 } 1488 Object oldVal = myValue; 1489 myValue = (Integer ) value; 1490 tn.fireMethod(getName(), oldVal, myValue); 1491 } 1492 public PropertyEditor getPropertyEditor() { 1494 return new NumberedTagsEditor(); 1495 } 1496 } 1497 1498 public class EditableNumProperty extends TagsProperty { 1499 public EditableNumProperty(String name, boolean isWriteable) { 1500 super(name, isWriteable, new String []{"boo"}); 1501 } 1502 1503 public PropertyEditor getPropertyEditor() { 1504 return new EditableDisplayerTest.EditableTagsEditor(); 1505 } 1506 } 1507 1508 1509 public class NumberedTagsEditor extends PropertyEditorSupport { 1511 private int val=3; 1512 public NumberedTagsEditor() { 1514 } 1515 1516 public String [] getTags() { 1517 return new String [] {"zero","one","two","three","four","five","six","seven"}; 1518 } 1519 1520 1521 public void setValue(Object newValue) { 1523 val = ((Integer ) newValue).intValue(); 1524 firePropertyChange(); 1525 } 1526 1527 public String getAsText() { 1528 return getTags()[((Integer ) getValue()).intValue()]; 1529 } 1530 1531 public void setAsText(String txt) { 1532 String [] t = getTags(); 1533 for (int i=0; i < t.length; i++) { 1534 if (txt.trim().equals(t[i])) { 1535 setValue(new Integer (i)); 1536 return; 1537 } 1538 } 1539 IllegalArgumentException iae = new IllegalArgumentException (txt); 1540 UIException.annotateUser(iae, txt, txt + " is not a valid value", 1541 null, null); 1542 } 1543 1544 public Object getValue() { 1545 return new Integer (val); 1546 } 1547 1548 public Component getCustomEditor() { 1549 return new JPanel (); 1550 } 1551 } 1552 1553 public class EditableTagsEditor extends TagsEditor implements ExPropertyEditor { 1554 private Object val="woof"; 1555 public EditableTagsEditor() { 1556 super(new String [] {"miaou","woof","moo","quack"}); 1557 } 1558 public void attachEnv(PropertyEnv env) { 1559 env.getFeatureDescriptor().setValue("canEditAsText", Boolean.TRUE); 1560 } 1561 public void setAsText(String s) { 1562 setValue(s); 1563 } 1564 public void setValue(Object val) { 1565 this.val = val; 1566 } 1567 public Object getValue() { 1568 return val; 1569 } 1570 public String getAsText() { 1571 return val.toString(); 1572 } 1573 public boolean supportsCustomEditor() { 1574 return true; 1575 } 1576 public Component getCustomEditor() { 1577 return new JLabel ("You called?"); 1578 } 1579 } 1580 1581 private class ValueIcon implements Icon { 1582 1583 public int getIconHeight() { 1584 return 12; 1585 } 1586 1587 public int getIconWidth() { 1588 return 12; 1589 } 1590 1591 public void paintIcon(Component c, Graphics g, int x, int y) { 1592 Color col = g.getColor(); 1593 try { 1594 g.setColor(Color.BLUE); 1595 g.drawRect(x, y, getIconWidth(), getIconHeight()); 1596 g.fillRect(x+3, y+3, getIconWidth()-5, getIconHeight()-5); 1597 } finally { 1598 g.setColor(col); 1599 } 1600 } 1601 } 1602 1603 1604 public class StringProperty extends PropertySupport { 1606 private String myValue = "my oh my"; 1607 public StringProperty(String name, boolean isWriteable) { 1609 super(name, String .class, name, "", true, isWriteable); 1610 } 1611 public Object getValue() { 1613 return myValue; 1614 } 1615 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 1617 System.err.println("SETVALUE ON STRINGPROPERTY: " + value); 1618 Object oldVal = myValue; 1619 myValue = value.toString(); 1620 tn.fireMethod(getName(), oldVal, myValue); 1621 } 1622 } 1623 1624 private static final BufferedImage toBufferedImage(Image img) { 1626 new ImageIcon (img); 1628 BufferedImage rep = createBufferedImage(img.getWidth(null), img.getHeight(null)); 1629 Graphics g = rep.createGraphics(); 1630 g.drawImage(img, 0, 0, null); 1631 g.dispose(); 1632 img.flush(); 1633 return rep; 1634 } 1635 1636 1637 private static final BufferedImage createBufferedImage(int width, int height) { 1638 ColorModel model = GraphicsEnvironment.getLocalGraphicsEnvironment(). 1639 getDefaultScreenDevice().getDefaultConfiguration().getColorModel(Transparency.BITMASK); 1640 BufferedImage buffImage = new BufferedImage (model, 1641 model.createCompatibleWritableRaster(width, height), model.isAlphaPremultiplied(), null); 1642 return buffImage; 1643 } 1644 1645 1646 1647} 1648 | Popular Tags |