From c70641243c667093d23f689c7c28866fa661b1af Mon Sep 17 00:00:00 2001
From: Stefan Bodewig
Date: Mon, 6 Nov 2000 12:52:51 +0000
Subject: [PATCH] Tow Antidote patches:
*) Design document.
*) can now write BuildEvents to console.
Submitted by: Simeon Fitch
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268152 13f79535-47bb-0310-9956-ffa450edef68
---
WHATSNEW | 2 +
src/antidote/ChangeLog | 40 +++
src/antidote/build.xml | 4 +-
src/antidote/docs/design-overview.html | 258 ++++++++++++++++++
.../apache/tools/ant/gui/ActionManager.java | 47 +++-
.../org/apache/tools/ant/gui/AntEditor.java | 2 +
.../org/apache/tools/ant/gui/Antidote.java | 22 +-
.../tools/ant/gui/BuildEventForwarder.java | 151 ++++++++++
.../org/apache/tools/ant/gui/Console.java | 117 +++++++-
.../apache/tools/ant/gui/EventResponder.java | 3 +
.../apache/tools/ant/gui/LogLevelEnum.java | 163 +++++++++++
.../org/apache/tools/ant/gui/Main.java | 13 +-
.../tools/ant/gui/ProjectNavigator.java | 2 +-
.../apache/tools/ant/gui/ProjectProxy.java | 112 ++++++--
.../apache/tools/ant/gui/ResourceManager.java | 21 ++
.../tools/ant/gui/command/BuildCmd.java | 90 ++++++
.../tools/ant/gui/command/LoadFileCmd.java | 2 +-
.../tools/ant/gui/event/AntBuildEvent.java | 138 ++++++++++
.../tools/ant/gui/event/BuildEventType.java | 208 ++++++++++++++
.../apache/tools/ant/gui/event/EventBus.java | 70 +++--
.../tools/ant/gui/resources/action.properties | 21 +-
.../ant/gui/resources/antidote.properties | 8 +-
.../tools/ant/gui/resources/default.gif | Bin 0 -> 1212 bytes
.../tools/ant/gui/resources/icon-small.gif | Bin 0 -> 3791 bytes
.../apache/tools/ant/gui/resources/start.gif | Bin 0 -> 888 bytes
.../apache/tools/ant/gui/resources/stop.gif | Bin 0 -> 888 bytes
.../tools/ant/gui/util/WindowUtils.java | 13 +-
27 files changed, 1429 insertions(+), 78 deletions(-)
create mode 100644 src/antidote/docs/design-overview.html
create mode 100644 src/antidote/org/apache/tools/ant/gui/BuildEventForwarder.java
create mode 100644 src/antidote/org/apache/tools/ant/gui/LogLevelEnum.java
create mode 100644 src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java
create mode 100644 src/antidote/org/apache/tools/ant/gui/event/AntBuildEvent.java
create mode 100644 src/antidote/org/apache/tools/ant/gui/event/BuildEventType.java
create mode 100644 src/antidote/org/apache/tools/ant/gui/resources/default.gif
create mode 100644 src/antidote/org/apache/tools/ant/gui/resources/icon-small.gif
create mode 100644 src/antidote/org/apache/tools/ant/gui/resources/start.gif
create mode 100644 src/antidote/org/apache/tools/ant/gui/resources/stop.gif
diff --git a/WHATSNEW b/WHATSNEW
index 35f9b32e0..dc8eca047 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -4,6 +4,8 @@ Changes from Ant 1.2 to the current sources
Other changes:
--------------
+* A GUI Frontend: Antidote
+
* New tasks: propertyfile, depend, antlr
* Added output attribute to .
diff --git a/src/antidote/ChangeLog b/src/antidote/ChangeLog
index c491cd8cb..76657e1ab 100644
--- a/src/antidote/ChangeLog
+++ b/src/antidote/ChangeLog
@@ -1,3 +1,43 @@
+2000-11-05 Simeon H.K. Fitch
+
+ * org/apache/tools/ant/gui/LogLevelEnum.java: Added log level
+ enumeration for use with combo boxes (drops nicely into default model).
+
+ * org/apache/tools/ant/gui/event/BuildEventType.java: Added
+ delivering of event to a BuildListener based on enumeration value.
+
+ * org/apache/tools/ant/gui/ProjectProxy.java: Added generation of
+ BuildEvent on project start and finish, as the project itself
+ doesn't generate theses events (unfortunately).
+
+ * org/apache/tools/ant/gui/Console.java: Added filtering level,
+ and clearing of buffer when a new build starts.
+
+ * org/apache/tools/ant/gui/AntEditor.java: Added automatic border
+ for all subclasses.
+
+2000-11-04 Simeon H.K. Fitch
+
+ * org/apache/tools/ant/gui/ProjectProxy.java: Added inner class to
+ execute the build in a separate thread.
+
+ * org/apache/tools/ant/gui/event/EventBus.java: Added check to see
+ if postEvent() is being called on the AWTEvent thread, and if not,
+ post the dispatching of the event to that thread. This is needed
+ as most of the listeners will be bound to GUI components and will
+ be updating their state (which must occur on the event thread).
+
+ * org/apache/tools/ant/gui/ProjectProxy.java: Added a
+ BuildListener to forward events to the EventBus.
+
+2000-11-03 Simeon H.K. Fitch
+
+ * org/apache/tools/ant/gui/Antidote.java: Removed hard-coded
+ Console class.
+
+ * org/apache/tools/ant/gui/Console.java: Changed to a real
+ AntEditor class, initialized by the config file.
+
2000-11-02 Simeon H.K. Fitch
* org/apache/tools/ant/gui/event/EventBus.java: Added interrupt
diff --git a/src/antidote/build.xml b/src/antidote/build.xml
index 8a37bc514..58141d0f3 100644
--- a/src/antidote/build.xml
+++ b/src/antidote/build.xml
@@ -50,8 +50,8 @@
+ deprecation="on"
+ optimize="off" >
diff --git a/src/antidote/docs/design-overview.html b/src/antidote/docs/design-overview.html
new file mode 100644
index 000000000..bed6d8ee6
--- /dev/null
+++ b/src/antidote/docs/design-overview.html
@@ -0,0 +1,258 @@
+
+
+
+ Antidote Design Overview
+
+
+
+
+ Antidote Design Overview
+
+ Version 0.1 (2000/11/02)
+
+ Authors:
+ Simeon H.K. Fitch
+
+
+ Introduction
+
+ The purpose of this document is to communicate the overall
+ structure and design patters used in Antidote, the GUI for
+ Ant. This document is a work in progress, as well as a living
+ document, and it is most likely not be in full synchronization with
+ the source code. Therefore, if there is any doubt, view the source
+ ;-)
+
+ Overview
+
+ The Antidote architecture design aims to provide a high level
+ of modularity and extensibility. Ideally the components of
+ Antidote will be able to be assembled in different configurations
+ to provide the type of application or plug-in desired.
+
+ To acheive this modularity, a high level of decoupling is
+ necessary. The standard UI design approach of providing separation
+ of view (presentation) from model (data) is applied, leveraging
+ the built-in Ant data model where possible, as well as the
+ predifined Swing model interfaces. Furthermore, the architecture
+ is highly event driven, whereby modules communicate via a shared
+ communications channel.
+
+ To a large extent, the configuration of application modules is
+ driven by localized configuration files, allowing new editors or
+ data views to be added, as well as providing multi-language
+ support.
+
+ The diagram below conveys a high altitude view of the
+ application's structure. As the application grows, new components
+ will be plugged in to what will be described as the EventBus.
+
+
+
+Antidote Component Architecture
+
+ +---------------+ +----------------+ +-------------+ +-------------+
+ | | | | | | | |
+ | ActionManager | | EventResponder | | AntEditor | | AntEditor |
+ | | | | |(ProjectNav) | |(SourceEdit) |
+ +---------------+ +----------------+ +-------------+ +-------------+
+ | ^ ^ ^
+ | | | |
+ ActionEvent EventObject AntEvent AntEvent
+ | | | |
+ v v v v
+ /---------------------------------------------------------------------\
+ / \
+< EventBus >
+ \ /
+ \---------------------------------------------------------------------/
+ | ^ ^ ^
+ | | | |
+ EventObject ChangeEvent BuildEvent EventObject
+ | | | |
+ v | | v
+ +---------------+ +----------------+ +-------------+ +--------------+
+ | | | | | | | |
+ | Console | | ProjectProxy | | Ant | | (Your Module)|
+ | | | | | | | |
+ +---------------+ +----------------+ +-------------+ +--------------+
+
+
+
+
Event Bus
+
+ The backbone of the application is the EventBus. Any
+ component of the application can post events to the
+ EventBus. Components that wish to receive events are
+ called BusMembers.
+
+ The EventBus will dispatch any object of type
+ java.util.EventBus, which means that Ant BuildEvent
+ objects, as well as AWTEvent objects can be posted (if desired). A
+ new class of events called AntEvent is defined for Antidote
+ specific events, which have the additional capability of being
+ cancelled mid-dispatch.
+
+ Each BusMember must provide a BusFilter instance,
+ which is the members' means of telling the bus which
+ events it is interested in. This allows a BusMember to,
+ say, only receive AntEvent objects.
+
+ When a BusMember registers itself with the
+ EventBus, it must provide a (so called) interrupt
+ level which is a integer value defining a relative ordering
+ for dispatching EventObjects to BusMembers. The
+ purpose of this is to allow certain BusMember instances
+ to see an event before others, and in the case of AntEventEventBus class defines the interrupt level constants
+ MONITORING=1, VETOING=5, and RESPONDING=10 to
+ help define categories of members. The implied purpose being that:
+
+
+ - MONITORING: Just listens for events, like a logger
+ or status monitor.
+
+ - VETOING: Listens for certain types of events, and
+ may process them in a non-default manner to determine if the
+ event should be cancelled before being dispatched to the
+ RESPONDING group. An example of this might be to handle
+ a SaveAs event, whereby a VETOING member will
+ check to see if the file exists, and ask the user if they are
+ sure they want to overwrite the existing file. The SaveAs
+ event could then be cancelled before the operation is executed.
+
+ - RESPONDING: Process events in a default manner,
+ knowing that the event has passed any VETOING members.
+
+
+
+ Within a specific interrupt level, the order in which members will
+ receive events is undefied. A BusMember may be registered
+ at a level that is +/- of one of the defined levels, as long as it
+ follows the constraint MONITORING <= interruptLevel <=
+ MAX_INTERRUPT.
+
+
+ Actions and ActionManager
+
+ Extensive use of the javax.swing.Action interface is
+ made for defining the set of menu and tool bar options that are
+ available. The configuration file action.properties
+ exists to define what should appear in the menu and toolbar, how
+ it is displayed, and the Action command name that is
+ dispatched when the user invokes that action. A class called
+ ActionManager exists for not only processing the
+ configuration file, but also for dispatching invoked action events
+ to the EventBus, and for controlling the enabled state of
+ an Action. When a new menu item or toolbar button is
+ desired, first it is added to the action.properties file,
+ and then the code to respond to it is added to the
+ EventResponder (see below).
+
+
+
Commands and EventResponder
+
+ At some point in the stages of event processing, an event may
+ require the data model to be modified, or some other task be
+ performed. The Command interface is defined to classify
+ code which performs some task or operation. This is distinct from
+ an Action, which is a user request for an operation. A
+ Command class is the encapsulation of the operation
+ itself.
+
+ When an Action generates an ActionEvent, the
+ event is posted to the EventBus which delivers the event
+ to all interested BusMembers. It eventually makes it to
+ the EventResponder instance (registered at the
+ RESPONDING interrupt level), which is responsible for
+ translating specific events into Command objects, and
+ then executing the Command object. For example, when the
+ user selects the "Open..." menu option, an ActionEvent is
+ generated by the Swing MenuItem class, which is then
+ posted to the EventBus by the ActionManager. The
+ ActionEvent is delivered to the EventResponder,
+ which converts the ActionEvent into a Command
+ instance. The EventResponder then calls the method
+ Command.execute() to invoke the command (which displays a
+ dialog for selecting a file to open).
+
+ When adding new Actions or general tasks to the
+ application, a Command object should be created to
+ encapsulate the behavior. This includes most operations which
+ modify the state of the data model.
+
+ The purpose of this encapsulation is to allow the clean
+ separation of making a request, and servicing a request. Due to
+ various conditions in the application state, the actualy response
+ to a request may change, as well as who services it. This
+ design approach facilitates that.
+
+ Data Model and Views
+
+ The data model is mainly defined by the Ant application,
+ primarily through the Project, Target, and
+ Task classes.
However, Antidote defines the class
+ ProjectProxy to act not only as a proxy to the real
+ Project class, but also as creator of GUI views of
+ the Project. A view is essentially a flyweight or
+ data proxy; it provides an orgainizational perspective on the actual
+ Project structure. For example, to render a
+ JTree version of the Project, one would call the
+ method ProjectProxy.getTreeModel(). Similarly, to get a
+ Document version of the Project, the
+ ProjectProxy,getDocument() method is used.
+
+ NB: This part of the architecture is not fleshed out very
+ well. There needs to be a discussion of the degree to which the
+ Antidote development should be able to impose changes on the Ant
+ data model, and to what level that model should be mirrored in the
+ Antidote code base. The coupling between them should be kept low,
+ and at the same time changes to one should affect the other
+ minimally. Still, features like property change events and bean
+ introspection (or BeanInfo) may be needed to be added to the Ant
+ data model. Having each view into the data go to the ProjectProxy
+ for its data model may not be the best approach. In other words,
+ lots of thought needs to occur here.
+
+ Application Context
+
+ In order to keep the coupling amoung application modules to a
+ minimum, a single point of reference is needed for coordination
+ and data sharing. The class AppContext is the catch-all
+ class for containing the application state. Most modules and
+ Command classes require an instance of the
+ AppContext class. Because all state information in
+ contained in an AppContext instance, multiple instances
+ of Antidote can run inside the same JVM as long as each has it's
+ own AppContext. (Interestingly, two instances of the
+ Antidote could conceivably share an AppContext instance
+ through RMI, allowing remote interaction/collaboration.)
+
+ Configuration and ResourceManager
+
+ Full "i18n" support should be assumed in modern applications,
+ and all user viewable strings should be defined in a configuration
+ file. For Antidote this configuraiton file is
+ antidote.properties, which is located (with other UI
+ resources) in the subpackage "resources".
+
+ To aid in the lookup of text properties, as well as other
+ resources like icons, a class called ResourceManager is
+ defined. There are various convenience methods attached to this
+ class, which will likely grow to make looking up configuration
+ values as easy as possible.
+
+ The organization of configuration properties is based on the
+ fully qualifed path of the class that requires the property. For
+ example, the "about" box contains a messages, so it looks for the
+ property "org.apache.tools.ant.gui.About.message" for the text
+ message it should display. Therefore, the ResourceManager
+ method getString() takes a Class instance as
+ well as a String key. Please see the
+ ResourceManager documentation for more information. Given
+ this support, no user visible strings should appear in the source
+ code itself.
+
+
+
diff --git a/src/antidote/org/apache/tools/ant/gui/ActionManager.java b/src/antidote/org/apache/tools/ant/gui/ActionManager.java
index 9274cc0a8..921a4979f 100644
--- a/src/antidote/org/apache/tools/ant/gui/ActionManager.java
+++ b/src/antidote/org/apache/tools/ant/gui/ActionManager.java
@@ -113,7 +113,24 @@ public class ActionManager {
while(tok.hasMoreTokens()) {
String name = tok.nextToken();
JMenu menu = new JMenu(name);
- retval.add(menu);
+
+ // XXX should be in config file
+ menu.setMnemonic(name.charAt(0));
+
+ // XXX need to i18n here...
+ if(name.equalsIgnoreCase("help")) {
+ try {
+ retval.setHelpMenu(menu);
+ }
+ catch(Error err) {
+ // Catch the "not implemented" error in
+ // some (all?) Swing implementations
+ retval.add(menu);
+ }
+ }
+ else {
+ retval.add(menu);
+ }
menus.put(name, menu);
}
@@ -130,10 +147,13 @@ public class ActionManager {
menus.put(parent, menu);
}
- if(action.isPreceededBySeparator()) {
+ // See if we should add a separator.
+ if(action.isPreceededBySeparator() &&
+ menu.getMenuComponentCount() > 0) {
menu.addSeparator();
}
JMenuItem item = menu.add(action);
+ item.setAccelerator(action.getAccelerator());
addNiceStuff(item, action);
}
}
@@ -171,6 +191,13 @@ public class ActionManager {
// Set the action command so that it is consitent
// no matter what language the display is in.
button.setActionCommand(action.getID());
+
+ // XXX this should be moved to the config file.
+ String label = button.getText();
+ if(label != null) {
+ button.setMnemonic(label.charAt(0));
+ }
+
String tip = action.getShortDescription();
if(tip != null) {
button.setToolTipText(tip);
@@ -202,6 +229,7 @@ public class ActionManager {
/** Property name for the parent menu item. */
public static final String PARENT_MENU_NAME = "parentMenuName";
public static final String SEPARATOR = "separator";
+ public static final String ACCELERATOR = "accelerator";
/** Unique id. */
private String _id = null;
@@ -215,8 +243,14 @@ public class ActionManager {
_id = id;
putValue(NAME, getString(id, "name"));
putValue(SHORT_DESCRIPTION, getString(id, "shortDescription"));
- putValue(PARENT_MENU_NAME, getString(id, "parentMenuName"));
- putValue(SEPARATOR, getString(id, "separator"));
+ putValue(PARENT_MENU_NAME, getString(id, PARENT_MENU_NAME));
+ putValue(SEPARATOR, getString(id, SEPARATOR));
+
+ String accelerator = getString(id, ACCELERATOR);
+
+ if(accelerator != null) {
+ putValue(ACCELERATOR, KeyStroke.getKeyStroke(accelerator));
+ }
String iconName = getString(id, "icon");
if(iconName != null) {
@@ -232,7 +266,6 @@ public class ActionManager {
ex.printStackTrace();
}
}
-
}
/**
@@ -291,6 +324,10 @@ public class ActionManager {
return (Icon) getValue(SMALL_ICON);
}
+ public KeyStroke getAccelerator() {
+ return (KeyStroke) getValue(ACCELERATOR);
+ }
+
/**
* Pass the action on to the EventBus.
*
diff --git a/src/antidote/org/apache/tools/ant/gui/AntEditor.java b/src/antidote/org/apache/tools/ant/gui/AntEditor.java
index a9ed5fe87..2fb9a237e 100644
--- a/src/antidote/org/apache/tools/ant/gui/AntEditor.java
+++ b/src/antidote/org/apache/tools/ant/gui/AntEditor.java
@@ -54,6 +54,7 @@
package org.apache.tools.ant.gui;
import javax.swing.JPanel;
+import javax.swing.BorderFactory;
/**
* Abstract base class for an "editor", which is really anything that
@@ -78,6 +79,7 @@ public abstract class AntEditor extends JPanel {
*/
protected AntEditor(AppContext context) {
_context = context;
+ setBorder(BorderFactory.createTitledBorder(getName()));
}
/**
diff --git a/src/antidote/org/apache/tools/ant/gui/Antidote.java b/src/antidote/org/apache/tools/ant/gui/Antidote.java
index 956bc0fb9..b84c42adc 100644
--- a/src/antidote/org/apache/tools/ant/gui/Antidote.java
+++ b/src/antidote/org/apache/tools/ant/gui/Antidote.java
@@ -66,11 +66,6 @@ import java.lang.reflect.Constructor;
* @author Simeon Fitch
*/
public class Antidote extends JPanel {
-
-
- /** Logging console. */
- private Console _console = null;
-
/** Source of application state data. */
private AppContext _context = null;
@@ -83,18 +78,25 @@ public class Antidote extends JPanel {
_context = context;
- _console = new Console(_context);
-
-
// Add the various editors/views to the editing area.
JSplitPane splitter = new JSplitPane();
splitter.add(JSplitPane.LEFT, populateEditors("left"));
splitter.add(JSplitPane.RIGHT, populateEditors("right"));
+ // This is necessary because, frankly, the JSplitPane widget
+ // sucks, and doesn't provide enought (working) control over the
+ // initial size of it's subcomponents. setDividerLocation(double)
+ // doesn't seem to work until after the widget is visible.
+ splitter.setPreferredSize(new Dimension(500, 300));
- add(BorderLayout.CENTER, splitter);
+ // Top bottom splitter.
+ JSplitPane splitter2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+ splitter2.setOneTouchExpandable(true);
- add(BorderLayout.SOUTH, _console);
+ splitter2.add(JSplitPane.TOP, splitter);
+ splitter2.add(JSplitPane.BOTTOM, populateEditors("bottom"));
+ add(BorderLayout.CENTER, splitter2);
+ splitter2.resetToPreferredSizes();
setPreferredSize(new Dimension(640, 480));
}
diff --git a/src/antidote/org/apache/tools/ant/gui/BuildEventForwarder.java b/src/antidote/org/apache/tools/ant/gui/BuildEventForwarder.java
new file mode 100644
index 000000000..c92b54bec
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/BuildEventForwarder.java
@@ -0,0 +1,151 @@
+/*
+ * 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
+ * .
+ */
+package org.apache.tools.ant.gui;
+import org.apache.tools.ant.gui.event.*;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.BuildEvent;
+
+/**
+ * BuildListener for forwarding events to the EventBus.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch
+ */
+public class BuildEventForwarder implements BuildListener {
+
+ /** Application context. */
+ private AppContext _context = null;
+
+ public BuildEventForwarder(AppContext context) {
+ _context = context;
+ }
+
+ /**
+ * Fired before any targets are started.
+ */
+ public void buildStarted(BuildEvent event){
+ postEvent(event, BuildEventType.BUILD_STARTED);
+ }
+
+ /**
+ * Fired after the last target has finished. This event
+ * will still be thrown if an error occured during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void buildFinished(BuildEvent event) {
+ postEvent(event, BuildEventType.BUILD_FINISHED);
+ }
+
+ /**
+ * Fired when a target is started.
+ *
+ * @see BuildEvent#getTarget()
+ */
+ public void targetStarted(BuildEvent event) {
+ postEvent(event, BuildEventType.TARGET_STARTED);
+ }
+
+ /**
+ * Fired when a target has finished. This event will
+ * still be thrown if an error occured during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void targetFinished(BuildEvent event) {
+ postEvent(event, BuildEventType.TARGET_FINISHED);
+ }
+
+ /**
+ * Fired when a task is started.
+ *
+ * @see BuildEvent#getTask()
+ */
+ public void taskStarted(BuildEvent event) {
+ postEvent(event, BuildEventType.TASK_STARTED);
+ }
+
+ /**
+ * Fired when a task has finished. This event will still
+ * be throw if an error occured during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void taskFinished(BuildEvent event) {
+ postEvent(event, BuildEventType.TASK_FINISHED);
+ }
+
+ /**
+ * Fired whenever a message is logged.
+ *
+ * @see BuildEvent#getMessage()
+ * @see BuildEvent#getPriority()
+ */
+ public void messageLogged(BuildEvent event) {
+ postEvent(event, BuildEventType.MESSAGE_LOGGED);
+ }
+
+ /**
+ * Forward the event.
+ *
+ * @param event Event to forward.
+ * @param type Description of how the event came in.
+ */
+ private void postEvent(BuildEvent event, BuildEventType type) {
+ _context.getEventBus().postEvent(
+ new AntBuildEvent(_context, event, type));
+ }
+
+
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/Console.java b/src/antidote/org/apache/tools/ant/gui/Console.java
index defa1947c..7dbcff2cf 100644
--- a/src/antidote/org/apache/tools/ant/gui/Console.java
+++ b/src/antidote/org/apache/tools/ant/gui/Console.java
@@ -52,10 +52,13 @@
* .
*/
package org.apache.tools.ant.gui;
-
+import org.apache.tools.ant.gui.event.*;
import javax.swing.*;
-import java.awt.GridLayout;
+import javax.swing.text.Document;
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
import java.awt.Dimension;
+import java.util.EventObject;
/**
* Logging console display.
@@ -63,22 +66,114 @@ import java.awt.Dimension;
* @version $Revision$
* @author Simeon Fitch
*/
-public class Console extends JPanel {
- private AppContext _context = null;
+public class Console extends AntEditor {
+ /** Area where messages are printed. */
private JTextPane _text = null;
-
+ /** Selection of logging levels. */
+ private JComboBox _logLevel = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param context Application context;
+ */
public Console(AppContext context) {
- setLayout(new GridLayout(1,1));
- _context = context;
+ super(context);
+ context.getEventBus().addMember(EventBus.MONITORING, new Handler());
+ setLayout(new BorderLayout());
_text = new JTextPane();
_text.setEditable(false);
JScrollPane scroller = new JScrollPane(_text);
+ scroller.setVerticalScrollBarPolicy(
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ add(BorderLayout.CENTER, scroller);
+
+ JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ JLabel label = new JLabel(
+ context.getResources().getString(getClass(), "logLevel"));
+ controls.add(label);
+ _logLevel = new JComboBox(LogLevelEnum.getValues());
+ controls.add(_logLevel);
- add(scroller);
+ add(BorderLayout.NORTH, controls);
- _text.setText(
- "This is the console area. \nLots of stuff to see here...");
- setPreferredSize(new Dimension(200, 40));
}
+
+ /** Class for handling project events. */
+ private class Handler implements BusMember {
+ private final Filter _filter = new Filter();
+
+ /**
+ * Get the filter to that is used to determine if an event should
+ * to to the member.
+ *
+ * @return Filter to use.
+ */
+ public BusFilter getBusFilter() {
+ return _filter;
+ }
+
+ /**
+ * Called when an event is to be posed to the member.
+ *
+ * @param event Event to post.
+ */
+ public void eventPosted(EventObject event) {
+ AntBuildEvent buildEvent = (AntBuildEvent) event;
+ String text = null;
+
+ Document doc = _text.getDocument();
+
+ switch(buildEvent.getType().getValue()) {
+ case BuildEventType.BUILD_STARTED_VAL:
+ try {
+ doc.remove(0, doc.getLength());
+ }
+ catch(Exception ex) {
+ // Intentionally ignored.
+ }
+ break;
+ case BuildEventType.TARGET_STARTED_VAL:
+ text = buildEvent.getEvent().getTarget().getName() + ":";
+ break;
+ case BuildEventType.TARGET_FINISHED_VAL:
+ case BuildEventType.TASK_STARTED_VAL:
+ case BuildEventType.TASK_FINISHED_VAL:
+ break;
+ case BuildEventType.MESSAGE_LOGGED_VAL:
+ text = buildEvent.toString();
+ break;
+ }
+
+ // Filter out events that are below our selected filterint level.
+ LogLevelEnum level = (LogLevelEnum) _logLevel.getSelectedItem();
+ if(buildEvent.getEvent().getPriority() > level.getValue()) return;
+
+ if(text != null) {
+ try {
+ doc.insertString(doc.getLength(), text, null);
+ doc.insertString(doc.getLength(), "\n", null);
+ }
+ catch(Exception ex) {
+ // XXX log me.
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /** Class providing filtering for project events. */
+ private static class Filter implements BusFilter {
+ /**
+ * Determines if the given event should be accepted.
+ *
+ * @param event Event to test.
+ * @return True if event should be given to BusMember, false otherwise.
+ */
+ public boolean accept(EventObject event) {
+ return event instanceof AntBuildEvent;
+ }
+ }
+
}
diff --git a/src/antidote/org/apache/tools/ant/gui/EventResponder.java b/src/antidote/org/apache/tools/ant/gui/EventResponder.java
index 0b32da1b5..3b180cd8f 100644
--- a/src/antidote/org/apache/tools/ant/gui/EventResponder.java
+++ b/src/antidote/org/apache/tools/ant/gui/EventResponder.java
@@ -117,6 +117,9 @@ class EventResponder {
if(command.equals(OpenCmd.ACTION_NAME)) {
new OpenCmd(_context).execute();
}
+ else if(command.equals(BuildCmd.ACTION_NAME)) {
+ new BuildCmd(_context).execute();
+ }
else if(command.equals(CloseCmd.ACTION_NAME)) {
new CloseCmd(_context).execute();
}
diff --git a/src/antidote/org/apache/tools/ant/gui/LogLevelEnum.java b/src/antidote/org/apache/tools/ant/gui/LogLevelEnum.java
new file mode 100644
index 000000000..0dd09c4a6
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/LogLevelEnum.java
@@ -0,0 +1,163 @@
+/*
+ * 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
+ * .
+ */
+package org.apache.tools.ant.gui;
+
+/**
+ * Enumeration class of the different log levels.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch
+ */
+public class LogLevelEnum {
+ /** Enum value. */
+ private int _value = 0;
+
+ /**
+ * Standard ctor.
+ *
+ * @param value Index value.
+ */
+ private LogLevelEnum(int value) {
+ _value = value;
+ }
+
+ /**
+ * Get the enumeration value.
+ *
+ * @return
+ */
+ public int getValue() {
+ return _value;
+ }
+
+ /**
+ * Get the enumeration value with the given index value.
+ *
+ * @param value Index value.
+ * @return Enumeration value.
+ */
+ public static LogLevelEnum fromInt(int value) {
+ return _objectMap[value];
+ }
+
+ /**
+ * Get the set of enumeration values.
+ *
+ * @return Value set.
+ */
+ public static LogLevelEnum[] getValues() {
+ return _objectMap;
+ }
+
+ /**
+ * Determine if the given object is logically equal to this one.
+ *
+ * @param o Object to compare to
+ * @return True if equal, false otherwise.
+ */
+ public boolean equals(Object o) {
+ if(o instanceof LogLevelEnum) {
+ return ((LogLevelEnum)o)._value == _value;
+ }
+ return false;
+ }
+ /**
+ * Generate a hash value.
+ *
+ * @return Hash value.
+ */
+ public int hashValue() {
+ return _value;
+ }
+
+ /**
+ * Provide a string representation of this.
+ *
+ * @return String representation.
+ */
+ public String toString() {
+ return _stringMap[_value];
+ }
+
+
+ /* Index values. */
+ public static final int ERROR_VAL = 0;
+ public static final int WARNING_VAL = 1;
+ public static final int INFO_VAL = 2;
+ public static final int VERBOSE_VAL = 3;
+ public static final int DEBUG_VAL = 4;
+
+ /* Enumeration values. */
+ public static final LogLevelEnum ERROR =
+ new LogLevelEnum(ERROR_VAL);
+ public static final LogLevelEnum WARNING =
+ new LogLevelEnum(WARNING_VAL);
+ public static final LogLevelEnum INFO =
+ new LogLevelEnum(INFO_VAL);
+ public static final LogLevelEnum VERBOSE =
+ new LogLevelEnum(VERBOSE_VAL);
+ public static final LogLevelEnum DEBUG =
+ new LogLevelEnum(DEBUG_VAL);
+
+ /** Index to object mapping. */
+ private static final LogLevelEnum[] _objectMap = {
+ ERROR, WARNING, INFO, VERBOSE, DEBUG
+ };
+
+ /** String map. XXX needs to be localized. */
+ private static final String[] _stringMap = {
+ "Error", "Warning", "Info", "Verbose", "Debug"
+ };
+
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/Main.java b/src/antidote/org/apache/tools/ant/gui/Main.java
index 492d44a34..3283e7ce8 100644
--- a/src/antidote/org/apache/tools/ant/gui/Main.java
+++ b/src/antidote/org/apache/tools/ant/gui/Main.java
@@ -52,7 +52,7 @@
* .
*/
package org.apache.tools.ant.gui;
-
+import org.apache.tools.ant.gui.util.WindowUtils;
import javax.swing.*;
import java.awt.BorderLayout;
@@ -82,10 +82,19 @@ public class Main {
f.getContentPane().add(BorderLayout.NORTH,
context.getActions().createToolBar());
+ ImageIcon icon =
+ context.getResources().getImageIcon("icon-small.gif");
+ if(icon != null) {
+ f.setIconImage(icon.getImage());
+ }
+ else {
+ System.out.println("Application icon not found.");
+ }
f.pack();
+
f.setVisible(true);
// Hack around linux window placement annoyance.
- f.setLocation(100, 100);
+ WindowUtils.centerWindow(f);
}
catch(Exception ex) {
diff --git a/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java b/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java
index 31ff1af89..523a2c5d1 100644
--- a/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java
+++ b/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java
@@ -85,7 +85,7 @@ class ProjectNavigator extends AntEditor {
JScrollPane scroller = new JScrollPane(_tree);
add(scroller);
- setPreferredSize(new Dimension(100, 100));
+ setPreferredSize(new Dimension(150, 100));
}
diff --git a/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java b/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java
index b6979a43e..b2496fee5 100644
--- a/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java
+++ b/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java
@@ -54,10 +54,15 @@
package org.apache.tools.ant.gui;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.gui.event.*;
import java.io.File;
import java.io.IOException;
import javax.swing.tree.TreeModel;
import javax.swing.text.Document;
+import java.util.Enumeration;
/**
* This class provides the gateway interface to the data model for
@@ -70,44 +75,59 @@ import javax.swing.text.Document;
*/
public class ProjectProxy {
+ /** Application context */
+ private AppContext _context = null;
/** The file where the project was last saved. */
private File _file = null;
-
/** The real Ant Project instance. */
private Project _project = null;
-
- /**
- * Default constructor. NB: right now it is private, but
- * will be opened up once the gui supports creating new projects.
- *
- */
- private ProjectProxy() {
- }
+ /** Private the current thread executing a build. */
+ private Thread _buildThread = null;
/**
* File loading ctor.
*
* @param file File containing build file to load.
*/
- public ProjectProxy(File file) throws IOException {
- this();
+ public ProjectProxy(AppContext context, File file) throws IOException {
_file = file;
+ _context = context;
loadProject();
}
-
+ /**
+ * Load the project from the build file.
+ *
+ */
private void loadProject() throws IOException {
_project = new Project();
- _project.init();
+ synchronized(_project) {
+ _project.init();
- // XXX there is a bunch of stuff in the class org.apache.tools.ant.Main
- // that needs to be abstracted out so that it doesn't
- // have to be replicated here.
+ // XXX there is a bunch of stuff in the class
+ // org.apache.tools.ant.Main that needs to be
+ // abstracted out so that it doesn't have to be
+ // replicated here.
- // XXX need to provide a way to pass in externally defined properties.
- // Perhaps define an external Antidote properties file.
- _project.setUserProperty("ant.file" , _file.getAbsolutePath());
- ProjectHelper.configureProject(_project, _file);
+ // XXX need to provide a way to pass in externally
+ // defined properties. Perhaps define an external
+ // Antidote properties file.
+ _project.setUserProperty("ant.file" , _file.getAbsolutePath());
+ ProjectHelper.configureProject(_project, _file);
+ }
+ }
+
+ /**
+ * Build the project with the current target (or the default target
+ * if none is selected. Build occurs on a separate thread, so method
+ * returns immediately.
+ *
+ */
+ public void build() throws BuildException {
+ if(_project == null) return;
+
+ _buildThread = new Thread(new BuildRunner());
+ _buildThread.start();
}
/**
@@ -146,4 +166,56 @@ public class ProjectProxy {
}
return null;
}
+
+ /**
+ * Convenience method for causeing the project to fire a build event.
+ * Implemented because the corresponding method in the Project class
+ * is not publically accessible.
+ *
+ * @param event Event to fire.
+ */
+ private void fireBuildEvent(BuildEvent event, BuildEventType type) {
+ synchronized(_project) {
+ Enumeration enum = _project.getBuildListeners().elements();
+ while(enum.hasMoreElements()) {
+ BuildListener l = (BuildListener) enum.nextElement();
+ type.fireEvent(event, l);
+ }
+ }
+ }
+
+ /** Class for executing the build in a separate thread. */
+ private class BuildRunner implements Runnable {
+ public void run() {
+ synchronized(_project) {
+ // Add the build listener for
+ // dispatching BuildEvent objects to the
+ // EventBus.
+ BuildEventForwarder handler =
+ new BuildEventForwarder(_context);
+ _project.addBuildListener(handler);
+ try {
+ fireBuildEvent(new BuildEvent(
+ _project), BuildEventType.BUILD_STARTED);
+ // XXX add code to indicate target execution
+ // on the targets that are selected.
+ _project.executeTarget(
+ _project.getDefaultTarget());
+ }
+ catch(BuildException ex) {
+ BuildEvent errorEvent = new BuildEvent(_project);
+ errorEvent.setException(ex);
+ errorEvent.setMessage(ex.getMessage(), Project.MSG_ERR);
+ fireBuildEvent(errorEvent, BuildEventType.MESSAGE_LOGGED);
+ }
+ finally {
+ fireBuildEvent(new BuildEvent(
+ _project), BuildEventType.BUILD_FINISHED);
+ _project.removeBuildListener(handler);
+ _buildThread = null;
+ }
+ }
+ }
+ }
+
}
diff --git a/src/antidote/org/apache/tools/ant/gui/ResourceManager.java b/src/antidote/org/apache/tools/ant/gui/ResourceManager.java
index 0ec6a5c87..9b03913f2 100644
--- a/src/antidote/org/apache/tools/ant/gui/ResourceManager.java
+++ b/src/antidote/org/apache/tools/ant/gui/ResourceManager.java
@@ -55,6 +55,9 @@ package org.apache.tools.ant.gui;
import java.util.*;
import java.text.MessageFormat;
+import javax.swing.ImageIcon;
+import java.net.URL;
+import java.io.File;
/**
* Singleton class for accessing various resources by the application.
@@ -143,4 +146,22 @@ public class ResourceManager {
return MessageFormat.format(format, arguments);
}
+ /**
+ * Get the image as an ImageIcon with the given file name.
+ * For example "open.gif". The image is loaded from the resources package.
+ *
+ * @param fileName Image file to load.
+ * @return Image as an ImageIcon, or null if not found.
+ */
+ public ImageIcon getImageIcon(String fileName) {
+ ImageIcon icon = null;
+
+ URL location = getClass().getResource("resources/" + fileName);
+
+ if(location != null) {
+ icon = new ImageIcon(location);
+ }
+ return icon;
+ }
+
}
diff --git a/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java b/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java
new file mode 100644
index 000000000..684fb8859
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+q *
+ * 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
+ * .
+ */
+package org.apache.tools.ant.gui.command;
+import org.apache.tools.ant.gui.AppContext;
+import org.apache.tools.ant.gui.ProjectProxy;
+
+/**
+ * Starts an Ant build.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch
+ */
+public class BuildCmd implements Command {
+ /** Name of the action the command maps to. */
+ public static final String ACTION_NAME = "startBuild";
+
+ /** The application context */
+ private AppContext _context = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param context Application context.
+ */
+ public BuildCmd(AppContext context) {
+ _context = context;
+ }
+
+ /**
+ * Start the Ant build.
+ *
+ */
+ public void execute() {
+ ProjectProxy project = _context.getProject();
+ if(project != null) {
+ project.build();
+ }
+ }
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java b/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java
index 473393c01..3fd3f8fa9 100644
--- a/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java
+++ b/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java
@@ -95,7 +95,7 @@ public class LoadFileCmd implements Command {
}
else {
try {
- ProjectProxy project = new ProjectProxy(_file);
+ ProjectProxy project = new ProjectProxy(_context, _file);
_context.setProject(project);
}
catch(IOException ex) {
diff --git a/src/antidote/org/apache/tools/ant/gui/event/AntBuildEvent.java b/src/antidote/org/apache/tools/ant/gui/event/AntBuildEvent.java
new file mode 100644
index 000000000..52f3f9072
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/event/AntBuildEvent.java
@@ -0,0 +1,138 @@
+/*
+ * 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
+ * .
+ */
+package org.apache.tools.ant.gui.event;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.gui.util.StackFrame;
+import org.apache.tools.ant.gui.command.Command;
+import org.apache.tools.ant.gui.command.NoOpCmd;
+import org.apache.tools.ant.gui.AppContext;
+import java.util.EventObject;
+
+/**
+ * Wrapper event for the events generated during an Ant build.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch
+ */
+public class AntBuildEvent extends AntEvent {
+
+ /** The original event we are wrapping. */
+ private BuildEvent _buildEvent = null;
+ /** The type of event we are wrapping. */
+ private BuildEventType _type = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param context application context.
+ */
+ public AntBuildEvent(AppContext context,
+ BuildEvent buildEvent, BuildEventType type) {
+ super(context);
+ _buildEvent = buildEvent;
+ _type = type;
+
+ if(_buildEvent == null || _type == null) {
+ throw new IllegalArgumentException("Null parameter passed");
+ }
+ }
+
+ /**
+ * Get the wrapped build event.
+ *
+ * @return Build event.
+ */
+ public BuildEvent getEvent() {
+ return _buildEvent;
+ }
+
+ /**
+ * Get the build event type.
+ *
+ * @return Event type.
+ */
+ public BuildEventType getType() {
+ return _type;
+ }
+
+ /**
+ * Create the appropriate default response command to this event.
+ *
+ * @return Command representing an appropriate response to this event.
+ */
+ public Command createDefaultCmd() {
+ return new NoOpCmd();
+ }
+
+ /**
+ * Create a string representation of this.
+ *
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ if(_buildEvent.getMessage() != null) {
+ buf.append(_buildEvent.getMessage());
+ buf.append('\n');
+ }
+
+ if(_buildEvent.getException() != null) {
+ buf.append(StackFrame.toString(_buildEvent.getException()));
+ }
+
+ return buf.toString();
+ }
+
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/event/BuildEventType.java b/src/antidote/org/apache/tools/ant/gui/event/BuildEventType.java
new file mode 100644
index 000000000..be23dada6
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/event/BuildEventType.java
@@ -0,0 +1,208 @@
+/*
+ * 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
+ * .
+ */
+package org.apache.tools.ant.gui.event;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.BuildEvent;
+import java.lang.reflect.Method;
+
+/**
+ * Enumeration class of the different contexts in which Ant will generate
+ * a BuildEvent.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch
+ */
+public class BuildEventType {
+ /** Enum value. */
+ private int _value = 0;
+
+ /**
+ * Standard ctor.
+ *
+ * @param value Index value.
+ */
+ private BuildEventType(int value) {
+ _value = value;
+ }
+
+ /**
+ * Get the enumeration value.
+ *
+ * @return
+ */
+ public int getValue() {
+ return _value;
+ }
+
+ /**
+ * Pseudo abstract method for firing an event to a build listener
+ * based on our enumation value. I overridded by the individual instances.
+ *
+ * @param e Event to fire.
+ * @param l Listener to send event to.
+ */
+ public void fireEvent(BuildEvent e, BuildListener l) {
+ try {
+ Method method =
+ BuildListener.class.getMethod(_methodNameMap[_value],
+ _listenerMethodParam);
+ method.invoke(l, new Object[] { e });
+ }
+ catch(Exception ex) {
+ // XXX log me.
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Get the enumeration value with the given index value.
+ *
+ * @param value Index value.
+ * @return Enumeration value.
+ */
+ public static BuildEventType fromInt(int value) {
+ return _objectMap[value];
+ }
+
+ /**
+ * Determine if the given object is logically equal to this one.
+ *
+ * @param o Object to compare to
+ * @return True if equal, false otherwise.
+ */
+ public boolean equals(Object o) {
+ if(o instanceof BuildEventType) {
+ return ((BuildEventType)o)._value == _value;
+ }
+ return false;
+ }
+ /**
+ * Generate a hash value.
+ *
+ * @return Hash value.
+ */
+ public int hashValue() {
+ return _value;
+ }
+
+ /**
+ * Provide a string representation of this.
+ *
+ * @return String representation.
+ */
+ public String toString() {
+ return _stringMap[_value];
+ }
+
+
+ /* Index values. */
+ public static final int BUILD_STARTED_VAL = 0;
+ public static final int BUILD_FINISHED_VAL = 1;
+ public static final int TARGET_STARTED_VAL = 2;
+ public static final int TARGET_FINISHED_VAL = 3;
+ public static final int TASK_STARTED_VAL = 4;
+ public static final int TASK_FINISHED_VAL = 5;
+ public static final int MESSAGE_LOGGED_VAL = 6;
+
+ /* Enumeration values. */
+ public static final BuildEventType BUILD_STARTED =
+ new BuildEventType(BUILD_STARTED_VAL);
+ public static final BuildEventType BUILD_FINISHED =
+ new BuildEventType(BUILD_FINISHED_VAL);
+ public static final BuildEventType TARGET_STARTED =
+ new BuildEventType(TARGET_STARTED_VAL);
+ public static final BuildEventType TARGET_FINISHED =
+ new BuildEventType(TARGET_FINISHED_VAL);
+ public static final BuildEventType TASK_STARTED =
+ new BuildEventType(TASK_STARTED_VAL);
+ public static final BuildEventType TASK_FINISHED =
+ new BuildEventType(TASK_FINISHED_VAL);
+ public static final BuildEventType MESSAGE_LOGGED =
+ new BuildEventType(MESSAGE_LOGGED_VAL);
+
+ /** Index to object mapping. */
+ private static final BuildEventType[] _objectMap = {
+ BUILD_STARTED,
+ BUILD_FINISHED,
+ TARGET_STARTED,
+ TARGET_FINISHED,
+ TASK_STARTED,
+ TASK_FINISHED,
+ MESSAGE_LOGGED
+ };
+
+ /** String map. XXX needs to be localized. */
+ private static final String[] _stringMap = {
+ "Build Started",
+ "Build Finished",
+ "Target Started",
+ "Target Finished",
+ "Task Started",
+ "Task Finished",
+ "Message Logged"
+ };
+
+ /** Map of corresponding method names in the BuildListener intereface. */
+ private static final String[] _methodNameMap = {
+ "buildStarted",
+ "buildFinished",
+ "targetStarted",
+ "targetFinished",
+ "taskStarted",
+ "taskFinished",
+ "messageLogged"
+ };
+
+ private static final Class[] _listenerMethodParam = { BuildEvent.class };
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/event/EventBus.java b/src/antidote/org/apache/tools/ant/gui/event/EventBus.java
index 2ab048f78..d5b1d6ea9 100644
--- a/src/antidote/org/apache/tools/ant/gui/event/EventBus.java
+++ b/src/antidote/org/apache/tools/ant/gui/event/EventBus.java
@@ -54,7 +54,7 @@
package org.apache.tools.ant.gui.event;
import java.util.*;
-
+import javax.swing.SwingUtilities;
/**
* An event "bus" providing a centralized place for posting
* and recieving generic application events. To receive events a class must
@@ -142,29 +142,55 @@ public class EventBus {
* @param event Event to post.
*/
public void postEvent(EventObject event) {
- synchronized(_memberSet) {
- // XXX need to insert code here to test whether we are being
- // executed by the AWTEventQueue, or some other thread. If
- // the latter, then we need to insert our execution on the
- // AWTEventQueue thread as all code executing commands assumes
- // that context.
+ EventDispatcher disp = new EventDispatcher(event);
- for(int i = 0; i < _memberSet.length; i++) {
- if(_memberSet[i] == null) continue;
+ // Events need to be dispatched on the AWTEvent thread, as the UI
+ // components assume that.
+ if(SwingUtilities.isEventDispatchThread()) {
+ disp.run();
+ }
+ else {
+ SwingUtilities.invokeLater(disp);
+ }
+ }
- Iterator it = _memberSet[i].iterator();
- while(it.hasNext()) {
- BusMember next = (BusMember) it.next();
- BusFilter filter = next.getBusFilter();
- if(filter == null || filter.accept(event)) {
- next.eventPosted(event);
- }
- // Check to see if the member cancelled the event. If so
- // then don't send it on to the other members.
- if(event instanceof AntEvent &&
- ((AntEvent)event).isCancelled()) break;
- }
- }
+ /** Class that performs the duty of dispatching events to the members. */
+ private class EventDispatcher implements Runnable {
+ /** Event to dispatch. */
+ private EventObject _event = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param event Event to dispatch.
+ */
+ public EventDispatcher(EventObject event) {
+ _event = event;
+ }
+
+ /**
+ * Perform dispatching.
+ *
+ */
+ public void run() {
+ synchronized(_memberSet) {
+ for(int i = 0; i < _memberSet.length; i++) {
+ if(_memberSet[i] == null) continue;
+
+ Iterator it = _memberSet[i].iterator();
+ while(it.hasNext()) {
+ BusMember next = (BusMember) it.next();
+ BusFilter filter = next.getBusFilter();
+ if(filter == null || filter.accept(_event)) {
+ next.eventPosted(_event);
+ }
+ // Check to see if the member cancelled the event. If so
+ // then don't send it on to the other members.
+ if(_event instanceof AntEvent &&
+ ((AntEvent)_event).isCancelled()) break;
+ }
+ }
+ }
}
}
}
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/action.properties b/src/antidote/org/apache/tools/ant/gui/resources/action.properties
index 03fddbfef..bcf1c8617 100644
--- a/src/antidote/org/apache/tools/ant/gui/resources/action.properties
+++ b/src/antidote/org/apache/tools/ant/gui/resources/action.properties
@@ -1,21 +1,24 @@
-menus=File, Help
+menus=File, Build, Help
-actions=open, close, exit, about
+actions=open, close, exit, about, startBuild, stopBuild
new.name=New
new.shortDescription=Create a new project
new.parentMenuName=File
new.icon=new.gif
+new.accelerator=control N
open.name=Open
open.shortDescription=Open an existing project
open.parentMenuName=File
open.icon=open.gif
+open.accelerator=control O
save.name=Save
save.shortDescription=Save the current project
save.parentMenuName=File
save.icon=save.gif
+save.accelerator=control S
close.name=Close
close.shortDescription=Close the current project
@@ -30,3 +33,17 @@ about.name=About
about.shortDescription=About this application
about.parentMenuName=Help
about.separator=true;
+
+startBuild.name=Start
+startBuild.shortDescription=Start build of selected target
+startBuild.parentMenuName=Build
+startBuild.icon=start.gif
+startBuild.separator=true
+startBuild.accelerator=control B
+
+stopBuild.name=Stop
+stopBuild.shortDescription=Stop the current build
+stopBuild.parentMenuName=Build
+stopBuild.icon=stop.gif
+stopBuild.accelerator=control K
+
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties b/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties
index 12b8249fb..8b6119161 100644
--- a/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties
+++ b/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties
@@ -9,10 +9,16 @@ org.apache.tools.ant.gui.Antidote.right.editors=\
org.apache.tools.ant.gui.Antidote.left.editors=\
org.apache.tools.ant.gui.ProjectNavigator
+# Configure the editors that appear on the bottom of the UI.
+org.apache.tools.ant.gui.Antidote.bottom.editors=\
+ org.apache.tools.ant.gui.Console
+
# Set specific class properties.
org.apache.tools.ant.gui.SourceEditor.name=Source
org.apache.tools.ant.gui.PropertyEditor.name=Properties
-org.apache.tools.ant.gui.ProjectNavigator.name=Task Navigator
+org.apache.tools.ant.gui.ProjectNavigator.name=Project
+org.apache.tools.ant.gui.Console.name=Console
+org.apache.tools.ant.gui.Console.logLevel=Log message level:
org.apache.tools.ant.gui.XMLFileFilter.description=XML Files
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/default.gif b/src/antidote/org/apache/tools/ant/gui/resources/default.gif
new file mode 100644
index 0000000000000000000000000000000000000000..0c42bd3ae1268697e3420ad88c83d8ba8dc59422
GIT binary patch
literal 1212
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
literal 0
HcmV?d00001
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/start.gif b/src/antidote/org/apache/tools/ant/gui/resources/start.gif
new file mode 100644
index 0000000000000000000000000000000000000000..6a67694bed874061c749975414206db30a2f6d07
GIT binary patch
literal 888
zcmW+#&8v=a5Ist|N?AzV1sakCvaunlv+}jEko};nC4ayvk&=ytWHmk#rF>+qA>F!m
z%2Jt9);<=<;x%)po__B;&&-@T=lq`ICyyOEd~O-b_>BpzJz6`||D^2roR2?zr@;*}
zgdq)O0AU0PCqx91L=kY9gARAd5sq|}qvx4G!PSEiLJHMb0ShqT0RTWm%ikK8!%lfr*i)l^DOxM>Y4s4$t%~Z!wy8Q*1V~P$*N4JU7E)^!1o6BQhf^
z8oY6OWOsLA=W_Ayd&DD2i@q!iEY^-b`&Y-#zw6gcdVjy{FJc*3I*Y}|Z6{vD+p9}k
z_HKLf{QjG38@8Xivh?H2`G!_#%*>f{&hI&S>co+w=a;dJ-*k7}HqBuI+S(lOlsmvU-5ie6sG8
zGo0xxXOlEdsf!XrOtHjfZZZ8HR4{@WtYFJwIYT|EWF#|L$=1kW;WPvk||7SDiemyEabCJBR5FTQ|oI!Te?fGaHXrfM|O7?c5Wi1luBwR
zEYy6wQ=tfDs6uUzrJAI7T`E$Us#JSsrDpEkT#8bbs)V^0O|RYVqV}-uYG=kpv(dtB
zCWd8NmbE$U!wBRYm>79liSgTfRC6Ef@J!G07NdDL#bz@Lg)-I1b2BVPUys=`A~Uk0
z!5gPXc6S$cE*Jm4M?8|W=*zOeV*Ti|e|7BsyK%#$5BAIcB9?)rb69NNvGO9`UR&C>
zf5*M&=igl4wDa`Ur5|5bZ*ARvVfEhSukWwzI(}ly+Dluzv*pZ#*H3=#d3*QJ*>{ir
jT)FiA{^66~K0SSP@yzYL2W~vO`D@?Dhb!ARZN#zvQ?hZ%
literal 0
HcmV?d00001
diff --git a/src/antidote/org/apache/tools/ant/gui/util/WindowUtils.java b/src/antidote/org/apache/tools/ant/gui/util/WindowUtils.java
index 03bc38cb1..28582272d 100644
--- a/src/antidote/org/apache/tools/ant/gui/util/WindowUtils.java
+++ b/src/antidote/org/apache/tools/ant/gui/util/WindowUtils.java
@@ -82,7 +82,7 @@ public class WindowUtils {
}
/**
- * Center the given child window with repsect to the child window.
+ * Center the given child window with repsect to the parent window.
*
* @param parent Window to base centering on.
* @param child Window to center.
@@ -94,4 +94,15 @@ public class WindowUtils {
bounds.y + (bounds.height - size.height)/2);
}
+ /**
+ * Center the given child window with repsect to the root.
+ *
+ * @param child Window to center.
+ */
+ public static void centerWindow(Window child) {
+ Dimension rsize = child.getToolkit().getScreenSize();
+ Dimension size = child.getSize();
+ child.setLocation((rsize.width - size.width)/2,
+ (rsize.height - size.height)/2);
+ }
}