
I was struck by Tod's comments regarding the pleasure of creating user interfaces in javascript, due to the terse manner in which an entire hierarchy of components can be created, and how easy that makes the code to read. I agree completely - it is particularly in the creation of UIs where this really helps, and vastly reduces the amount of code written, and the ability to look at code and visualise what it is doing.
Now there is no way I can code my app client-side, for reasons I won't discuss.
But - I still want these advantages.
So I got to thinking - what about other scripting languages that work server-side, such as Groovy.
It really didn't take me long to knock up an example, and here's my groovy source (fully working):
package org.sgodden.echo3.testapp.groovy;
import nextapp.echo.app.Button;
import nextapp.echo.app.Color;
import nextapp.echo.app.Extent;
import nextapp.echo.app.Grid;
import nextapp.echo.app.Label;
public class TestGrid extends Grid {
public TestGrid() {
size = 2;
background = Color.BLUE;
width = new Extent(100, Extent.PERCENT);
components = [
new Label(
text: "Label 1"
),
new Label(
text: "Label 2"
),
new Label(
text: "Label 3"
),
new Button(
text: "Click me",
actionPerformed: {evt -> println "You clicked me: $evt"}
)
];
}
}
I did have to make some very minor modifications to the server-side framework in order to allow this:
getProperty / setProperty methods on Component had to be renamed, because they do not actually perform the work of true JavaBeans property mechanism hooks. They are used for altering the state of the local style (the component model), not the bean itself. So I renamed those to getComponentProperty / setComponentProperty. This was necessary because as groovy dynamically creates classes, it grafts on its own get/setProperty methods, to perform the work of standard JavaBeans property getting / setting. Without this change, it was not possible for Groovy classes to subclass Echo classes.setComponents(Component[]) method to Component, to allow children to be specified in one shot. The implementation of this method is trivial - it does removeAll, then just adds each component.Look at that groovy code - I think it's beautiful. The economy of lines, the ability to visualise the tree you are creating from the hierarchical code, the trivial simplicity of adding the event listener. My devs are really happy about it - creating the UI is the most common and laborious task that they do, and with this approach they find it *much* easier. Additionally, we can put Groovy into "development" mode, where it does not cache the classes it generates, meaning they don't have to restart the server as they make UI changes. We believe our productivity and quality are about to improve significantly.
Tod, I hope you can see the power and benefit of this to those of us who need to stay server-side. I think there are *lots* of people that would want to use this. Would it be possible to incorporate those changes into the trunk? I appreciate that renaming the get/setProperty methods is a breaking change for anyone who has written their own component, but it's a simple refactor. Maybe it can wait for a point release.
Otherwise I will continue to apply patches to the trunk as I keep up with it.
Excellent
I'm interested in this too. I also have little interest in writing applications client side, so server-side scripting would be a welcome feature.
Aejaks, server-side scripting in Tcl
My Aejaks project also does server-side scripting using the Tcl language. I like Groovy a lot, but I have also been using Tcl/Tk for the past 16 years, so it seemed like a natural fit. Aejaks implements a Tk-like programming model. No core Echo2 modifications are required. Aejaks includes a "console" application, allowing you to type code in and have it executed immediately, which makes for a great environment for code development and trying out snippets.
Here's the same example above, coded in Aejaks:
Pack [Grid .g -background blue -width 100%]
Pack [Label .g.l1 -text "Label 1"] [Label .g.l2 -text "Label 2"] \
[Label .g.l3 -text "Label 3"] [Button .g.click -text "Click me" -command "puts clickedme"]
Current release is 0.7, but I'm slowly getting to 1.0, which I'm adding a database access layer among other things.
http://aejaks.sf.net
Server-side JavaScript
That does looks pretty interesting sgodden. Just to stir things up a bit, my vote is for Echo3 with Javascript on the server side.
Here are some links relating to Javascript on the server side:
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://www.aptana.com/jaxer/
http://mod-gcj.sourceforge.net/rhinola.html
http://en.wikipedia.org/wiki/Helma_Object_Publisher
http://en.wikipedia.org/wiki/AppJet
Server side javascript...
Actually the best idea is to use JSR-223 (included in Java 6) which allows for pluggable scripting engines, can use the JVM's classloader and provides by default a Javascript engine.
Good point
Good point - I'm going to take a look at that. I prefer an approach that does not require modifications to echo3. The main requirement I have is that it works with javabeans conventions, so that I can do the
actionPerformed: {println "You clicked me"}bit.
Posted on the WIKI
I've posted this on the WIKI for those who are interested.