*) Design document. *) can now write BuildEvents to console. Submitted by: Simeon Fitch <metasim@yahoo.com> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268152 13f79535-47bb-0310-9956-ffa450edef68master
@@ -4,6 +4,8 @@ Changes from Ant 1.2 to the current sources | |||||
Other changes: | Other changes: | ||||
-------------- | -------------- | ||||
* A GUI Frontend: Antidote | |||||
* New tasks: propertyfile, depend, antlr | * New tasks: propertyfile, depend, antlr | ||||
* Added output attribute to <java>. | * Added output attribute to <java>. | ||||
@@ -1,3 +1,43 @@ | |||||
2000-11-05 Simeon H.K. Fitch <simeon@fitch.net> | |||||
* 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 <simeon@fitch.net> | |||||
* 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 <simeon@fitch.net> | |||||
* 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 <simeon@fitch.net> | 2000-11-02 Simeon H.K. Fitch <simeon@fitch.net> | ||||
* org/apache/tools/ant/gui/event/EventBus.java: Added interrupt | * org/apache/tools/ant/gui/event/EventBus.java: Added interrupt | ||||
@@ -50,8 +50,8 @@ | |||||
<javac srcdir="${src.dir}" | <javac srcdir="${src.dir}" | ||||
destdir="${build.classes}" | destdir="${build.classes}" | ||||
debug="on" | debug="on" | ||||
deprecation="off" | |||||
optimize="on" > | |||||
deprecation="on" | |||||
optimize="off" > | |||||
<classpath refid="classpath" /> | <classpath refid="classpath" /> | ||||
</javac> | </javac> | ||||
@@ -0,0 +1,258 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "strict.dtd"> | |||||
<HTML> | |||||
<HEAD> | |||||
<TITLE>Antidote Design Overview</TITLE> | |||||
</HEAD> | |||||
<BODY> | |||||
<H1>Antidote Design Overview</H1> | |||||
<P>Version 0.1 (2000/11/02)</P> | |||||
<P>Authors: | |||||
<A HREF="mailto:simeon@fitch.net">Simeon H.K. Fitch</A> | |||||
</P> | |||||
<H2>Introduction</H2> | |||||
<P>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 | |||||
;-)</P> | |||||
<H2>Overview</H2> | |||||
<P>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.</P> | |||||
<P>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.</P> | |||||
<P>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.</P> | |||||
<P>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 <TT>EventBus</TT>. | |||||
<TT><PRE> | |||||
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)| | |||||
| | | | | | | | | |||||
+---------------+ +----------------+ +-------------+ +--------------+ | |||||
</TT></PRE> | |||||
<H2>Event Bus</H2> | |||||
<P>The backbone of the application is the <TT>EventBus</TT>. Any | |||||
component of the application can post events to the | |||||
<TT>EventBus</TT>. Components that wish to receive events are | |||||
called <TT>BusMember</TT>s.</P> | |||||
<P>The <TT>EventBus</TT> will dispatch any object of type | |||||
<TT>java.util.EventBus</TT>, which means that Ant <TT>BuildEvent</TT> | |||||
objects, as well as <TT>AWTEvent</TT> objects can be posted (if desired). A | |||||
new class of events called <TT>AntEvent</TT> is defined for Antidote | |||||
specific events, which have the additional capability of being | |||||
cancelled mid-dispatch.</P> | |||||
<P>Each <TT>BusMember</TT> must provide a <TT>BusFilter</TT> instance, | |||||
which is the members' means of telling the bus which | |||||
events it is interested in. This allows a <TT>BusMember</TT> to, | |||||
say, only receive <TT>AntEvent</TT> objects.</P> | |||||
<P>When a <TT>BusMember</TT> registers itself with the | |||||
<TT>EventBus</TT>, it must provide a (so called) <I>interrupt | |||||
level</I> which is a integer value defining a relative ordering | |||||
for dispatching <TT>EventObject</TT>s to <TT>BusMember</TT>s. The | |||||
purpose of this is to allow certain <TT>BusMember</TT> instances | |||||
to see an event before others, and in the case of <TT>AntEvent</TT | |||||
objects, keep the event from propogating onward. The | |||||
<TT>EventBus</TT> class defines the interrupt level constants | |||||
<TT>MONITORING=1</TT>, <TT>VETOING=5</TT>, and <TT>RESPONDING=10</TT> to | |||||
help define categories of members. The implied purpose being that: | |||||
<UL> | |||||
<LI><TT>MONITORING</TT>: Just listens for events, like a logger | |||||
or status monitor.</LI> | |||||
<LI><TT>VETOING</TT>: 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 | |||||
<TT>RESPONDING</TT> group. An example of this might be to handle | |||||
a <I>SaveAs</I> event, whereby a <TT>VETOING</TT> 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 <I>SaveAs</I> | |||||
event could then be cancelled before the operation is executed.</LI> | |||||
<LI><TT>RESPONDING</TT>: Process events in a default manner, | |||||
knowing that the event has passed any <TT>VETOING</TT> members.</LI> | |||||
</UL> | |||||
Within a specific interrupt level, the order in which members will | |||||
receive events is undefied. A <TT>BusMember</TT> may be registered | |||||
at a level that is +/- of one of the defined levels, as long as it | |||||
follows the constraint <TT>MONITORING <= interruptLevel <= | |||||
MAX_INTERRUPT</TT>.</P> | |||||
<H2>Actions and ActionManager</H2> | |||||
<P>Extensive use of the <TT>javax.swing.Action</TT> interface is | |||||
made for defining the set of menu and tool bar options that are | |||||
available. The configuration file <TT>action.properties</TT> | |||||
exists to define what should appear in the menu and toolbar, how | |||||
it is displayed, and the <TT>Action</TT> command name that is | |||||
dispatched when the user invokes that action. A class called | |||||
<TT>ActionManager</TT> exists for not only processing the | |||||
configuration file, but also for dispatching invoked action events | |||||
to the <TT>EventBus</TT>, and for controlling the enabled state of | |||||
an <TT>Action</TT>. When a new menu item or toolbar button is | |||||
desired, first it is added to the <TT>action.properties</TT> file, | |||||
and then the code to respond to it is added to the | |||||
<TT>EventResponder</TT> (see below). | |||||
<H2>Commands and EventResponder</H2> | |||||
<P>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 <TT>Command</TT> interface is defined to classify | |||||
code which performs some task or operation. This is distinct from | |||||
an <TT>Action</TT>, which is a user request for an operation. A | |||||
<TT>Command</TT> class is the encapsulation of the operation | |||||
itself.</P> | |||||
<P>When an <TT>Action</TT> generates an <TT>ActionEvent</TT>, the | |||||
event is posted to the <TT>EventBus</TT> which delivers the event | |||||
to all interested <TT>BusMember</TT>s. It eventually makes it to | |||||
the <TT>EventResponder</TT> instance (registered at the | |||||
<TT>RESPONDING</TT> interrupt level), which is responsible for | |||||
translating specific events into <TT>Command</TT> objects, and | |||||
then executing the <TT>Command</TT> object. For example, when the | |||||
user selects the "Open..." menu option, an <TT>ActionEvent</TT> is | |||||
generated by the Swing <TT>MenuItem</TT> class, which is then | |||||
posted to the <TT>EventBus</TT> by the <TT>ActionManager</TT>. The | |||||
<TT>ActionEvent</TT> is delivered to the <TT>EventResponder</TT>, | |||||
which converts the <TT>ActionEvent</TT> into a <TT>Command</TT> | |||||
instance. The <TT>EventResponder</TT> then calls the method | |||||
<TT>Command.execute()</TT> to invoke the command (which displays a | |||||
dialog for selecting a file to open).</P> | |||||
<P>When adding new <TT>Action</TT>s or general tasks to the | |||||
application, a <TT>Command</TT> object should be created to | |||||
encapsulate the behavior. This includes most operations which | |||||
modify the state of the data model.</P> | |||||
<P>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.</P> | |||||
<H2>Data Model and Views</H2> | |||||
<P>The data model is mainly defined by the Ant application, | |||||
primarily through the <TT>Project</TT>, <TT>Target</TT>, and | |||||
<TT>Task</TT> classes.<P> However, Antidote defines the class | |||||
<TT>ProjectProxy</TT> to act not only as a proxy to the real | |||||
<TT>Project</TT> class, but also as creator of GUI <I>views</I> of | |||||
the <TT>Project</TT>. A <I>view</I> is essentially a flyweight or | |||||
data proxy; it provides an orgainizational perspective on the actual | |||||
<TT>Project</TT> structure. For example, to render a | |||||
<TT>JTree</TT> version of the <TT>Project</TT>, one would call the | |||||
method <TT>ProjectProxy.getTreeModel()</TT>. Similarly, to get a | |||||
<TT>Document</TT> version of the <TT>Project</TT>, the | |||||
<TT>ProjectProxy,getDocument()</TT> method is used.</P> | |||||
<P><I>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.</I></P> | |||||
<H2>Application Context</H2> | |||||
<P>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 <TT>AppContext</TT> is the catch-all | |||||
class for containing the application state. Most modules and | |||||
<TT>Command</TT> classes require an instance of the | |||||
<TT>AppContext</TT> class. Because all state information in | |||||
contained in an <TT>AppContext</TT> instance, multiple instances | |||||
of Antidote can run inside the same JVM as long as each has it's | |||||
own <TT>AppContext</TT>. (Interestingly, two instances of the | |||||
Antidote could conceivably share an <TT>AppContext</TT> instance | |||||
through RMI, allowing remote interaction/collaboration.)</P> | |||||
<H2>Configuration and ResourceManager</H2> | |||||
<P>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 | |||||
<TT>antidote.properties</TT>, which is located (with other UI | |||||
resources) in the subpackage "resources".</P> | |||||
<P>To aid in the lookup of text properties, as well as other | |||||
resources like icons, a class called <TT>ResourceManager</TT> 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.</P> | |||||
<P>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 "<TT>org.apache.tools.ant.gui.About.message</TT>" for the text | |||||
message it should display. Therefore, the <TT>ResourceManager</TT> | |||||
method <TT>getString()</TT> takes a <TT>Class</TT> instance as | |||||
well as a <TT>String</TT> key. Please see the | |||||
<TT>ResourceManager</TT> documentation for more information. Given | |||||
this support, no user visible strings should appear in the source | |||||
code itself.</P> | |||||
</BODY> | |||||
</HTML> |
@@ -113,7 +113,24 @@ public class ActionManager { | |||||
while(tok.hasMoreTokens()) { | while(tok.hasMoreTokens()) { | ||||
String name = tok.nextToken(); | String name = tok.nextToken(); | ||||
JMenu menu = new JMenu(name); | 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); | menus.put(name, menu); | ||||
} | } | ||||
@@ -130,10 +147,13 @@ public class ActionManager { | |||||
menus.put(parent, menu); | menus.put(parent, menu); | ||||
} | } | ||||
if(action.isPreceededBySeparator()) { | |||||
// See if we should add a separator. | |||||
if(action.isPreceededBySeparator() && | |||||
menu.getMenuComponentCount() > 0) { | |||||
menu.addSeparator(); | menu.addSeparator(); | ||||
} | } | ||||
JMenuItem item = menu.add(action); | JMenuItem item = menu.add(action); | ||||
item.setAccelerator(action.getAccelerator()); | |||||
addNiceStuff(item, action); | addNiceStuff(item, action); | ||||
} | } | ||||
} | } | ||||
@@ -171,6 +191,13 @@ public class ActionManager { | |||||
// Set the action command so that it is consitent | // Set the action command so that it is consitent | ||||
// no matter what language the display is in. | // no matter what language the display is in. | ||||
button.setActionCommand(action.getID()); | 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(); | String tip = action.getShortDescription(); | ||||
if(tip != null) { | if(tip != null) { | ||||
button.setToolTipText(tip); | button.setToolTipText(tip); | ||||
@@ -202,6 +229,7 @@ public class ActionManager { | |||||
/** Property name for the parent menu item. */ | /** Property name for the parent menu item. */ | ||||
public static final String PARENT_MENU_NAME = "parentMenuName"; | public static final String PARENT_MENU_NAME = "parentMenuName"; | ||||
public static final String SEPARATOR = "separator"; | public static final String SEPARATOR = "separator"; | ||||
public static final String ACCELERATOR = "accelerator"; | |||||
/** Unique id. */ | /** Unique id. */ | ||||
private String _id = null; | private String _id = null; | ||||
@@ -215,8 +243,14 @@ public class ActionManager { | |||||
_id = id; | _id = id; | ||||
putValue(NAME, getString(id, "name")); | putValue(NAME, getString(id, "name")); | ||||
putValue(SHORT_DESCRIPTION, getString(id, "shortDescription")); | 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"); | String iconName = getString(id, "icon"); | ||||
if(iconName != null) { | if(iconName != null) { | ||||
@@ -232,7 +266,6 @@ public class ActionManager { | |||||
ex.printStackTrace(); | ex.printStackTrace(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
@@ -291,6 +324,10 @@ public class ActionManager { | |||||
return (Icon) getValue(SMALL_ICON); | return (Icon) getValue(SMALL_ICON); | ||||
} | } | ||||
public KeyStroke getAccelerator() { | |||||
return (KeyStroke) getValue(ACCELERATOR); | |||||
} | |||||
/** | /** | ||||
* Pass the action on to the EventBus. | * Pass the action on to the EventBus. | ||||
* | * | ||||
@@ -54,6 +54,7 @@ | |||||
package org.apache.tools.ant.gui; | package org.apache.tools.ant.gui; | ||||
import javax.swing.JPanel; | import javax.swing.JPanel; | ||||
import javax.swing.BorderFactory; | |||||
/** | /** | ||||
* Abstract base class for an "editor", which is really anything that | * 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) { | protected AntEditor(AppContext context) { | ||||
_context = context; | _context = context; | ||||
setBorder(BorderFactory.createTitledBorder(getName())); | |||||
} | } | ||||
/** | /** | ||||
@@ -66,11 +66,6 @@ import java.lang.reflect.Constructor; | |||||
* @author Simeon Fitch | * @author Simeon Fitch | ||||
*/ | */ | ||||
public class Antidote extends JPanel { | public class Antidote extends JPanel { | ||||
/** Logging console. */ | |||||
private Console _console = null; | |||||
/** Source of application state data. */ | /** Source of application state data. */ | ||||
private AppContext _context = null; | private AppContext _context = null; | ||||
@@ -83,18 +78,25 @@ public class Antidote extends JPanel { | |||||
_context = context; | _context = context; | ||||
_console = new Console(_context); | |||||
// Add the various editors/views to the editing area. | // Add the various editors/views to the editing area. | ||||
JSplitPane splitter = new JSplitPane(); | JSplitPane splitter = new JSplitPane(); | ||||
splitter.add(JSplitPane.LEFT, populateEditors("left")); | splitter.add(JSplitPane.LEFT, populateEditors("left")); | ||||
splitter.add(JSplitPane.RIGHT, populateEditors("right")); | 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)); | setPreferredSize(new Dimension(640, 480)); | ||||
} | } | ||||
@@ -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 | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
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)); | |||||
} | |||||
} |
@@ -52,10 +52,13 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.tools.ant.gui; | package org.apache.tools.ant.gui; | ||||
import org.apache.tools.ant.gui.event.*; | |||||
import javax.swing.*; | 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.awt.Dimension; | ||||
import java.util.EventObject; | |||||
/** | /** | ||||
* Logging console display. | * Logging console display. | ||||
@@ -63,22 +66,114 @@ import java.awt.Dimension; | |||||
* @version $Revision$ | * @version $Revision$ | ||||
* @author Simeon Fitch | * @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; | private JTextPane _text = null; | ||||
/** Selection of logging levels. */ | |||||
private JComboBox _logLevel = null; | |||||
/** | |||||
* Standard ctor. | |||||
* | |||||
* @param context Application context; | |||||
*/ | |||||
public Console(AppContext 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 = new JTextPane(); | ||||
_text.setEditable(false); | _text.setEditable(false); | ||||
JScrollPane scroller = new JScrollPane(_text); | 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; | |||||
} | |||||
} | |||||
} | } |
@@ -117,6 +117,9 @@ class EventResponder { | |||||
if(command.equals(OpenCmd.ACTION_NAME)) { | if(command.equals(OpenCmd.ACTION_NAME)) { | ||||
new OpenCmd(_context).execute(); | new OpenCmd(_context).execute(); | ||||
} | } | ||||
else if(command.equals(BuildCmd.ACTION_NAME)) { | |||||
new BuildCmd(_context).execute(); | |||||
} | |||||
else if(command.equals(CloseCmd.ACTION_NAME)) { | else if(command.equals(CloseCmd.ACTION_NAME)) { | ||||
new CloseCmd(_context).execute(); | new CloseCmd(_context).execute(); | ||||
} | } | ||||
@@ -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 | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
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" | |||||
}; | |||||
} |
@@ -52,7 +52,7 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.tools.ant.gui; | package org.apache.tools.ant.gui; | ||||
import org.apache.tools.ant.gui.util.WindowUtils; | |||||
import javax.swing.*; | import javax.swing.*; | ||||
import java.awt.BorderLayout; | import java.awt.BorderLayout; | ||||
@@ -82,10 +82,19 @@ public class Main { | |||||
f.getContentPane().add(BorderLayout.NORTH, | f.getContentPane().add(BorderLayout.NORTH, | ||||
context.getActions().createToolBar()); | 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.pack(); | ||||
f.setVisible(true); | f.setVisible(true); | ||||
// Hack around linux window placement annoyance. | // Hack around linux window placement annoyance. | ||||
f.setLocation(100, 100); | |||||
WindowUtils.centerWindow(f); | |||||
} | } | ||||
catch(Exception ex) { | catch(Exception ex) { | ||||
@@ -85,7 +85,7 @@ class ProjectNavigator extends AntEditor { | |||||
JScrollPane scroller = new JScrollPane(_tree); | JScrollPane scroller = new JScrollPane(_tree); | ||||
add(scroller); | add(scroller); | ||||
setPreferredSize(new Dimension(100, 100)); | |||||
setPreferredSize(new Dimension(150, 100)); | |||||
} | } | ||||
@@ -54,10 +54,15 @@ | |||||
package org.apache.tools.ant.gui; | package org.apache.tools.ant.gui; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.ProjectHelper; | 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.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import javax.swing.tree.TreeModel; | import javax.swing.tree.TreeModel; | ||||
import javax.swing.text.Document; | import javax.swing.text.Document; | ||||
import java.util.Enumeration; | |||||
/** | /** | ||||
* This class provides the gateway interface to the data model for | * This class provides the gateway interface to the data model for | ||||
@@ -70,44 +75,59 @@ import javax.swing.text.Document; | |||||
*/ | */ | ||||
public class ProjectProxy { | public class ProjectProxy { | ||||
/** Application context */ | |||||
private AppContext _context = null; | |||||
/** The file where the project was last saved. */ | /** The file where the project was last saved. */ | ||||
private File _file = null; | private File _file = null; | ||||
/** The real Ant Project instance. */ | /** The real Ant Project instance. */ | ||||
private Project _project = null; | 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. | * File loading ctor. | ||||
* | * | ||||
* @param file File containing build file to load. | * @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; | _file = file; | ||||
_context = context; | |||||
loadProject(); | loadProject(); | ||||
} | } | ||||
/** | |||||
* Load the project from the build file. | |||||
* | |||||
*/ | |||||
private void loadProject() throws IOException { | private void loadProject() throws IOException { | ||||
_project = new Project(); | _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; | 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; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | } |
@@ -55,6 +55,9 @@ package org.apache.tools.ant.gui; | |||||
import java.util.*; | import java.util.*; | ||||
import java.text.MessageFormat; | 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. | * Singleton class for accessing various resources by the application. | ||||
@@ -143,4 +146,22 @@ public class ResourceManager { | |||||
return MessageFormat.format(format, arguments); | 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; | |||||
} | |||||
} | } |
@@ -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 | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
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(); | |||||
} | |||||
} | |||||
} |
@@ -95,7 +95,7 @@ public class LoadFileCmd implements Command { | |||||
} | } | ||||
else { | else { | ||||
try { | try { | ||||
ProjectProxy project = new ProjectProxy(_file); | |||||
ProjectProxy project = new ProjectProxy(_context, _file); | |||||
_context.setProject(project); | _context.setProject(project); | ||||
} | } | ||||
catch(IOException ex) { | catch(IOException ex) { | ||||
@@ -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 | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
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(); | |||||
} | |||||
} |
@@ -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 | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
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 }; | |||||
} |
@@ -54,7 +54,7 @@ | |||||
package org.apache.tools.ant.gui.event; | package org.apache.tools.ant.gui.event; | ||||
import java.util.*; | import java.util.*; | ||||
import javax.swing.SwingUtilities; | |||||
/** | /** | ||||
* An event "bus" providing a centralized place for posting | * An event "bus" providing a centralized place for posting | ||||
* and recieving generic application events. To receive events a class must | * and recieving generic application events. To receive events a class must | ||||
@@ -142,29 +142,55 @@ public class EventBus { | |||||
* @param event Event to post. | * @param event Event to post. | ||||
*/ | */ | ||||
public void postEvent(EventObject event) { | 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; | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -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.name=New | ||||
new.shortDescription=Create a new project | new.shortDescription=Create a new project | ||||
new.parentMenuName=File | new.parentMenuName=File | ||||
new.icon=new.gif | new.icon=new.gif | ||||
new.accelerator=control N | |||||
open.name=Open | open.name=Open | ||||
open.shortDescription=Open an existing project | open.shortDescription=Open an existing project | ||||
open.parentMenuName=File | open.parentMenuName=File | ||||
open.icon=open.gif | open.icon=open.gif | ||||
open.accelerator=control O | |||||
save.name=Save | save.name=Save | ||||
save.shortDescription=Save the current project | save.shortDescription=Save the current project | ||||
save.parentMenuName=File | save.parentMenuName=File | ||||
save.icon=save.gif | save.icon=save.gif | ||||
save.accelerator=control S | |||||
close.name=Close | close.name=Close | ||||
close.shortDescription=Close the current project | close.shortDescription=Close the current project | ||||
@@ -30,3 +33,17 @@ about.name=About | |||||
about.shortDescription=About this application | about.shortDescription=About this application | ||||
about.parentMenuName=Help | about.parentMenuName=Help | ||||
about.separator=true; | 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 | |||||
@@ -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.Antidote.left.editors=\ | ||||
org.apache.tools.ant.gui.ProjectNavigator | 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. | # Set specific class properties. | ||||
org.apache.tools.ant.gui.SourceEditor.name=Source | org.apache.tools.ant.gui.SourceEditor.name=Source | ||||
org.apache.tools.ant.gui.PropertyEditor.name=Properties | 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 | org.apache.tools.ant.gui.XMLFileFilter.description=XML Files | ||||
@@ -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 parent Window to base centering on. | ||||
* @param child Window to center. | * @param child Window to center. | ||||
@@ -94,4 +94,15 @@ public class WindowUtils { | |||||
bounds.y + (bounds.height - size.height)/2); | 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); | |||||
} | |||||
} | } |