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. | // Set location to left side. | ||||
| gridx = 0; | gridx = 0; | ||||
| // Move it over to be as close to field as possible. | // Move it over to be as close to field as possible. | ||||
| anchor = EAST; | |||||
| anchor = NORTHEAST; | |||||
| // Don't take up any extra. | // Don't take up any extra. | ||||
| weightx = 0.0; | weightx = 0.0; | ||||
| return this; | return this; | ||||
| @@ -85,7 +85,7 @@ public class ProjectProxy { | |||||
| /** The current thread executing a build. */ | /** The current thread executing a build. */ | ||||
| private Thread _buildThread = null; | private Thread _buildThread = null; | ||||
| /** The selection model for selected targets. */ | /** The selection model for selected targets. */ | ||||
| private TargetSelectionModel _selections = null; | |||||
| private ElementSelectionModel _selections = null; | |||||
| /** | /** | ||||
| * File loading ctor. | * File loading ctor. | ||||
| @@ -104,7 +104,7 @@ public class ProjectProxy { | |||||
| */ | */ | ||||
| private void loadProject() throws IOException { | private void loadProject() throws IOException { | ||||
| _project = ACSFactory.getInstance().load(_file); | _project = ACSFactory.getInstance().load(_file); | ||||
| _selections = new TargetSelectionModel(); | |||||
| _selections = new ElementSelectionModel(); | |||||
| _selections.addTreeSelectionListener(new SelectionForwarder()); | _selections.addTreeSelectionListener(new SelectionForwarder()); | ||||
| } | } | ||||
| @@ -169,7 +169,7 @@ public class ProjectProxy { | |||||
| * | * | ||||
| * @return Selection model. | * @return Selection model. | ||||
| */ | */ | ||||
| public TreeSelectionModel getTreeSelectionModel() { | |||||
| public ElementSelectionModel getTreeSelectionModel() { | |||||
| return _selections; | return _selections; | ||||
| } | } | ||||
| @@ -209,6 +209,10 @@ public class ProjectProxy { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Run the build. | |||||
| * | |||||
| */ | |||||
| public void run() { | public void run() { | ||||
| // Add the build listener for | // Add the build listener for | ||||
| // dispatching BuildEvent objects to the | // dispatching BuildEvent objects to the | ||||
| @@ -255,8 +259,8 @@ public class ProjectProxy { | |||||
| /** Forwards selection events to the event bus. */ | /** Forwards selection events to the event bus. */ | ||||
| private class SelectionForwarder implements TreeSelectionListener { | private class SelectionForwarder implements TreeSelectionListener { | ||||
| public void valueChanged(TreeSelectionEvent e) { | 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. */ | /** The property sheet. */ | ||||
| private DynamicCustomizer _customizer = null; | private DynamicCustomizer _customizer = null; | ||||
| /** Container for the customizer. */ | |||||
| private JPanel _container = null; | |||||
| /** | /** | ||||
| * Standard ctor. | * Standard ctor. | ||||
| @@ -82,23 +84,25 @@ class PropertyEditor extends AntEditor { | |||||
| super(context); | super(context); | ||||
| context.getEventBus().addMember(EventBus.MONITORING, new Handler()); | context.getEventBus().addMember(EventBus.MONITORING, new Handler()); | ||||
| setLayout(new BorderLayout()); | 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) { | if(_customizer != null) { | ||||
| remove(_customizer); | |||||
| _container.remove(_customizer); | |||||
| _customizer = null; | _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(); | validate(); | ||||
| } | } | ||||
| @@ -124,9 +128,9 @@ class PropertyEditor extends AntEditor { | |||||
| * @param event Event to post. | * @param event Event to post. | ||||
| */ | */ | ||||
| public void eventPosted(EventObject event) { | 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. | * @return True if event should be given to BusMember, false otherwise. | ||||
| */ | */ | ||||
| public boolean accept(EventObject event) { | 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$ | * @version $Revision$ | ||||
| * @author Simeon Fitch */ | * @author Simeon Fitch */ | ||||
| public abstract class ACSElement extends ElementNode { | public abstract class ACSElement extends ElementNode { | ||||
| /** Name of the 'xmlString' property. */ | |||||
| public static final String XML_STRING = "xmlString"; | |||||
| /** Event support. */ | /** Event support. */ | ||||
| private PropertyChangeSupport _propSupport = null; | private PropertyChangeSupport _propSupport = null; | ||||
| @@ -74,7 +76,6 @@ public abstract class ACSElement extends ElementNode { | |||||
| * | * | ||||
| */ | */ | ||||
| protected ACSElement() { | protected ACSElement() { | ||||
| } | } | ||||
| /** | /** | ||||
| @@ -86,6 +87,15 @@ public abstract class ACSElement extends ElementNode { | |||||
| return getTagName(); | return getTagName(); | ||||
| } | } | ||||
| /** | |||||
| * Get the XML representation of this. | |||||
| * | |||||
| * @return XML representation. | |||||
| */ | |||||
| public String getXMLString() { | |||||
| return toString(); | |||||
| } | |||||
| /** | /** | ||||
| * Add a change listener. | * 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.XmlDocument; | ||||
| import com.sun.xml.tree.XmlDocumentBuilder; | import com.sun.xml.tree.XmlDocumentBuilder; | ||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import java.util.Enumeration; | |||||
| import com.sun.xml.parser.Resolver; | import com.sun.xml.parser.Resolver; | ||||
| /** | /** | ||||
| @@ -79,10 +80,25 @@ public class ACSFactory { | |||||
| static { | static { | ||||
| try { | 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. | _elementMap.load(ACSFactory.class. | ||||
| getResourceAsStream("acs-element.properties")); | getResourceAsStream("acs-element.properties")); | ||||
| } | } | ||||
| catch(Throwable ex) { | catch(Throwable ex) { | ||||
| // If something wrong happens here we can't do much more... | |||||
| ex.printStackTrace(); | ex.printStackTrace(); | ||||
| System.exit(1); | System.exit(1); | ||||
| } | } | ||||
| @@ -62,8 +62,17 @@ import com.sun.xml.tree.ElementNode; | |||||
| * @author Simeon Fitch | * @author Simeon Fitch | ||||
| */ | */ | ||||
| public class ACSProjectElement extends ACSNamedElement { | 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() { | public String getDisplayName() { | ||||
| return getTagName() + ": " + getName(); | 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.*; | import java.beans.*; | ||||
| /** | /** | ||||
| * BeanInfo for the ACSTargetElement class. | |||||
| * BeanInfo for the ACSProjectElement class. | |||||
| * | * | ||||
| * @version $Revision$ | * @version $Revision$ | ||||
| * @author Simeon Fitch | * @author Simeon Fitch | ||||
| @@ -91,9 +91,23 @@ public class ACSProjectElementBeanInfo extends BaseBeanInfo { | |||||
| new PropertyDescriptor(ACSProjectElement.NAME, | new PropertyDescriptor(ACSProjectElement.NAME, | ||||
| ACSProjectElement.class), | ACSProjectElement.class), | ||||
| new PropertyDescriptor(ACSProjectElement.DESCRIPTION, | new PropertyDescriptor(ACSProjectElement.DESCRIPTION, | ||||
| ACSProjectElement.class), | |||||
| new PropertyDescriptor(ACSProjectElement.DEFAULT, | |||||
| ACSProjectElement.class), | |||||
| new PropertyDescriptor(ACSProjectElement.BASEDIR, | |||||
| ACSProjectElement.class) | 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) { | catch(IntrospectionException ex) { | ||||
| ex.printStackTrace(); | ex.printStackTrace(); | ||||
| @@ -64,6 +64,13 @@ import java.util.StringTokenizer; | |||||
| */ | */ | ||||
| public class ACSTargetElement extends ACSNamedElement { | 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. | * 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. | * @return Dependency names. | ||||
| */ | */ | ||||
| public String[] getDependencyNames() { | |||||
| String depends = getAttribute("depends"); | |||||
| public String[] getDepends() { | |||||
| String depends = getAttribute(DEPENDS); | |||||
| StringTokenizer tok = new StringTokenizer(depends,","); | StringTokenizer tok = new StringTokenizer(depends,","); | ||||
| String[] retval = new String[tok.countTokens()]; | String[] retval = new String[tok.countTokens()]; | ||||
| for(int i = 0; i < retval.length; i++) { | for(int i = 0; i < retval.length; i++) { | ||||
| retval[i] = tok.nextToken(); | |||||
| retval[i] = tok.nextToken().trim(); | |||||
| } | } | ||||
| return retval; | 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 { | try { | ||||
| retval = new PropertyDescriptor[] { | retval = new PropertyDescriptor[] { | ||||
| new PropertyDescriptor(getResources().getString( | |||||
| getClass(),ACSTargetElement.NAME), | |||||
| new PropertyDescriptor(ACSTargetElement.NAME, | |||||
| ACSTargetElement.class), | 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) { | catch(IntrospectionException ex) { | ||||
| ex.printStackTrace(); | ex.printStackTrace(); | ||||
| @@ -54,6 +54,7 @@ | |||||
| package org.apache.tools.ant.gui.acs; | package org.apache.tools.ant.gui.acs; | ||||
| import org.apache.tools.ant.gui.ResourceManager; | import org.apache.tools.ant.gui.ResourceManager; | ||||
| import org.apache.tools.ant.gui.customizer.DynamicCustomizer; | |||||
| import java.beans.*; | import java.beans.*; | ||||
| /** | /** | ||||
| @@ -63,10 +64,11 @@ import java.beans.*; | |||||
| * @author Simeon Fitch | * @author Simeon Fitch | ||||
| */ | */ | ||||
| abstract class BaseBeanInfo extends SimpleBeanInfo { | 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. */ | /** 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. | * Default ctor. | ||||
| @@ -93,6 +95,18 @@ abstract class BaseBeanInfo extends SimpleBeanInfo { | |||||
| return new ACSBeanDescriptor(this); | 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. | * Get the type that this BeanInfo represents. | ||||
| * | * | ||||
| @@ -7,4 +7,5 @@ | |||||
| # Specific elements. | # Specific elements. | ||||
| project=org.apache.tools.ant.gui.acs.ACSProjectElement | project=org.apache.tools.ant.gui.acs.ACSProjectElement | ||||
| property=org.apache.tools.ant.gui.acs.ACSPropertyElement | |||||
| target=org.apache.tools.ant.gui.acs.ACSTargetElement | 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.lang.reflect.*; | ||||
| import java.beans.*; | import java.beans.*; | ||||
| import javax.swing.*; | import javax.swing.*; | ||||
| import java.util.Hashtable; | |||||
| import java.util.Enumeration; | |||||
| import java.util.*; | |||||
| import java.awt.GridBagLayout; | import java.awt.GridBagLayout; | ||||
| import java.awt.GridBagConstraints; | import java.awt.GridBagConstraints; | ||||
| import java.awt.Component; | import java.awt.Component; | ||||
| @@ -74,6 +73,8 @@ public class DynamicCustomizer extends JPanel { | |||||
| static { | static { | ||||
| PropertyEditorManager.registerEditor( | PropertyEditorManager.registerEditor( | ||||
| String.class, StringPropertyEditor.class); | String.class, StringPropertyEditor.class); | ||||
| PropertyEditorManager.registerEditor( | |||||
| String[].class, StringArrayPropertyEditor.class); | |||||
| PropertyEditorManager.registerEditor( | PropertyEditorManager.registerEditor( | ||||
| int.class, IntegerPropertyEditor.class); | int.class, IntegerPropertyEditor.class); | ||||
| PropertyEditorManager.registerEditor( | PropertyEditorManager.registerEditor( | ||||
| @@ -84,14 +85,19 @@ public class DynamicCustomizer extends JPanel { | |||||
| Double.class, DoublePropertyEditor.class); | 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. */ | /** The type that this editor instance can handle. */ | ||||
| private Class _type = null; | private Class _type = null; | ||||
| /** The value currently being edited. */ | /** The value currently being edited. */ | ||||
| private Object _value = null; | private Object _value = null; | ||||
| /** Mapping from PropertyDescriptor to PropertyEditor. */ | /** Mapping from PropertyDescriptor to PropertyEditor. */ | ||||
| private Hashtable _prop2Editor = new Hashtable(); | |||||
| private Map _prop2Editor = new HashMap(); | |||||
| /** Mapping from PropertyEditor to field PropertyDescriptor. */ | /** Mapping from PropertyEditor to field PropertyDescriptor. */ | ||||
| private Hashtable _editor2Prop = new Hashtable(); | |||||
| private Map _editor2Prop = new HashMap(); | |||||
| /** Listener for receiving change events from the editors. */ | /** Listener for receiving change events from the editors. */ | ||||
| private EditorChangeListener _eListener = new EditorChangeListener(); | private EditorChangeListener _eListener = new EditorChangeListener(); | ||||
| /** Read-only flag. */ | /** Read-only flag. */ | ||||
| @@ -121,11 +127,18 @@ public class DynamicCustomizer extends JPanel { | |||||
| LabelFieldGBC gbc = new LabelFieldGBC(); | LabelFieldGBC gbc = new LabelFieldGBC(); | ||||
| try { | try { | ||||
| BeanInfo info = Introspector.getBeanInfo(type); | BeanInfo info = Introspector.getBeanInfo(type); | ||||
| // Set up pretty display stuff. | |||||
| setBorder(BorderFactory.createTitledBorder( | setBorder(BorderFactory.createTitledBorder( | ||||
| info.getBeanDescriptor().getDisplayName())); | info.getBeanDescriptor().getDisplayName())); | ||||
| setToolTipText(info.getBeanDescriptor().getShortDescription()); | |||||
| // Get the properties and sort them. | |||||
| PropertyDescriptor[] props = info.getPropertyDescriptors(); | PropertyDescriptor[] props = info.getPropertyDescriptors(); | ||||
| Arrays.sort(props, new PropertyComparator()); | |||||
| for(int i = 0; i < props.length; i++) { | for(int i = 0; i < props.length; i++) { | ||||
| // Ignore the "class" property, if it is provided. | |||||
| if(props[i].getName().equals("class")) continue; | if(props[i].getName().equals("class")) continue; | ||||
| // Create a label for the field. | |||||
| JLabel label = new JLabel(props[i].getDisplayName() + ":"); | JLabel label = new JLabel(props[i].getDisplayName() + ":"); | ||||
| // Lookup the editor. | // Lookup the editor. | ||||
| @@ -195,9 +208,9 @@ public class DynamicCustomizer extends JPanel { | |||||
| // Iterate over each property, doing a lookup on the associated editor | // Iterate over each property, doing a lookup on the associated editor | ||||
| // and setting the editor's value to the value of the property. | // 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); | PropertyEditor editor = (PropertyEditor) _prop2Editor.get(desc); | ||||
| Method reader = desc.getReadMethod(); | Method reader = desc.getReadMethod(); | ||||
| if(reader != null) { | 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) { | private PropertyEditor getEditorForProperty(PropertyDescriptor prop) { | ||||
| PropertyEditor retval = null; | PropertyEditor retval = null; | ||||
| Class type = prop.getPropertyEditorClass(); | Class type = prop.getPropertyEditorClass(); | ||||
| @@ -231,7 +250,10 @@ public class DynamicCustomizer extends JPanel { | |||||
| // PropertyEditor manager for the editor registered for the | // PropertyEditor manager for the editor registered for the | ||||
| // given property type. | // given property type. | ||||
| if(retval == null) { | if(retval == null) { | ||||
| retval = PropertyEditorManager.findEditor(prop.getPropertyType()); | |||||
| Class t = prop.getPropertyType(); | |||||
| if(t != null) { | |||||
| retval = PropertyEditorManager.findEditor(t); | |||||
| } | |||||
| } | } | ||||
| return retval; | 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. | * 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(); | |||||
| } | |||||
| } | |||||