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.FlowLayout ; 27 import java.awt.Graphics ; 28 import java.awt.Point ; 29 import java.awt.event.FocusEvent ; 30 import java.awt.event.FocusListener ; 31 import java.awt.event.KeyEvent ; 32 import java.awt.event.MouseEvent ; 33 import java.awt.event.WindowAdapter ; 34 import java.awt.event.WindowEvent ; 35 import java.beans.PropertyEditor ; 36 import java.beans.PropertyEditorSupport ; 37 import java.lang.reflect.InvocationTargetException ; 38 import javax.swing.Icon ; 39 import javax.swing.JFrame ; 40 import javax.swing.JLabel ; 41 import javax.swing.JPanel ; 42 import javax.swing.SwingUtilities ; 43 import javax.swing.event.ChangeEvent ; 44 import javax.swing.event.ChangeListener ; 45 import org.netbeans.junit.NbTestCase; 46 import org.netbeans.modules.openide.explorer.UIException; 47 import org.openide.ErrorManager; 48 import org.openide.nodes.AbstractNode; 49 import org.openide.nodes.Children; 50 import org.openide.nodes.Node; 51 import org.openide.nodes.PropertySupport; 52 import org.openide.nodes.Sheet; 53 54 55 public class EditorDisplayerTest extends NbTestCase { 56 57 static { 58 ComboTest.registerPropertyEditors(); 59 } 60 61 public EditorDisplayerTest(String name) { 62 super(name); 63 } 64 65 128 129 134 135 EditorPropertyDisplayer basicRen; 136 EditorPropertyDisplayer tagsRen1; 137 EditorPropertyDisplayer tagsRen2; 138 EditorPropertyDisplayer tagsRen3; 139 EditorPropertyDisplayer boolRen; 140 EditorPropertyDisplayer custRen; 141 EditorPropertyDisplayer custRen2; 142 EditorPropertyDisplayer exRen; 143 EditorPropertyDisplayer numRen; 144 EditorPropertyDisplayer edRen; 145 146 private TNode tn; 147 private BasicProperty basicProp; 148 private TagsProperty tags1; 149 private TagsProperty tags2; 150 private TagsProperty tags3; 151 private BooleanProperty booleanProp; 152 private EditorCustom ec; 153 private CustomProperty customProp; 154 private CustomProperty customProp2; 155 private BasicEditor te; 156 private boolean setup=false; 157 private JFrame jf=null; 158 private JPanel jp=null; 159 private int SLEEP_LENGTH=10; 160 161 protected void tearDown() { 162 if (jf != null) { 163 jf.hide(); 164 jf.dispose(); 165 } 166 } 167 168 protected void setUp() throws Exception { 169 172 try { 173 if (setup) return; 174 basicProp= new BasicProperty("basicProp", true); 175 System.err.println("Created basicProp at " + System.currentTimeMillis() + " - " + basicProp); 176 177 tags1 = new TagsProperty("tags1", true, new String [] {"What","is","the","meaning","of","life"}); 178 tags2 = new TagsProperty("tags2", true, new String [] {"Austrolopithecines","automatically","engender","every","one"}); 179 tags3 = new TagsProperty("tags3", true, new String [] {"Behold","the","power","of","cheese"}); 180 booleanProp = new BooleanProperty("booleanProp", true); 181 customProp = new CustomProperty("CustomProp", true); 182 customProp2 = new CustomProperty("CustomProp2", true); 183 ExceptionProperty exProp = new ExceptionProperty("Exception prop", true); 184 NumProperty numProp = new NumProperty("Int prop", true); 185 EditableNumProperty edProp = new EditableNumProperty("Editable", true); 186 187 188 te = new BasicEditor(); 190 ec = new EditorCustom(); 191 tn = new TNode(); 193 194 System.err.println("Crating frame"); 195 jf = new JFrame (); 196 jf.getContentPane().setLayout(new BorderLayout ()); 197 jp = new JPanel (); 198 jp.setLayout(new FlowLayout ()); 199 jf.getContentPane().add(jp, BorderLayout.CENTER); 200 jf.setLocation(20,20); 201 jf.setSize(600, 200); 202 203 synchronized (jp.getTreeLock()) { 204 System.err.println("BasicProp = " + basicProp); 205 206 basicRen = new EditorPropertyDisplayer(basicProp); 207 tagsRen1 = new EditorPropertyDisplayer(tags1); 208 tagsRen2 = new EditorPropertyDisplayer(tags2); 209 tagsRen3 = new EditorPropertyDisplayer(tags3); 210 boolRen = new EditorPropertyDisplayer(booleanProp); 211 custRen = new EditorPropertyDisplayer(customProp); 212 custRen2 = new EditorPropertyDisplayer(customProp2); 213 exRen = new EditorPropertyDisplayer(exProp); 214 numRen = new EditorPropertyDisplayer(numProp); 215 edRen = new EditorPropertyDisplayer(edProp); 216 217 tagsRen2.setRadioButtonMax(10); 218 219 jp.add(basicRen); 220 jp.add(tagsRen1); 221 jp.add(tagsRen2); 222 jp.add(tagsRen3); 223 jp.add(boolRen); 224 jp.add(custRen); 225 jp.add(custRen2); 226 jp.add(exRen); 227 jp.add(numRen); 228 jp.add(edRen); 229 } 230 231 System.err.println("Waiting for window"); 232 new WaitWindow(jf); System.err.println("Window shown"); 234 } catch (Exception e) { 235 e.printStackTrace(); 236 } finally { 237 setup = true; 238 } 239 } 240 241 public void testEverything() throws Exception { 242 try { 243 System.err.println("running"); 244 clickOn(basicRen); 245 sleep(); 246 sleep(); 247 sleep(); 248 tagsRen2.setRadioButtonMax(2); 249 System.err.println("set to 2"); 250 sleep(); 251 sleep(); 252 sleep(); 253 tagsRen2.setRadioButtonMax(10); 254 255 } catch (Exception e) { 256 e.printStackTrace(); 257 258 259 } finally { 260 setup = true; 261 } 264 } 265 266 private class FL implements FocusListener { 267 private FocusEvent gainedEvent=null; 268 private FocusEvent lostEvent=null; 269 private int gainedCount=0; 270 private int lostCount=0; 271 public void assertGained() { 272 assertNotNull("No focus gained received after clicking on an editable renderer", gainedEvent); 273 assertTrue("Received wrong number of focus gained events for a single click on a renderer " + gainedCount, gainedCount == 1); 274 } 275 276 public void assertLost() { 277 assertNotNull("No focus lost event received after clicking away from a focused, editable renderer", lostEvent); 278 assertTrue("Received wrong number of focus lost events for a single click away from a focused renderer" + lostCount, lostCount == 1); 279 } 280 281 public void focusGained(FocusEvent e) { 282 gainedEvent = e; 283 gainedCount++; 284 } 285 286 public void focusLost(FocusEvent e) { 287 lostEvent = e; 288 lostCount++; 289 } 290 } 291 292 private class CL implements ChangeListener { 293 294 private ChangeEvent e; 295 public void assertEvent(String msg) { 296 sleep(); assertNotNull(msg, e); 298 e = null; 299 } 300 301 public void assertNoEvent(String msg) { 302 sleep(); 303 assertNull(e); 304 e = null; 305 } 306 307 public void stateChanged(ChangeEvent e) { 308 this.e = e; 309 } 310 311 } 312 313 private static class TestGCVal extends Object { 314 public String toString() { 315 return "TestGCVal"; 316 } 317 } 318 319 private static class WaitWindow extends WindowAdapter { 320 boolean shown=false; 321 public WaitWindow(JFrame f) { 322 f.addWindowListener(this); 323 f.show(); 324 if (!shown) { 325 synchronized(this) { 326 try { 327 wait(5000); 329 } catch (Exception e) {} 330 } 331 } 332 } 333 334 public void windowOpened(WindowEvent e) { 335 shown = true; 336 synchronized(this) { 337 notifyAll(); 339 ((JFrame ) e.getSource()).removeWindowListener(this); 340 } 341 } 342 } 343 344 private void sleep() { 345 347 try { 348 Thread.currentThread().sleep(SLEEP_LENGTH); 349 } catch (InterruptedException ie) { 350 } 352 353 354 355 357 try { 358 SwingUtilities.invokeAndWait(new Runnable () { 360 public void run() { 361 System.currentTimeMillis(); 362 } 363 }); 364 SwingUtilities.invokeAndWait(new Runnable () { 366 public void run() { 367 System.currentTimeMillis(); 368 } 369 }); 370 } catch (Exception e) { 371 } 372 373 374 } 375 376 private void changeProperty(final RendererPropertyDisplayer ren, final Node.Property newProp) throws Exception { 377 SwingUtilities.invokeAndWait(new Runnable () { 378 public void run() { 379 ren.setProperty(newProp); 380 } 381 }); 382 } 383 384 private void clickOn(final EditorPropertyDisplayer ren, final int fromRight, final int fromTop) throws Exception { 385 SwingUtilities.invokeAndWait(new Runnable () { 386 public void run() { 387 Point toClick = new Point (ren.getWidth() - fromRight, fromTop); 388 Component target=ren.getComponentAt(toClick); 389 toClick = SwingUtilities.convertPoint(ren, toClick, target); 390 System.err.println("Target component is " + target.getClass().getName() + " - " + target + " clicking at " + toClick); 391 392 MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 393 target.dispatchEvent(me); 394 me = new MouseEvent (target, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 395 target.dispatchEvent(me); 396 me = new MouseEvent (target, MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 397 } 398 }); 399 sleep(); 400 } 401 402 private void clickOn(final EditorPropertyDisplayer ren) throws Exception { 403 SwingUtilities.invokeAndWait(new Runnable () { 404 public void run() { 405 Point toClick = new Point (5,5); 406 Component target=ren.getComponentAt(toClick); 407 MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); 408 target.dispatchEvent(me); 409 } 410 }); 411 sleep(); 412 } 413 414 private void setEnabled(final EditorPropertyDisplayer ren,final boolean val) throws Exception { 415 SwingUtilities.invokeAndWait(new Runnable () { 416 public void run() { 417 ren.setEnabled(val); 418 } 419 }); 420 sleep(); 421 } 422 423 private Exception throwMe = null; 424 private String flushResult = null; 425 private String flushValue(final EditorPropertyDisplayer ren) throws Exception { 426 SwingUtilities.invokeAndWait(new Runnable () { 427 public void run() { 428 try { 429 } catch (Exception e) { 431 throwMe = e; 432 flushResult = null; 433 } 434 } 435 }); 436 if (throwMe != null) { 437 try { 438 throw throwMe; 439 } finally { 440 throwMe = null; 441 } 442 } 443 return flushResult; 444 } 445 446 447 private void releaseKey(final Component target, final int key) throws Exception { 448 SwingUtilities.invokeAndWait(new Runnable () { 449 public void run() { 450 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), 0, key, (char) key); 451 target.dispatchEvent(ke); 452 } 453 }); 454 sleep(); 455 } 456 457 private void pressKey(final Component target, final int key) throws Exception { 458 SwingUtilities.invokeAndWait(new Runnable () { 459 public void run() { 460 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, key, (char) key); 461 target.dispatchEvent(ke); 462 } 463 }); 464 sleep(); 465 } 466 467 private void shiftPressKey(final Component target, final int key) throws Exception { 468 SwingUtilities.invokeAndWait(new Runnable () { 469 public void run() { 470 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.SHIFT_MASK, key, (char) key); 471 target.dispatchEvent(ke); 472 } 473 }); 474 sleep(); 475 } 476 477 478 private void typeKey(final Component target, final int key) throws Exception { 479 SwingUtilities.invokeAndWait(new Runnable () { 480 public void run() { 481 KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, (char) key); 482 target.dispatchEvent(ke); 483 } 484 }); 485 sleep(); 486 } 487 488 public class TNode extends AbstractNode { 490 public TNode() { 492 super(Children.LEAF); 493 setName("TNode"); setDisplayName("TNode"); 495 createSheet(); 496 } 497 public Node cloneNode() { 499 return new TNode(); 500 } 501 502 public void addProp(Node.Property p) { 503 props.put(p); 504 this.firePropertyChange(PROP_PROPERTY_SETS, null, null); 505 this.firePropertySetsChange(null, null); 506 } 507 508 Sheet sheet=null; 509 Sheet.Set props=null; 510 protected Sheet createSheet() { 512 sheet = super.createSheet(); 513 props = sheet.get(Sheet.PROPERTIES); 515 if (props == null) { 516 props = Sheet.createPropertiesSet(); 517 sheet.put(props); 518 } 519 props.put(basicProp); 520 props.put(tags1); 521 props.put(tags2); 522 props.put(tags3); 523 props.put(booleanProp); 524 props.put(customProp); 525 526 return sheet; 527 } 528 public void fireMethod(String s, Object o1, Object o2) { 530 firePropertyChange(s,o1,o2); 531 } 532 } 533 534 public class BasicProperty extends PropertySupport { 536 private Object myValue = "Value"; 537 public BasicProperty(String name, boolean isWriteable) { 539 super(name, Object .class, name, "", true, isWriteable); 540 } 541 public Object getValue() { 543 return myValue; 544 } 545 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 547 Object oldVal = myValue; 548 myValue = value; 549 tn.fireMethod(getName(), oldVal, myValue); 550 } 551 public PropertyEditor getPropertyEditor() { 553 return te; 554 } 555 } 556 557 public class BasicEditor extends PropertyEditorSupport implements ExPropertyEditor { 559 PropertyEnv env; 560 561 public BasicEditor() { 563 } 564 565 569 public void attachEnv(PropertyEnv env) { 570 this.env = env; 571 } 572 573 public boolean supportsCustomEditor() { 575 return false; 576 } 577 578 public void setValue(Object newValue) { 580 super.setValue(newValue); 581 } 582 583 public String getAsText() { 584 return getValue() == null ? "null" : getValue().toString(); 585 } 586 } 587 588 589 private static class PseudoWindowsLookAndFeel extends WindowsLookAndFeel { 590 public boolean isSupportedLookAndFeel() { 591 return true; 592 } 593 } 594 595 public class TagsEditor extends PropertyEditorSupport implements ExPropertyEditor { 596 PropertyEnv env; 597 String [] tags; 598 public TagsEditor(String [] tags) { 599 this.tags = tags; 600 } 601 602 public String [] getTags() { 603 return tags; 604 } 605 606 public void attachEnv(PropertyEnv env) { 607 this.env = env; 608 } 609 610 public boolean supportsCustomEditor() { 611 return false; 612 } 613 614 public void setValue(Object newValue) { 615 super.setValue(newValue); 616 } 617 618 619 } 620 621 public class TagsProperty extends PropertySupport { 623 private Object myValue = "Value"; 624 private String [] tags; 625 public TagsProperty(String name, boolean isWriteable, String [] tags) { 627 super(name, Object .class, name, "", true, isWriteable); 628 this.tags = tags; 629 } 630 public Object getValue() { 632 return myValue; 633 } 634 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 636 Object oldVal = myValue; 637 myValue = value; 638 tn.fireMethod(getName(), oldVal, myValue); 639 } 640 public PropertyEditor getPropertyEditor() { 642 return new TagsEditor(tags); 643 } 644 645 public String getShortDescription() { 646 return "I have tags!"; 647 } 648 } 649 650 public class BooleanProperty extends PropertySupport { 652 private Boolean myValue = Boolean.FALSE; 653 public BooleanProperty(String name, boolean isWriteable) { 655 super(name, Boolean .class, name, "", true, isWriteable); 656 } 657 public Object getValue() { 659 return myValue; 660 } 661 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 663 Object oldVal = myValue; 664 myValue = (Boolean ) value; 665 tn.fireMethod(getName(), oldVal, myValue); 666 } 667 public Object getValue(String key) { 668 if ("valueIcon".equals(key)) { 669 return new ValueIcon(); 670 } else { 671 return super.getValue(key); 672 } 673 } 674 } 675 676 public class CustomProperty extends PropertySupport { 677 private Object myValue = "Value"; 678 public CustomProperty(String name, boolean isWriteable) { 680 super(name, Object .class, name, "", true, isWriteable); 681 } 682 public Object getValue() { 684 return myValue; 685 } 686 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 688 Object oldVal = myValue; 689 myValue = value; 690 tn.fireMethod(getName(), oldVal, myValue); 691 } 692 public PropertyEditor getPropertyEditor() { 694 return ec; 695 } 696 697 public Object getValue(String key) { 698 if ("valueIcon".equals(key)) { 699 return new ValueIcon(); 700 } else { 701 return super.getValue(key); 702 } 703 } 704 } 705 706 public class ExceptionProperty extends PropertySupport { 707 private Object myValue = "Value"; 708 public ExceptionProperty(String name, boolean isWriteable) { 710 super(name, Object .class, name, "", true, isWriteable); 711 } 712 public Object getValue() { 714 return myValue; 715 } 716 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 718 Object oldVal = myValue; 719 myValue = value; 720 tn.fireMethod(getName(), oldVal, myValue); 721 } 722 public PropertyEditor getPropertyEditor() { 724 return exed; 725 } 726 } 727 728 private ExEditor exed = new ExEditor(); 729 public static class ExEditor extends PropertyEditorSupport { 730 private Object myVal="Value"; 731 public ExEditor() {} 732 public void setAsText(String val) { 733 if (val.equals("Value")) { 735 myVal = val; 736 } else { 737 IllegalArgumentException iae = new IllegalArgumentException ("No!"); 738 UIException.annotateUser(iae, "NoNo!", "Localized message", null, 739 null); 740 throw iae; 741 } 742 } 743 744 public void setValue(Object newValue) { 745 myVal = newValue; 746 firePropertyChange(); 747 } 748 749 public Object getValue() { 750 return "Value"; 751 } 752 } 753 754 755 public class EditorCustom extends PropertyEditorSupport implements ExPropertyEditor { 757 PropertyEnv env; 758 759 public EditorCustom() { 761 } 762 763 767 public void attachEnv(PropertyEnv env) { 768 this.env = env; 769 env.setState(env.STATE_INVALID); 770 } 771 772 public boolean supportsCustomEditor() { 774 return true; 775 } 776 777 public void setValue(Object newValue) { 779 super.setValue(newValue); 780 } 781 782 public String getAsText() { 783 return getValue() == null ? "null" : getValue().toString(); 784 } 785 786 public Component getCustomEditor() { 787 return new JPanel (); 788 } 789 } 790 791 public class NumProperty extends PropertySupport { 792 private Integer myValue = new Integer (4); 793 public NumProperty(String name, boolean isWriteable) { 795 super(name, Integer .class, name, "", true, isWriteable); 796 } 797 public Object getValue() { 799 return myValue; 800 } 801 public void setValue(Object value) throws IllegalArgumentException ,IllegalAccessException , InvocationTargetException { 803 if (!(value instanceof Integer )) { 804 throw new IllegalArgumentException ("Not an integer - " + value); 805 } 806 Object oldVal = myValue; 807 myValue = (Integer ) value; 808 tn.fireMethod(getName(), oldVal, myValue); 809 } 810 public PropertyEditor getPropertyEditor() { 812 return new NumberedTagsEditor(); 813 } 814 } 815 816 public class EditableNumProperty extends TagsProperty { 817 public EditableNumProperty(String name, boolean isWriteable) { 818 super(name, isWriteable, new String []{"boo"}); 819 } 820 821 public PropertyEditor getPropertyEditor() { 822 return new EditorDisplayerTest.EditableTagsEditor(); 823 } 824 } 825 826 827 public class NumberedTagsEditor extends PropertyEditorSupport { 829 private int val=3; 830 public NumberedTagsEditor() { 832 } 833 834 public String [] getTags() { 835 return new String [] {"zero","one","two","three","four","five","six","seven"}; 836 } 837 838 839 public void setValue(Object newValue) { 841 val = ((Integer ) newValue).intValue(); 842 firePropertyChange(); 843 } 844 845 public String getAsText() { 846 return getTags()[((Integer ) getValue()).intValue()]; 847 } 848 849 public void setAsText(String txt) { 850 String [] t = getTags(); 851 for (int i=0; i < t.length; i++) { 852 if (txt.trim().equals(t[i])) { 853 setValue(new Integer (i)); 854 return; 855 } 856 } 857 IllegalArgumentException iae = new IllegalArgumentException (txt); 858 UIException.annotateUser(iae, txt, txt + " is not a valid value", 859 null, null); 860 } 861 862 public Object getValue() { 863 return new Integer (val); 864 } 865 866 public Component getCustomEditor() { 867 return new JPanel (); 868 } 869 } 870 871 public class EditableTagsEditor extends TagsEditor implements ExPropertyEditor { 872 private Object val="woof"; 873 public EditableTagsEditor() { 874 super(new String [] {"miaou","woof","moo","quack"}); 875 } 876 public void attachEnv(PropertyEnv env) { 877 env.getFeatureDescriptor().setValue("canEditAsText", Boolean.TRUE); 878 } 879 public void setAsText(String s) { 880 setValue(s); 881 } 882 public void setValue(Object val) { 883 this.val = val; 884 } 885 public Object getValue() { 886 return val; 887 } 888 public String getAsText() { 889 return val.toString(); 890 } 891 public boolean supportsCustomEditor() { 892 return true; 893 } 894 public Component getCustomEditor() { 895 return new JLabel ("You called?"); 896 } 897 } 898 899 private class ValueIcon implements Icon { 900 901 public int getIconHeight() { 902 return 12; 903 } 904 905 public int getIconWidth() { 906 return 12; 907 } 908 909 public void paintIcon(Component c, Graphics g, int x, int y) { 910 Color col = g.getColor(); 911 try { 912 g.setColor(Color.BLUE); 913 g.drawRect(x, y, getIconWidth(), getIconHeight()); 914 g.fillRect(x+3, y+3, getIconWidth()-5, getIconHeight()-5); 915 } finally { 916 g.setColor(col); 917 } 918 } 919 920 } 921 } 922 | Popular Tags |