Groovers,
I wanted to hack up a way where i could type some groovy code
in a text box and have it compute math functions on arrays of numbers.
Is the code below the best way to do this?
The groovy tutorial is a bit "thin" (to use yawmarks words) in explaining
the ways to get this done.
For those new to Groovy, catch up quickly:
Download
http://groovy.codehaus.org/Download
Install
http://groovy.codehaus.org/Installing+Groovy
Compile + Run Code Below w/ Classpath
-classpath .;"C:\...\groovy-1.0\embeddable\groovy-all-1.0.jar"
Embedding + BSF Tutorial
http://groovy.codehaus.org/Embedding+Groovy
http://groovy.codehaus.org/Bean+Scripting+Framework
About the code:
I dont know how to create and return double arrays in groovy so
i just return a double to test the code : /
For streamlining its possible to wrap the users code in the Class +
Method like:
String code = "public class X implements... " + code + " } \n } ";
but i left that in for clarity.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import groovy.lang.*;
public class GroovyTester implements ActionListener{
public static void main(String[] args){
new GroovyTester();
}
public GroovyTester(){
guiSetup();
}
public void guiSetup(){
numberField = new JTextField("1.0");
numberField.addActionListener(this);
groovyBox = new JTextArea(CODE);
scrollPane = new JScrollPane(groovyBox);
answerField = new JTextField();
contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(2, 1));
contentPane.add(numberField, BorderLayout.NORTH);
contentPane.add(scrollPane, BorderLayout.CENTER);
contentPane.add(answerField, BorderLayout.SOUTH);
window = new JFrame();
window.setContentPane(contentPane);
window.setSize(400, 400);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == numberField){
processFunction();
}
}
public void processFunction(){
Computation c = loadGroovyFunction();
if(c != null){
double[] values = inputArray();
if(values.length > 0){
double answer = c.compute(values);
answerField.setText("answer: " + answer);
} else {
answerField.setText("no input");
}
} else {
answerField.setText("error");
}
}
public double[] inputArray(){
String[] input = numberField.getText().split("\\s*[, ]\\s*");
for(int i = 0; i < input.length; i++){
System.out.println("Input #" + (i+1) + ": '" + input[i] + "'");
}
double[] values = new double[input.length];
for(int i = 0; i < input.length; i++){
try{
values[i] = Double.parseDouble(input);
} catch(Exception e){
values[i] = 0;
}
}
return values;
}
public Computation loadGroovyFunction(){
try{
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader gcl = new GroovyClassLoader(parent);
String groovyCode = groovyBox.getText();
Class clazz = gcl.parseClass(groovyCode);
Object object = clazz.newInstance();
return (Computation)object;
} catch(Exception e){
e.printStackTrace();
return null;
}
}
public static interface Computation{
public double compute(double[] values);
}
JFrame window;
JPanel contentPane;
JTextField numberField;
JScrollPane scrollPane;
JTextArea groovyBox;
JTextField answerField;
public static final String CODE =
"\npublic class X implements GroovyTester.Computation{\n"+
"\n" +
"public double compute(double[] values){\n" +
"return values[0] * 2;\n" +
"}\n" +
"\n" +
"}\n";
}