Ant InputHandler GUI Using Groovy

Intro

With Apache Ant you can get input from the user using the “input” task. When you run Ant in a console window, the DefaultInputHandler is used. This handler just uses the console’s error and input streams.

When you run Ant in a graphical IDE, a Graphical User Interface based input handler may be used. This handler will use the graphics toolkit (on Eclipse that would be SWT) to pop up dialog boxes.


GUI in console?

Can you use GUI input dialogs when running in a command shell? Yes, and it is very easy. (Of, this is true if a gui environment is available to Java runtime, etc.).

First you create an InputHandler subclass that will be used with the Ant command option “-inputhandler class name”. If you use Ant 1.8* you can use a nested “inputputhandler” task in the “input” task within the build script.

Probably a much better approach is to just create a new custom Ant task, “ginput” for this, or even use a macrodef or scriptdef that uses Groovy inline or from a script file.

Another alternative is to use a browser interface for the Ant input. See “Java’s HTTP Server for browser-based Groovy app” for an example of using an embedded server to invoke browser UI.

Groovy?
Why Groovy for this? Just to be able to use the SwingBuilder that potentially could make the Gui creation much simpler. One can envision a full blown form being used for cases where Ant is used outside its traditional use-case.

GUI InputHandler subclass

Below in listing 1, there is an example Groovy source: AntGuiInputHandler.groovy

Much harder is actually getting Ant to use this handler.

Build file

First lets create an Ant build file that will get some input:

<project name="AntGui" default="all" basedir=".">
<target name="all">

    <input message="What is your name?"
       addproperty="got.response"/>		
    <echo>${got.response}>/echo>		
</target>

</project>

Compiling
Now, compile the Groovy source as follows:

groovyc AntGuiInputHandler.groovy

Running
There are many ways to actually run the Ant build. The simplest but not the best way is to set up your CLASSPATH and then run Ant as usual, for example:

C:\temp\AntGui&amp;gt;set classpath=.;\java\groovyembeddablegroovy-all-1.8.1.jar

C:\temp\AntGui&amp;gt;ant -inputhandler AntGuiInputHandler
Buildfile: C:tempAntGuibuild.xml

all:
[input] prompt=What is your name?
[input] Josef
[echo] Josef from Groovy InputHandler

BUILD SUCCESSFUL
Total time: 11 seconds

The resulting input dialog is:

Ant GUI InputHandler prompt

Listing 1
Note: I currently have no Swing mojo, so this is just reuse of code snippets. BTW, SwingBuilder could use more docs or examples.

import java.awt.event.WindowEvent
import javax.swing.ActionPropertyChangeListener;

import groovy.swing.SwingBuilder;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.input.InputHandler;
import org.apache.tools.ant.input.InputRequest;
import org.apache.tools.ant.input.MultipleChoiceInputRequest;

import javax.swing.*

/**
 * @author jbetancourt
 *
 */
class AntGuiInputHandler implements InputHandler {

	/* (non-Javadoc)
	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
	 */
	@Override
	public void handleInput(InputRequest request) throws BuildException {
		def response = ''
		println "prompt=${request.getPrompt()}"
		
		if(request instanceof org.apache.tools.ant.input.MultipleChoiceInputRequest){
			response = 	getMultipleChoiceInput(request)
		}else{
			response = getTextInput(request)
		}
		
		println response
		request.setInput("${response} from Groovy InputHandler");
	}
	
	String getTextInput(InputRequest request){
		//def swingBuilder = new SwingBuilder()
		def response = ''
                // how to do this with the builder?
		response = JOptionPane.showInputDialog(
                   null, 'Project Name','Enter name', JOptionPane.OK_OPTION)

		return response	
		
	}
	
	
	String getMultipleChoiceInput(InputRequest request){
		def swingBuilder = new SwingBuilder()
		def req = (MultipleChoiceInputRequest)request;
		
		def choices = req.getChoices()
		def defaultValue = req.getDefaultValue()		
		def prompt = request.getPrompt()
		
	    def pane = swingBuilder.optionPane(
                  message:prompt, 
                  selectionValues:choices as Object[], 
                  optionType:JOptionPane.CLOSED_OPTION)
		def dialog = pane.createDialog(null, 'dialog')
		dialog.show()
		
		def response = pane.getInputValue()
		
		println "input: ${response}"		
		
		return response
	}
}

Pretty groovy use of Groovy!

Previously posted at: “Ant InputHandler GUI Using Groovy

Updates
2011-08-16T2159: Just stumbled upon the AntForm project. If I knew about it, I wouldn’t even have tried doing the above. Oh well.

Similar Posts:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Leave a Reply

Your email address will not be published. Required fields are marked *