element types and an additional property editor. The navigator now shows project, property, target and task nodes. PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268170 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -92,7 +92,7 @@ public class LabelFieldGBC extends GridBagConstraints { | |||
| // Set location to left side. | |||
| gridx = 0; | |||
| // Move it over to be as close to field as possible. | |||
| anchor = EAST; | |||
| anchor = NORTHEAST; | |||
| // Don't take up any extra. | |||
| weightx = 0.0; | |||
| return this; | |||
| @@ -85,7 +85,7 @@ public class ProjectProxy { | |||
| /** The current thread executing a build. */ | |||
| private Thread _buildThread = null; | |||
| /** The selection model for selected targets. */ | |||
| private TargetSelectionModel _selections = null; | |||
| private ElementSelectionModel _selections = null; | |||
| /** | |||
| * File loading ctor. | |||
| @@ -104,7 +104,7 @@ public class ProjectProxy { | |||
| */ | |||
| private void loadProject() throws IOException { | |||
| _project = ACSFactory.getInstance().load(_file); | |||
| _selections = new TargetSelectionModel(); | |||
| _selections = new ElementSelectionModel(); | |||
| _selections.addTreeSelectionListener(new SelectionForwarder()); | |||
| } | |||
| @@ -169,7 +169,7 @@ public class ProjectProxy { | |||
| * | |||
| * @return Selection model. | |||
| */ | |||
| public TreeSelectionModel getTreeSelectionModel() { | |||
| public ElementSelectionModel getTreeSelectionModel() { | |||
| return _selections; | |||
| } | |||
| @@ -209,6 +209,10 @@ public class ProjectProxy { | |||
| } | |||
| } | |||
| /** | |||
| * Run the build. | |||
| * | |||
| */ | |||
| public void run() { | |||
| // Add the build listener for | |||
| // dispatching BuildEvent objects to the | |||
| @@ -255,8 +259,8 @@ public class ProjectProxy { | |||
| /** Forwards selection events to the event bus. */ | |||
| private class SelectionForwarder implements TreeSelectionListener { | |||
| public void valueChanged(TreeSelectionEvent e) { | |||
| _context.getEventBus().postEvent(new TargetSelectionEvent( | |||
| _context, _selections.getSelectedTargets())); | |||
| _context.getEventBus().postEvent(new ElementSelectionEvent( | |||
| _context, _selections.getSelectedElements())); | |||
| } | |||
| } | |||
| @@ -72,6 +72,8 @@ class PropertyEditor extends AntEditor { | |||
| /** The property sheet. */ | |||
| private DynamicCustomizer _customizer = null; | |||
| /** Container for the customizer. */ | |||
| private JPanel _container = null; | |||
| /** | |||
| * Standard ctor. | |||
| @@ -82,23 +84,25 @@ class PropertyEditor extends AntEditor { | |||
| super(context); | |||
| context.getEventBus().addMember(EventBus.MONITORING, new Handler()); | |||
| setLayout(new BorderLayout()); | |||
| _container = new JPanel(new BorderLayout()); | |||
| add(new JScrollPane(_container)); | |||
| } | |||
| /** | |||
| * Update the display for the current item. | |||
| * Update the display for the current items. | |||
| * | |||
| * @param item Current item. | |||
| * @param items Current items to display. | |||
| */ | |||
| private void updateDisplay(ACSElement item) { | |||
| private void updateDisplay(ACSElement[] items) { | |||
| if(_customizer != null) { | |||
| remove(_customizer); | |||
| _container.remove(_customizer); | |||
| _customizer = null; | |||
| } | |||
| if(item != null) { | |||
| _customizer = new DynamicCustomizer(item.getClass(), true); | |||
| _customizer.setObject(item); | |||
| add(BorderLayout.CENTER, _customizer); | |||
| if(items != null) { | |||
| _customizer = new DynamicCustomizer(items[0].getClass()); | |||
| _customizer.setObject(items[0]); | |||
| _container.add(BorderLayout.CENTER, _customizer); | |||
| } | |||
| validate(); | |||
| } | |||
| @@ -124,9 +128,9 @@ class PropertyEditor extends AntEditor { | |||
| * @param event Event to post. | |||
| */ | |||
| public void eventPosted(EventObject event) { | |||
| TargetSelectionEvent e = (TargetSelectionEvent) event; | |||
| ACSTargetElement[] targets = e.getSelectedTargets(); | |||
| updateDisplay(targets.length == 0 ? null : targets[0]); | |||
| ElementSelectionEvent e = (ElementSelectionEvent) event; | |||
| ACSElement[] elements = e.getSelectedElements(); | |||
| updateDisplay(elements); | |||
| } | |||
| } | |||
| @@ -139,7 +143,7 @@ class PropertyEditor extends AntEditor { | |||
| * @return True if event should be given to BusMember, false otherwise. | |||
| */ | |||
| public boolean accept(EventObject event) { | |||
| return event instanceof TargetSelectionEvent; | |||
| return event instanceof ElementSelectionEvent; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,96 +0,0 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.gui; | |||
| import org.apache.tools.ant.gui.acs.ACSTargetElement; | |||
| import javax.swing.tree.DefaultTreeSelectionModel; | |||
| import javax.swing.tree.TreePath; | |||
| import java.util.*; | |||
| /** | |||
| * Selection model for the currently selected targets. | |||
| * | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| */ | |||
| class TargetSelectionModel extends DefaultTreeSelectionModel { | |||
| /** | |||
| * Default ctor. | |||
| * | |||
| */ | |||
| public TargetSelectionModel() { | |||
| setSelectionMode(DISCONTIGUOUS_TREE_SELECTION); | |||
| } | |||
| /** | |||
| * Convenience method for providing the set of currently selected | |||
| * targets. | |||
| * | |||
| * @return the currently selected targets. | |||
| */ | |||
| public ACSTargetElement[] getSelectedTargets() { | |||
| TreePath[] path = getSelectionPaths(); | |||
| List values = new LinkedList(); | |||
| for(int i = 0; path != null && i < path.length; i++) { | |||
| Object val = path[i].getLastPathComponent(); | |||
| if(val instanceof ACSTargetElement) { | |||
| values.add(val); | |||
| } | |||
| } | |||
| ACSTargetElement[] retval = new ACSTargetElement[values.size()]; | |||
| values.toArray(retval); | |||
| return retval; | |||
| } | |||
| } | |||
| @@ -65,6 +65,8 @@ import java.beans.PropertyChangeSupport; | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch */ | |||
| public abstract class ACSElement extends ElementNode { | |||
| /** Name of the 'xmlString' property. */ | |||
| public static final String XML_STRING = "xmlString"; | |||
| /** Event support. */ | |||
| private PropertyChangeSupport _propSupport = null; | |||
| @@ -74,7 +76,6 @@ public abstract class ACSElement extends ElementNode { | |||
| * | |||
| */ | |||
| protected ACSElement() { | |||
| } | |||
| /** | |||
| @@ -86,6 +87,15 @@ public abstract class ACSElement extends ElementNode { | |||
| return getTagName(); | |||
| } | |||
| /** | |||
| * Get the XML representation of this. | |||
| * | |||
| * @return XML representation. | |||
| */ | |||
| public String getXMLString() { | |||
| return toString(); | |||
| } | |||
| /** | |||
| * Add a change listener. | |||
| * | |||
| @@ -62,6 +62,7 @@ import com.sun.xml.tree.SimpleElementFactory; | |||
| import com.sun.xml.tree.XmlDocument; | |||
| import com.sun.xml.tree.XmlDocumentBuilder; | |||
| import java.util.Properties; | |||
| import java.util.Enumeration; | |||
| import com.sun.xml.parser.Resolver; | |||
| /** | |||
| @@ -79,10 +80,25 @@ public class ACSFactory { | |||
| static { | |||
| try { | |||
| // First we bootstrap our knowledge of the Ant tasks by reading | |||
| // in the taskdef definitions and assigning them the default | |||
| // task element class. | |||
| _elementMap.load(org.apache.tools.ant.taskdefs.Ant.class. | |||
| getResourceAsStream("defaults.properties")); | |||
| Enumeration enum = _elementMap.propertyNames(); | |||
| while(enum.hasMoreElements()) { | |||
| String name = (String) enum.nextElement(); | |||
| // XXX the name of the class needs to be stored externally. | |||
| _elementMap.setProperty( | |||
| name, "org.apache.tools.ant.gui.acs.ACSTaskElement"); | |||
| } | |||
| // Then we add/override the local definitions. | |||
| _elementMap.load(ACSFactory.class. | |||
| getResourceAsStream("acs-element.properties")); | |||
| } | |||
| catch(Throwable ex) { | |||
| // If something wrong happens here we can't do much more... | |||
| ex.printStackTrace(); | |||
| System.exit(1); | |||
| } | |||
| @@ -62,8 +62,17 @@ import com.sun.xml.tree.ElementNode; | |||
| * @author Simeon Fitch | |||
| */ | |||
| public class ACSProjectElement extends ACSNamedElement { | |||
| public ACSProjectElement() { | |||
| /** The 'default' property name. */ | |||
| public static final String DEFAULT = "default"; | |||
| /** The 'basdir' property name. */ | |||
| public static final String BASEDIR = "basedir"; | |||
| /** | |||
| * Default ctor. | |||
| * | |||
| */ | |||
| public ACSProjectElement() { | |||
| } | |||
| /** | |||
| @@ -83,4 +92,45 @@ public class ACSProjectElement extends ACSNamedElement { | |||
| public String getDisplayName() { | |||
| return getTagName() + ": " + getName(); | |||
| } | |||
| /** | |||
| * Get the name of the default target. | |||
| * | |||
| * @return Default target name. | |||
| */ | |||
| public String getDefault() { | |||
| return getAttribute(DEFAULT); | |||
| } | |||
| /** | |||
| * Set the name of the default target. | |||
| * | |||
| * @param def Name of the default target. | |||
| */ | |||
| public void setDefault(String def) { | |||
| String old = getDefault(); | |||
| setAttribute(DEFAULT, def); | |||
| firePropertyChange(DEFAULT, old, def); | |||
| } | |||
| /** | |||
| * Get the specified base directory for the build. | |||
| * | |||
| * @return Base directory | |||
| */ | |||
| public String getBasedir() { | |||
| return getAttribute(BASEDIR); | |||
| } | |||
| /** | |||
| * Set the base directory for builds. | |||
| * | |||
| * @param baseDir Build base directory. | |||
| */ | |||
| public void setBasedir(String baseDir) { | |||
| String old = getBasedir(); | |||
| setAttribute(BASEDIR, baseDir); | |||
| firePropertyChange(BASEDIR, old, baseDir); | |||
| } | |||
| } | |||
| @@ -56,7 +56,7 @@ package org.apache.tools.ant.gui.acs; | |||
| import java.beans.*; | |||
| /** | |||
| * BeanInfo for the ACSTargetElement class. | |||
| * BeanInfo for the ACSProjectElement class. | |||
| * | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| @@ -91,9 +91,23 @@ public class ACSProjectElementBeanInfo extends BaseBeanInfo { | |||
| new PropertyDescriptor(ACSProjectElement.NAME, | |||
| ACSProjectElement.class), | |||
| new PropertyDescriptor(ACSProjectElement.DESCRIPTION, | |||
| ACSProjectElement.class), | |||
| new PropertyDescriptor(ACSProjectElement.DEFAULT, | |||
| ACSProjectElement.class), | |||
| new PropertyDescriptor(ACSProjectElement.BASEDIR, | |||
| ACSProjectElement.class) | |||
| }; | |||
| retval[0].setDisplayName(getResources().getString( | |||
| getClass(),ACSProjectElement.NAME)); | |||
| retval[1].setDisplayName(getResources().getString( | |||
| getClass(),ACSProjectElement.DESCRIPTION)); | |||
| retval[2].setDisplayName(getResources().getString( | |||
| getClass(),ACSProjectElement.DEFAULT)); | |||
| retval[3].setDisplayName(getResources().getString( | |||
| getClass(),ACSProjectElement.BASEDIR)); | |||
| setSortingOrder(retval); | |||
| } | |||
| catch(IntrospectionException ex) { | |||
| ex.printStackTrace(); | |||
| @@ -64,6 +64,13 @@ import java.util.StringTokenizer; | |||
| */ | |||
| public class ACSTargetElement extends ACSNamedElement { | |||
| /** Dependency property name. */ | |||
| public static final String DEPENDS = "depends"; | |||
| /** 'if' clause property name. */ | |||
| public static final String IF = "if"; | |||
| /** 'unless' clause property name. */ | |||
| public static final String UNLESS = "unless"; | |||
| /** | |||
| * Default ctor. | |||
| * | |||
| @@ -73,29 +80,85 @@ public class ACSTargetElement extends ACSNamedElement { | |||
| } | |||
| /** | |||
| * Set the set of dependency names. | |||
| * Get the display name. | |||
| * | |||
| * @return Display name. | |||
| */ | |||
| public String getDisplayName() { | |||
| return getTagName() + ": " + getName(); | |||
| } | |||
| /** | |||
| * Get the set of dependency names. | |||
| * | |||
| * @return Dependency names. | |||
| */ | |||
| public String[] getDependencyNames() { | |||
| String depends = getAttribute("depends"); | |||
| public String[] getDepends() { | |||
| String depends = getAttribute(DEPENDS); | |||
| StringTokenizer tok = new StringTokenizer(depends,","); | |||
| String[] retval = new String[tok.countTokens()]; | |||
| for(int i = 0; i < retval.length; i++) { | |||
| retval[i] = tok.nextToken(); | |||
| retval[i] = tok.nextToken().trim(); | |||
| } | |||
| return retval; | |||
| } | |||
| /** | |||
| * Get the display name. | |||
| * Set the list of dependency names. | |||
| * | |||
| * @return Display name. | |||
| * @param depends Dependency names. | |||
| */ | |||
| public String getDisplayName() { | |||
| return getTagName() + ": " + getName(); | |||
| public void setDepends(String[] depends) { | |||
| String old = getAttribute(DEPENDS); | |||
| StringBuffer buf = new StringBuffer(); | |||
| for(int i = 0; depends != null && i < depends.length; i++) { | |||
| buf.append(depends[i]); | |||
| if(i < depends.length - 1) { | |||
| buf.append(", "); | |||
| } | |||
| } | |||
| setAttribute(DEPENDS, buf.toString()); | |||
| firePropertyChange(DEPENDS, old, buf.toString()); | |||
| } | |||
| /** | |||
| * Get the 'if' clause. | |||
| * | |||
| * @return 'if' clause. | |||
| */ | |||
| public String getIf() { | |||
| return getAttribute(IF); | |||
| } | |||
| /** | |||
| * Set the 'if' clause. | |||
| * | |||
| * @param val 'if' clause value. | |||
| */ | |||
| public void setIf(String val) { | |||
| String old = getIf(); | |||
| setAttribute(IF, val); | |||
| firePropertyChange(IF, old, val); | |||
| } | |||
| /** | |||
| * Get the 'unless' clause. | |||
| * | |||
| * @return 'unless' clause. | |||
| */ | |||
| public String getUnless() { | |||
| return getAttribute(UNLESS); | |||
| } | |||
| /** | |||
| * Set the 'unless' clause. | |||
| * | |||
| * @param val 'unless' clase value. | |||
| */ | |||
| public void setUnless(String val) { | |||
| String old = getUnless(); | |||
| setAttribute(UNLESS, val); | |||
| firePropertyChange(UNLESS, old, val); | |||
| } | |||
| } | |||
| @@ -88,14 +88,36 @@ public class ACSTargetElementBeanInfo extends BaseBeanInfo { | |||
| try { | |||
| retval = new PropertyDescriptor[] { | |||
| new PropertyDescriptor(getResources().getString( | |||
| getClass(),ACSTargetElement.NAME), | |||
| new PropertyDescriptor(ACSTargetElement.NAME, | |||
| ACSTargetElement.class), | |||
| new PropertyDescriptor(getResources().getString( | |||
| getClass(),ACSTargetElement.DESCRIPTION), | |||
| ACSTargetElement.class) | |||
| new PropertyDescriptor(ACSTargetElement.DESCRIPTION, | |||
| ACSTargetElement.class), | |||
| new PropertyDescriptor(ACSTargetElement.DEPENDS, | |||
| ACSTargetElement.class), | |||
| new PropertyDescriptor(ACSTargetElement.IF, | |||
| ACSTargetElement.class), | |||
| new PropertyDescriptor(ACSTargetElement.UNLESS, | |||
| ACSTargetElement.class), | |||
| new PropertyDescriptor(ACSTargetElement.XML_STRING, | |||
| ACSTargetElement.class, | |||
| "getXMLString", null) | |||
| }; | |||
| // Set display names. | |||
| retval[0].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.NAME)); | |||
| retval[1].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.DESCRIPTION)); | |||
| retval[2].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.DEPENDS)); | |||
| retval[3].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.IF)); | |||
| retval[4].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.UNLESS)); | |||
| retval[5].setDisplayName(getResources().getString( | |||
| getClass(),ACSTargetElement.XML_STRING)); | |||
| setSortingOrder(retval); | |||
| } | |||
| catch(IntrospectionException ex) { | |||
| ex.printStackTrace(); | |||
| @@ -54,6 +54,7 @@ | |||
| package org.apache.tools.ant.gui.acs; | |||
| import org.apache.tools.ant.gui.ResourceManager; | |||
| import org.apache.tools.ant.gui.customizer.DynamicCustomizer; | |||
| import java.beans.*; | |||
| /** | |||
| @@ -63,10 +64,11 @@ import java.beans.*; | |||
| * @author Simeon Fitch | |||
| */ | |||
| abstract class BaseBeanInfo extends SimpleBeanInfo { | |||
| /** Property name for specifiying a sorting order. */ | |||
| public static final String SORT_ORDER = DynamicCustomizer.SORT_ORDER; | |||
| /** Resource provider for bean info. */ | |||
| private static ResourceManager _resources = new ResourceManager( | |||
| "org.apache.tools.ant.gui.acs.beaninfo"); | |||
| private static ResourceManager _resources = new ResourceManager(); | |||
| /** | |||
| * Default ctor. | |||
| @@ -93,6 +95,18 @@ abstract class BaseBeanInfo extends SimpleBeanInfo { | |||
| return new ACSBeanDescriptor(this); | |||
| } | |||
| /** | |||
| * Set the sorting order property of the given objects based | |||
| * on the order that they appear in the array. | |||
| * | |||
| * @param vals FeatureDescriptors to set sorting order property for. | |||
| */ | |||
| protected void setSortingOrder(FeatureDescriptor[] vals) { | |||
| for(int i = 0; i < vals.length; i++) { | |||
| vals[i].setValue(SORT_ORDER, new Integer(i)); | |||
| } | |||
| } | |||
| /** | |||
| * Get the type that this BeanInfo represents. | |||
| * | |||
| @@ -7,4 +7,5 @@ | |||
| # Specific elements. | |||
| project=org.apache.tools.ant.gui.acs.ACSProjectElement | |||
| property=org.apache.tools.ant.gui.acs.ACSPropertyElement | |||
| target=org.apache.tools.ant.gui.acs.ACSTargetElement | |||
| @@ -1,14 +0,0 @@ | |||
| # Properties file for BeanInfo strings | |||
| org.apache.tools.ant.gui.acs.ACSTargetElementBeanInfo.beanName=Target | |||
| org.apache.tools.ant.gui.acs.ACSTargetElementBeanInfo.beanDescription=\ | |||
| An executable target in the build. | |||
| org.apache.tools.ant.gui.acs.ACSTargetElementBeanInfo.name=Name | |||
| org.apache.tools.ant.gui.acs.ACSTargetElementBeanInfo.description=Description | |||
| org.apache.tools.ant.gui.acs.ACSProjectElementBeanInfo.beanName=Project | |||
| org.apache.tools.ant.gui.acs.ACSProjectElementBeanInfo.beanDescription=\ | |||
| The top level project in the build definition. | |||
| org.apache.tools.ant.gui.acs.ACSProjectElementBeanInfo.name=Name | |||
| org.apache.tools.ant.gui.acs.ACSProjectElementBeanInfo.description=Description | |||
| @@ -57,8 +57,7 @@ import org.apache.tools.ant.gui.LabelFieldGBC; | |||
| import java.lang.reflect.*; | |||
| import java.beans.*; | |||
| import javax.swing.*; | |||
| import java.util.Hashtable; | |||
| import java.util.Enumeration; | |||
| import java.util.*; | |||
| import java.awt.GridBagLayout; | |||
| import java.awt.GridBagConstraints; | |||
| import java.awt.Component; | |||
| @@ -74,6 +73,8 @@ public class DynamicCustomizer extends JPanel { | |||
| static { | |||
| PropertyEditorManager.registerEditor( | |||
| String.class, StringPropertyEditor.class); | |||
| PropertyEditorManager.registerEditor( | |||
| String[].class, StringArrayPropertyEditor.class); | |||
| PropertyEditorManager.registerEditor( | |||
| int.class, IntegerPropertyEditor.class); | |||
| PropertyEditorManager.registerEditor( | |||
| @@ -84,14 +85,19 @@ public class DynamicCustomizer extends JPanel { | |||
| Double.class, DoublePropertyEditor.class); | |||
| } | |||
| /** Property name that PropertyDescriptors can save in their property | |||
| * dictionaries for for specifiying a display sorting order. The value | |||
| * sould be of type Integer. */ | |||
| public static final String SORT_ORDER = "sortOrder"; | |||
| /** The type that this editor instance can handle. */ | |||
| private Class _type = null; | |||
| /** The value currently being edited. */ | |||
| private Object _value = null; | |||
| /** Mapping from PropertyDescriptor to PropertyEditor. */ | |||
| private Hashtable _prop2Editor = new Hashtable(); | |||
| private Map _prop2Editor = new HashMap(); | |||
| /** Mapping from PropertyEditor to field PropertyDescriptor. */ | |||
| private Hashtable _editor2Prop = new Hashtable(); | |||
| private Map _editor2Prop = new HashMap(); | |||
| /** Listener for receiving change events from the editors. */ | |||
| private EditorChangeListener _eListener = new EditorChangeListener(); | |||
| /** Read-only flag. */ | |||
| @@ -121,11 +127,18 @@ public class DynamicCustomizer extends JPanel { | |||
| LabelFieldGBC gbc = new LabelFieldGBC(); | |||
| try { | |||
| BeanInfo info = Introspector.getBeanInfo(type); | |||
| // Set up pretty display stuff. | |||
| setBorder(BorderFactory.createTitledBorder( | |||
| info.getBeanDescriptor().getDisplayName())); | |||
| setToolTipText(info.getBeanDescriptor().getShortDescription()); | |||
| // Get the properties and sort them. | |||
| PropertyDescriptor[] props = info.getPropertyDescriptors(); | |||
| Arrays.sort(props, new PropertyComparator()); | |||
| for(int i = 0; i < props.length; i++) { | |||
| // Ignore the "class" property, if it is provided. | |||
| if(props[i].getName().equals("class")) continue; | |||
| // Create a label for the field. | |||
| JLabel label = new JLabel(props[i].getDisplayName() + ":"); | |||
| // Lookup the editor. | |||
| @@ -195,9 +208,9 @@ public class DynamicCustomizer extends JPanel { | |||
| // Iterate over each property, doing a lookup on the associated editor | |||
| // and setting the editor's value to the value of the property. | |||
| Enumeration enum = _prop2Editor.keys(); | |||
| while(enum.hasMoreElements()) { | |||
| PropertyDescriptor desc = (PropertyDescriptor) enum.nextElement(); | |||
| Iterator it = _prop2Editor.keySet().iterator(); | |||
| while(it.hasNext()) { | |||
| PropertyDescriptor desc = (PropertyDescriptor) it.next(); | |||
| PropertyEditor editor = (PropertyEditor) _prop2Editor.get(desc); | |||
| Method reader = desc.getReadMethod(); | |||
| if(reader != null) { | |||
| @@ -215,6 +228,12 @@ public class DynamicCustomizer extends JPanel { | |||
| } | |||
| } | |||
| /** | |||
| * Get the appropriate editor for the given property. | |||
| * | |||
| * @param prop Property to get editor for. | |||
| * @return Editor to use, or null if none found. | |||
| */ | |||
| private PropertyEditor getEditorForProperty(PropertyDescriptor prop) { | |||
| PropertyEditor retval = null; | |||
| Class type = prop.getPropertyEditorClass(); | |||
| @@ -231,7 +250,10 @@ public class DynamicCustomizer extends JPanel { | |||
| // PropertyEditor manager for the editor registered for the | |||
| // given property type. | |||
| if(retval == null) { | |||
| retval = PropertyEditorManager.findEditor(prop.getPropertyType()); | |||
| Class t = prop.getPropertyType(); | |||
| if(t != null) { | |||
| retval = PropertyEditorManager.findEditor(t); | |||
| } | |||
| } | |||
| return retval; | |||
| @@ -262,6 +284,27 @@ public class DynamicCustomizer extends JPanel { | |||
| } | |||
| /** Comparator for sorting PropertyDescriptor values. */ | |||
| private static class PropertyComparator implements Comparator { | |||
| public int compare(Object o1, Object o2) { | |||
| PropertyDescriptor p1 = (PropertyDescriptor)o1; | |||
| PropertyDescriptor p2 = (PropertyDescriptor)o2; | |||
| Integer i1 = (Integer) p1.getValue(SORT_ORDER); | |||
| Integer i2 = (Integer) p2.getValue(SORT_ORDER); | |||
| if(i1 == null && i2 == null) { | |||
| return 0; | |||
| } | |||
| else if(i1 != null) { | |||
| return i1.compareTo(i2); | |||
| } | |||
| else { | |||
| return i2.compareTo(i1) * -1; | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Test code. | |||
| * | |||
| @@ -1,99 +0,0 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.gui.event; | |||
| import org.apache.tools.ant.gui.acs.ACSTargetElement; | |||
| import org.apache.tools.ant.gui.command.Command; | |||
| import org.apache.tools.ant.gui.command.NoOpCmd; | |||
| import org.apache.tools.ant.gui.AppContext; | |||
| /** | |||
| * Event indicating that the current set of selected targets has changed. | |||
| * | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| */ | |||
| public class TargetSelectionEvent extends AntEvent { | |||
| /** New set of selected targets. */ | |||
| private ACSTargetElement[] _selectedTargets = null; | |||
| /** | |||
| * Standard ctor. | |||
| * | |||
| * @param context application context. | |||
| */ | |||
| public TargetSelectionEvent(AppContext context, | |||
| ACSTargetElement[] selectedTargets) { | |||
| super(context); | |||
| _selectedTargets = selectedTargets; | |||
| } | |||
| /** | |||
| * Current set of selected targets. | |||
| * | |||
| * @return selected target set. | |||
| */ | |||
| public ACSTargetElement[] getSelectedTargets() { | |||
| return _selectedTargets; | |||
| } | |||
| /** | |||
| * Create the appropriate default response command to this event. | |||
| * | |||
| * @return Command representing an appropriate response to this event. | |||
| */ | |||
| public Command createDefaultCmd() { | |||
| return new NoOpCmd(); | |||
| } | |||
| } | |||