|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.explorer.propertysheet; import java.awt.BorderLayout; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.KeyboardFocusManager; import javax.swing.JFrame; import java.util.StringTokenizer; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import org.openide.explorer.propertysheet.PropertySheet; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import org.openide.*; import org.openide.nodes.*; import org.openide.explorer.propertysheet.*; import org.openide.explorer.propertysheet.editors.*; import java.beans.*; import java.beans.PropertyVetoException; import java.io.File; import java.lang.ref.WeakReference; import java.lang.reflect.*; import javax.swing.*; import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import junit.framework.*; import junit.textui.TestRunner; import org.netbeans.junit.*; import org.openide.ErrorManager; import org.openide.util.Lookup; /* A comprehensive test of CustomEditorDisplayer */ public class CustomEditorDisplayerTest extends NbTestCase { static { org.netbeans.core.NonGui.registerPropertyEditors(); } public CustomEditorDisplayerTest(String name) { super(name); } public static void main(String args[]) { // LookAndFeel lf = UIManager.getLookAndFeel(); /* try { UIManager.setLookAndFeel(new com.jgoodies.plaf.plastic.Plastic3DLookAndFeel()); } catch (Exception e) { e.printStackTrace(); } */ TestRunner.run(suite ()); /* boolean go=false; try { UIManager.setLookAndFeel(new PseudoWindowsLookAndFeel()); go = true; } catch (NoClassDefFoundError e) { System.err.println("Couldn't run tests on windows look and feel"); } catch (UnsupportedLookAndFeelException e) { System.err.println("Couldn't run tests on windows look and feel"); } if (go) { TestRunner.run(suite ()); } go=false; try { UIManager.setLookAndFeel(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel()); go = true; } catch (NoClassDefFoundError e) { System.err.println("Couldn't run tests on GTK look and feel"); e.printStackTrace(); } catch (UnsupportedLookAndFeelException e) { System.err.println("Couldn't run tests on GTK look and feel"); e.printStackTrace(); } if (go) { TestRunner.run(suite ()); } try { UIManager.setLookAndFeel(lf); } catch (Exception e) { //highly unlikely } */ try { // new CustomEditorDisplayerTest("goo").setUp(); } catch (Exception e){} } static int idx = -1; public static Test suite() { return new CustomEditorDisplayerSuite (); } private static class CustomEditorDisplayerSuite extends NbTestSuite { public CustomEditorDisplayerSuite () { super (CustomEditorDisplayerTest.class); } public void run (final TestResult tr) { super.run (tr); } } /* * This test creates a Property, Editor and Node. First test checks if initialized * editor contains the same value as property. The second checks if the property * value is changed if the same change will be done in the editor. */ CustomEditorDisplayer basicRen; CustomEditorDisplayer fileRen; private TNode tn; private BasicProperty basicProp; private FileProperty fileProp; private BasicEditor te; private boolean setup=false; private JFrame jf=null; private JPanel jp=null; private int SLEEP_LENGTH=10; protected void tearDown() { if (jf != null) { jf.hide(); jf.dispose(); } } protected void setUp() throws Exception { // UIManager.setLookAndFeel(new com.sun.java.swing.plaf.windows.WindowsLookAndFeel()); // UIManager.setLookAndFeel(new com.sun.java.swing.plaf.gtk.GTKLookAndFeel()); try { if (setup) return; basicProp= new BasicProperty("basicProp", true); fileProp= new FileProperty("FileProp", true); // Create new BasicEditor te = new BasicEditor(); // Create new TNode tn = new TNode(); System.err.println("Crating frame"); jf = new JFrame(); jf.getContentPane().setLayout(new BorderLayout()); jp = new JPanel(); jp.setLayout(new FlowLayout()); jf.getContentPane().add(jp, BorderLayout.CENTER); jf.setLocation (20,20); jf.setSize (600, 200); synchronized (jp.getTreeLock()) { System.err.println("BasicProp = " + basicProp); basicRen = new CustomEditorDisplayer(basicProp); fileRen = new CustomEditorDisplayer(fileProp); jp.add(basicRen.getComponent()); jp.add(fileRen.getComponent()); } System.err.println("Waiting for window"); new WaitWindow(jf); //block until window open System.err.println("Window shown"); } catch (Exception e) { e.printStackTrace(); } finally { setup = true; } } public void testEntryInCustomEditor() throws Exception { //Just types into the value field and presses basicRen.setUpdatePolicy(PropertyDisplayer.UPDATE_ON_CONFIRMATION); BasicCustomEditor custom = (BasicCustomEditor)basicProp.getPropertyEditor().getCustomEditor(); clickOn(custom.valueField); typeKey(custom.valueField, KeyEvent.VK_W); typeKey(custom.valueField, KeyEvent.VK_O); typeKey(custom.valueField, KeyEvent.VK_O); typeKey(custom.valueField, KeyEvent.VK_G); typeKey(custom.valueField, KeyEvent.VK_L); typeKey(custom.valueField, KeyEvent.VK_E); Object pre = basicProp.getValue(); pressKey(custom.valueField, KeyEvent.VK_ENTER); Object post = basicProp.getValue(); assertTrue ("After entering text in editor, value should be the text. Expected WOOGLE got " + post, "WOOGLE".equals(post)); assertNotSame("After entering data in the custom editor and pressing enter with policy UPDATE_ON_CONFIRMATION, property value should be changed", pre, post); basicRen.setUpdatePolicy(PropertyDisplayer.UPDATE_ON_EXPLICIT_REQUEST); clickOn(custom.valueField); typeKey(custom.valueField, KeyEvent.VK_N); typeKey(custom.valueField, KeyEvent.VK_I); typeKey(custom.valueField, KeyEvent.VK_F); typeKey(custom.valueField, KeyEvent.VK_T); typeKey(custom.valueField, KeyEvent.VK_Y); pre = basicProp.getValue(); pressKey(custom.valueField, KeyEvent.VK_ENTER); post = basicProp.getValue(); assertTrue ("After entering text in editor with policy UPDATE_ON_EXPLICIT_REQUEST, the property value should not be the entered text. Expected NIFTY got " + post, "WOOGLE".equals(post)); assertSame("After entering data in the custom editor and pressing enter with policy UPDATE_ON_EXPLICIT_REQUEST, property value should NOT be changed", pre, post); } public void testFailureModes() throws Exception { basicRen.setUpdatePolicy(PropertyDisplayer.UPDATE_ON_CONFIRMATION); BasicCustomEditor custom = (BasicCustomEditor)basicProp.getPropertyEditor().getCustomEditor(); custom.setInvalidValueButton.doClick(); sleep(); sleep(); requestFocus(custom.valueField); IllegalArgumentException iae=null; try { pressKey(custom.valueField, KeyEvent.VK_ENTER); } catch (IllegalArgumentException e) { iae = e; } assertNotNull("Entering a bad value should throw an exception", iae); iae = null; custom.setDontAllowValidateButton.doClick(); sleep(); sleep(); requestFocus(custom.valueField); try { pressKey(custom.valueField, KeyEvent.VK_ENTER); } catch (IllegalArgumentException e) { iae = e; } assertNotNull("If a state change on the PropertyEnv causes a PropertyVetoException, an illegal argument exception should be thrown with the message from the PVE", iae); iae = null; BasicEditor editor = (BasicEditor) basicRen.getPropertyEditor(); PropertyEnv env = basicRen.getPropertyEnv(); assertEquals("After a failure to validate, the editor's property env's state should be STATE_INVALID", PropertyEnv.STATE_INVALID, env.getState()); assertSame("After a failure to validate, the PropertyEnv the editor is talking to should be the one owned by the CustomEditorDisplayer", env, editor.env); } public void testValidationMethods() throws Exception { basicRen.setUpdatePolicy(PropertyDisplayer.UPDATE_ON_EXPLICIT_REQUEST); BasicCustomEditor custom = (BasicCustomEditor)basicProp.getPropertyEditor().getCustomEditor(); clickOn(custom.valueField); typeKey(custom.valueField, KeyEvent.VK_F); typeKey(custom.valueField, KeyEvent.VK_U); typeKey(custom.valueField, KeyEvent.VK_N); typeKey(custom.valueField, KeyEvent.VK_K); typeKey(custom.valueField, KeyEvent.VK_Y); pressKey(custom.valueField, KeyEvent.VK_ENTER); assertTrue("After entering text with update policy UPDATE_ON_EXPLICIT_REQUEST, isValueModified should return true", basicRen.isValueModified()); String legality = basicRen.isModifiedValueLegal(); assertTrue("After entering a legal value with update policy UPDATE_ON_EXPLICIT_REQUEST, isModifiedValueLegal should return null but returned " + legality, legality == null); Exception e = null; try { basicRen.commit(); } catch (Exception e1) { e = e1; } assertNull("Committing a legal value should not throw an exception", e); assertEquals("Calling commit() with update policy UPDATE_ON_EXPLICIT_REQUEST should store the edited value in the property", "FUNKY", basicProp.getValue()); assertTrue("After committing a legal value, isValueModified should return false", !basicRen.isValueModified()); assertNull("After committing a legal value, isModifiedValueLegal should return null", basicRen.isModifiedValueLegal()); custom.setDontAllowValidateButton.doClick(); sleep(); sleep(); try { pressKey(custom.valueField, KeyEvent.VK_ENTER); } catch (Exception e2) { } assertNotNull("With an unvalidatable value, isModifiedValueLegal should return a localized message", basicRen.isModifiedValueLegal()); assertTrue("With an unvalidatable value, isValueModified should return true", basicRen.isValueModified()); custom.valueField.setText("foo goo"); custom.setDontAllowValidateButton.doClick(); sleep(); sleep(); try { basicRen.commit(); } catch (Exception e3) { e = e3; } assertNotNull("Committing an unvalidatable value should throw an exception", e); } private class FL implements FocusListener { private FocusEvent gainedEvent=null; private FocusEvent lostEvent=null; private int gainedCount=0; private int lostCount=0; public void assertGained() { assertNotNull ("No focus gained received after clicking on an editable renderer", gainedEvent); assertTrue("Received wrong number of focus gained events for a single click on a renderer " + gainedCount, gainedCount == 1); } public void assertLost() { assertNotNull ("No focus lost event received after clicking away from a focused, editable renderer", lostEvent); assertTrue("Received wrong number of focus lost events for a single click away from a focused renderer" + lostCount, lostCount == 1); } public void focusGained(java.awt.event.FocusEvent e) { gainedEvent = e; gainedCount++; } public void focusLost(java.awt.event.FocusEvent e) { lostEvent = e; lostCount++; } } private class CL implements ChangeListener { private ChangeEvent e; public void assertEvent(String msg) { sleep(); //give the event time to happen assertNotNull (msg, e); e = null; } public void assertNoEvent(String msg) { sleep(); assertNull (e); e = null; } public void stateChanged(ChangeEvent e) { this.e = e; } } private static class TestGCVal extends Object { public String toString() { return "TestGCVal"; } } private static class WaitWindow extends WindowAdapter { boolean shown=false; public WaitWindow (JFrame f) { f.addWindowListener(this); f.show(); if (!shown) { synchronized(this) { try { //System.err.println("Waiting for window"); wait(5000); } catch (Exception e) {} } } } public void windowOpened(WindowEvent e) { shown = true; synchronized(this) { //System.err.println("window opened"); notifyAll(); ((JFrame) e.getSource()).removeWindowListener(this); } } } private void sleep() { //useful when running interactively try { Thread.currentThread().sleep(SLEEP_LENGTH); } catch (InterruptedException ie) { //go away } //runs faster -uncomment for production use try { //jf.getTreeLock().wait(); SwingUtilities.invokeAndWait(new Runnable() { public void run() { System.currentTimeMillis(); } }); //jf.getTreeLock().wait(); SwingUtilities.invokeAndWait(new Runnable() { public void run() { System.currentTimeMillis(); } }); } catch (Exception e) { } } private void requestFocus(final JComponent jc) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { jc.requestFocus(); } }); sleep(); } private void changeProperty (final RendererPropertyDisplayer ren, final Node.Property newProp) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { ren.setProperty(newProp); } }); } private void clickOn (final JComponent ren, final int fromRight, final int fromTop) throws Exception { SwingUtilities.invokeAndWait (new Runnable() { public void run() { Point toClick = new Point(ren.getWidth() - fromRight, fromTop); Component target=ren.getComponentAt(toClick); toClick = SwingUtilities.convertPoint(ren, toClick, target); System.err.println("Target component is " + target.getClass().getName() + " - " + target + " clicking at " + toClick); MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); target.dispatchEvent(me); me = new MouseEvent (target, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); target.dispatchEvent(me); me = new MouseEvent (target, MouseEvent.MOUSE_CLICKED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); } }); sleep(); } private void clickOn (final JComponent ren) throws Exception { SwingUtilities.invokeAndWait (new Runnable() { public void run() { Point toClick = new Point(5,5); Component target=ren.getComponentAt(toClick); MouseEvent me = new MouseEvent (target, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), MouseEvent.BUTTON1_MASK, toClick.x, toClick.y, 2, false); target.dispatchEvent(me); } }); sleep(); } private void setEnabled(final CustomEditorDisplayer ren,final boolean val) throws Exception { SwingUtilities.invokeAndWait (new Runnable() { public void run() { ren.setEnabled(val); } }); sleep(); } private Exception throwMe = null; private String flushResult = null; private String flushValue(final CustomEditorDisplayer ren) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { try { //flushResult = ren.flushValue(); } catch (Exception e) { throwMe = e; flushResult = null; } } }); if (throwMe != null) { try { throw throwMe; } finally { throwMe = null; } } return flushResult; } private void releaseKey (final Component target, final int key) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), 0, key, (char) key); target.dispatchEvent(ke); } }); sleep(); } private Exception throwMe2 = null; private void pressKey (final Component target, final int key) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, key, (char) key); try { target.dispatchEvent(ke); } catch (Exception e) { throwMe2 = e; } } }); sleep(); if (throwMe2 != null) { Exception e1 = throwMe2; throwMe2 = null; throw e1; } } private void shiftPressKey (final Component target, final int key) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), KeyEvent.SHIFT_MASK, key, (char) key); target.dispatchEvent(ke); } }); sleep(); } private void typeKey (final Component target, final int key) throws Exception { SwingUtilities.invokeAndWait(new Runnable() { public void run() { KeyEvent ke = new KeyEvent (target, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, (char) key); target.dispatchEvent(ke); } }); sleep(); } //Node definition public class TNode extends AbstractNode { //create Node public TNode() { super (Children.LEAF); setName("TNode"); // or, super.setName if needed setDisplayName("TNode"); createSheet(); } //clone existing Node public Node cloneNode() { return new TNode(); } public void addProp (Node.Property p) { props.put(p); this.firePropertyChange(PROP_PROPERTY_SETS, null, null); this.firePropertySetsChange(null, null); } Sheet sheet=null; Sheet.Set props=null; // Create a property sheet: protected Sheet createSheet() { sheet = super.createSheet(); // Make sure there is a "Properties" set: props = sheet.get(Sheet.PROPERTIES); if (props == null) { props = Sheet.createPropertiesSet(); sheet.put(props); } props.put(basicProp); props.put(fileProp); return sheet; } // Method firing changes public void fireMethod(String s, Object o1, Object o2) { firePropertyChange(s,o1,o2); } } // Property definition public class BasicProperty extends PropertySupport { private Object myValue = "Value"; // Create new Property public BasicProperty(String name, boolean isWriteable) { super(name, Object.class, name, "", true, isWriteable); } // get property value public Object getValue() { return myValue; } // set property value public void setValue(Object value) throws IllegalArgumentException,IllegalAccessException, InvocationTargetException { System.err.println("BASICPROP setValue to " + value + " (was " + myValue+")"); Object oldVal = myValue; myValue = value; tn.fireMethod(getName(), oldVal, myValue); } // get the property editor public PropertyEditor getPropertyEditor() { return te; } } // Property definition public class FileProperty extends PropertySupport { private Object myValue = new File("aFile"); // Create new Property public FileProperty(String name, boolean isWriteable) { super(name, File.class, name, "", true, isWriteable); } // get property value public Object getValue() { return myValue; } // set property value public void setValue(Object value) throws IllegalArgumentException,IllegalAccessException, InvocationTargetException { Object oldVal = myValue; myValue = value; tn.fireMethod(getName(), oldVal, myValue); } } // Editor definition public class BasicEditor extends PropertyEditorSupport implements ExPropertyEditor, PropertyChangeListener, VetoableChangeListener { PropertyEnv env; // Create new BasicEditor public BasicEditor() { } /* * This method is called by the IDE to pass * the environment to the property editor. */ public void attachEnv(PropertyEnv env) { if (env != null) { env.removeVetoableChangeListener(this); } this.env = env; env.setState(env.STATE_VALID); env.addVetoableChangeListener(this); System.err.println(" ATTACHENV"); } // Set that this Editor doesn't support custom Editor public boolean supportsCustomEditor() { return true; } // Set the Property value threw the Editor public void setValue(Object newValue) { System.err.println(" BasicEditor.setValue: " + newValue); super.setValue(newValue); } public String getAsText() { return getValue() == null ? "null" : getValue().toString(); } private Component custom; public Component getCustomEditor() { if (custom == null) { custom = new BasicCustomEditor(this); } return custom; } public void vetoNext() { env.setState(env.STATE_NEEDS_VALIDATION); vetoNextChange = true; System.err.println(" veto next"); } public void propertyChange(PropertyChangeEvent evt) { } boolean vetoNextChange=false; public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException { System.err.println("GOT A VETOABLE CHANGE IN BASIC EDITOR"); PropertyEnv env = (PropertyEnv) e.getSource(); if ((vetoNextChange || "Dont allow validate".equals(getAsText())) && PropertyEnv.STATE_NEEDS_VALIDATION.equals(env.getState())) { System.err.println(" VETOING"); PropertyVetoException pve = new PropertyVetoException("NoNoNoNoNo", e); ErrorManager.getDefault().annotate(pve, ErrorManager.USER, null, "You can't do that!", null, null); vetoNextChange=false; throw pve; } } public void setAsText(String s) { System.err.println(" BasicEditor.setAsText: " + s); if ("invalidValue".equals(s)) { IllegalArgumentException iae = new IllegalArgumentException(); ErrorManager.getDefault().annotate(iae, ErrorManager.USER, "invalid value", "No way", null, null); throw iae; } setValue(s); } } public class BasicCustomEditor extends JPanel implements ActionListener { JTextField valueField=new JTextField(); JButton setInvalidValueButton = new JButton("Invalid value"); JButton setDontAllowValidateButton = new JButton("Dont allow validate"); BasicEditor editor; public BasicCustomEditor(BasicEditor editor) { this.editor = editor; init(); } private void init() { setLayout(new FlowLayout()); valueField.addActionListener(this); setInvalidValueButton.addActionListener(this); setDontAllowValidateButton.addActionListener(this); valueField.setColumns(30); setBackground(Color.ORANGE); add (valueField); add (setInvalidValueButton); add (setDontAllowValidateButton); } boolean processing; public void actionPerformed(ActionEvent e) { processing = true; try { if (e.getSource() == setDontAllowValidateButton) { editor.vetoNext(); valueField.setText("dont allow validate"); } if (e.getSource() == setInvalidValueButton) { valueField.setText("invalidValue"); } if (e.getSource() == valueField) { editor.setAsText(valueField.getText()); } editor.env.setState(PropertyEnv.STATE_NEEDS_VALIDATION); } finally { processing = false; } } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.