[image] About me

Java.net profile

View Andres Almiray's profile on LinkedIn

ohloh profile

View aalmiray's profile on slideshare

Twitter Feed FriendFeed

CodeCamp at FootHill College. Click Here for Details and Registration

Currently reading:

Programming Groovy - V.Subramaniam Beginning Java SE 6 Platform - J.Friesen The Story of the Irish Race - S.MacManus NFJS Anthology 2007 - N.Ford et al Groovy Recipes - S.Davis

[image] Recent Entries

[image] Tags

[image] Subscribe

Subscribe in Rojo

Add to Netvibes
Add to Google

[image] Projects

[image] I Recommend

GetJava Download Button

No Fluff Just Stuff

[image] Blogs I read

[image] Search

[image] Categories

[image] Monthly

« October 2008
Sun Mon Tue Wed Thu Fri Sat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
             

[image] Badges

[image]
[image]
[image]
[image]
[image]
Add to Technorati Favorites

 

Locations of visitors to this page
More than a year ago a series of post regarding Fuse and Groovy (I, II, III) were laid out on this blog, that clearly show I didn't know what I was getting into. These days I know a bit more about Groovy and creating Swing apps with it than then :-D so it seemed like a good idea to revisit FuseDemo but this time spicing it up with Griffon.

If you look at the original code you will notice there are four components with custom painting and a Main class that serves as application builder and entry point. The first iteration of this experiment will concentrate on porting the app 'as is', with no major tweaks to the painting code, here are a couple of screenshots of the finished app

[image]

[image]

Ok, I couldn't resist adding a minor tweak in terms of the app's behavior. Notice that when the Black theme is the current one, the "Red Theme" button is the only one enabled, the inverse is also true when the Red theme is enabled. This is probably related to binding as we will see next. So the first thing with any Griffon app is create the application's layout, once you have Griffon installed on your system type

griffon create-app FuseDemo

Next step would be adding the required libraries (fuse-core, fuse-swing) to the application's lib directory (you can get them from Fuse's project site), also all sources and resources from the original demo except the MainFrame class. Sources should be place under src/swing, resources should be placed under griffon-app/resources/swing. We are ready to write the view

Alright, so we have two actions that trigger the theme change, whose enabled property is bound to the current themeId value (handled by the model). The layout mirrors the one found in MainFrame. Now let's look at the controller code, which is the one that handles the theme change using a SwingHive

Changing a theme requires a naming convention (at least for this particular example, not just because of Fuse or Griffon themselves) so that the exact location of a ui theme is not exposed. Remember that the value of themeId is set on the actions, using handy constants available on the model class, which is the next source

Is that all? pretty much, but there is a missing piece of the puzzle, we have to instruct the SwingHive to inject the resources into our components, that is why the controller has a injectResources method. But where should we make the call to inject those resources? thankfully Griffon defines a set of lifecycle scripts that are called in an specific order: Intialize, Startup, Ready, Stop and Shutdown; the one we need is Startup (found in griffon-app/lifecycle/Startup.groovy) as it is called after the view has been built but before the app has finished bootstraping itself, it is just a matter of adding 3 lines of code

Don't forget that if you want a nice looking app (with native L&F where available) and MacOSX friendly menubars you should add the following to griffon-app/lifecycle/Initialize.groovy

And that is the whole code, you should have a working example of Fuse enabled Griffon application, you can run it by issuing the command

griffon run-app

You may probable be wondering if we could do better, sure! what about automatically registering the components that require Fuse injected resources? or tweaking the custom paint code with a groovier way (hint: GraphicsBuilder)? those questions will be answered in future posts, stay tuned! :-D In the meantime enjoy creating applications with Griffon

Keep on Groovying!

fuse griffon groovy swing
I've been itching to write about Groovy's solutions to the hidden threading rule, now that Griffon is finally out I can show you how easy it is to get it done.

Start by downloading Griffon and install it, no hurries, take your time, I'll wait... done?! ok let's continue ;) once you have setup your environment the next step is creating a sample application by issuing the command

griffon create-app workerTest

That should give you the barebones, if you don't believe me then issue the following command to run the app

griffon run-app

Alright! let's continue, on the threading rule post it was mentioned that SwingBuilder exposes two handy methods for invoking code inside/outside of the EventDispatch Thread, named doLater and doOutside. Now remember that somewhere before Jdk6 was released the Swinglabs project added another handy way to deal with threading in Swing: SwingWorker. It turned out to be a very good idea, so good that it was later added to the JSL, so now you have an option if your are running either jdk5 (Swinglab's SwingWorker) or jdk6 (Jdk6 SwingWorker), problem is that those classes are located in different packages.

Oh boy, can-t we have a simplified version? sure we can! enter the withWorker() node from SwingXBuilder. This node is smart enough to use either class depending on your runtime JVM, so you have to concentrate only on getting things done. Back to Griffon, one of its key components (the CompositeBuilder) allows you to mix&match builders based on FactoryBuilderSupport, FBS in turn has a pretty cool, convention driven approach to group together a set of related nodes, for example the threading ones. By grouping nodes together FBS is also able to 'lend' those nodes to external classes, like Griffon's controllers. This means that you can call doLater for instance from your controller as it it were a method defined on the controller itself, wicked!

Let's add withWorker to your sample controller, shall we? open up griffon-app/conf/Builder.config in your favorite editor and type
It looks like magic isn't it? if you want to find out more about the available groups search for all register* methods in the builders for the time being (docs coming soon!). Where to now? let's fill up the model (griffon-app/models/WorkerTestModel.groovy) and view (griffon-app/views/WorkerTestView.groovy) next

@Bindable makes it so easy to write observable beans. On to the view

Hopefully the code is self explanatory, an action is created inside the actions group, which is a placeholder for all actions, that way an action is not added accidentally to a component. Notice that the action's enabled property is bound to the model, so it is the label's text property. We will be updating those properties inside the controller (griffon-app/controllers/WorkerTestController.groovy) , which is the one shown next

We have reached the culmination point, withworker() will create an instance of SwingWorker suitable for your runtime JVM. It accepts a DSL-like definition of its tasks and what it should do once it finishes them. Additional info on those closures
onInit - behaves like a constructor, it is called once just before the worker starts. work - the body of the task. you may call publish() at any point to send updates to the UI onUpdate - handles the data made available by publish(), its parameter is of type List onDone - handles the termination of the task
A SwingWorker constructed this way does not start its job unless you specify its start property as true. Well that's it, really. By having controllers borrow nodes/methods/properties from a CompositeBuilder you can write Swing applications fluently and as is this case, handle Swing threading in an easier way (I'll say intuitive too). You can test this application by issuing the command

griffon run-app

Woops almost forgot, you will need SwingXBuilder 0.1.6-SNAPSHOT and its dependencies, place them on workerTest/lib or else you'll get a nasty ClassNotFoundException (and we don't want that ;-) )

Keep on Groovying!

griffon groovy swing
Some of you deciphered the cryptic message left a few days ago, today I'm glad to pass along the news that the first release of Griffon is finally available. So what is Griffon? to put it bluntly the goal of the Griffon project is to be to Swing application development what Grails is to web application development. A bold goal but surely attainable :-D

As Danno notes, the foundations of Griffon were laid over a year ago, at the time when SwingBuilder made the switch from Java source to Groovy source. A bit later after that FactoryBuilderSupport was born, and its thanks to FBS' extensibility power that another piece of the puzzle was created: the CompositeBuilder. This key component of the Griffon project allows you to mix&match any FBS based builder (like SwingXBuilder, JideBuilder and GraphicsBuilder) into a single cohesive unit, or a modularized one as it supports a variation of namespaces, which means that a set of factories may have a prefix to distinguish them from other similarly named factories contributed by another builder.

Enough on the background story, are you still reading this?! go download Griffon and take it for a spin! :-D

[Download|Install Guide|Quick Start Guide]

Let Griffon take your Swing application development to new heights ;-)

Keep on Groovying!

PS: use jdk6 for better results (like speedy Swing, Nimbus L&F and other goodies available only in j6u10)

announcement griffon groovy swing
Two months from now the 2008 edition of Silicon Valley Code Camp will take place Saturday and Sunday, November 8th and 9th at Foothill College. Currently there are 69 sessions and 394 attendees registered. Remember this is a free attendance event, so if you are in the area please consider dropping by.

This year's installment has a more colorful note in terms of languages, as you can find talks on Groovy, Scala, JavaScript, Ruby and Python, not just Java/.Net, Long live the Polyglot Programming revolution! :D

codecamp groovy java svcc2008
Griffon

... to a desktop near you

griffon groovy
Looks like the previous SwingBuilder binding entry stroke a chord on Greg Bollinger. Greg writes at dzone links:
That's pretty cool but horribly impractical. What I'd like to see is how binding would work to a true domain object vs some "example only" worthy ObservableMap that no one really uses to store form data in.
What everyone needs is the ability to easily bind forms to POJO's and back. Just like all the wonderful web frameworks can do. Let's see those kinds of examples if you really want to impress.

Horribly impractical... true, nobody in their sound mind should use an observable-map-as-POGO-replacement instead of regular domain objects when it comes to production code, for prototyping and testing I would think otherwise. An example with true domain objects you say? you got it! As I said ObservableMap works like an observable POGO, it simplifies testing as you do not need to declare a new class for your observable POGO, you just use the behavior, after all Groovy has blurred the line between Maps and POGOs. So what does it take to make a POGO an observable one? following the JavaBean conventions it means
Each observable property must fire PropertyChangeEvent when its value changes. The bean should expose register/unregister methods for PropertyChangeListener. The observable behavior (firing events) may be implemented with PropertyChangeSupport.
Simple rules really, but they can turn your domain object into a jungle of code. Groovy already provides simplified POGOs, just declare a field and its type without an access modifier and you got yourself a property. Groovy 1.6-beta-1+ goes one step further with @Bindable and ASTTransformations. As @shemnon shows here, it is quite easy to build an observable POGO, so lets follow his code samples

That's it. Import the annotation, annotate the pertinent properties, bind to your hearts content. But wait there is more, it turns out there is a way to streamline the binding form textField.text to textModel.text. SwingBuilder includes a factory for building any node/bean you'd like, aptly named bean. If we use that factory and set textModel as it value then we can also use the short binding syntax

Much better. You may be wondering, what happened to the trigger code (PropertyChangeListener)? well that remains the same, it doesn't matter if you have an ObservableMap instance of an observable POGO, there is no short syntax for triggers for the time being.

Keep on Groovying!

binding groovy swing swingbuilder
Those of you that follow @shemnon's blog will surely know that he has revamped how binding is supported in the development versions of Groovy 1.6.x (here, here and here). Impatiently as ever, I created my own distro of groovy 1.6-beta-2-SNAPSHOT and gave it a try, quite fitting with the latest JavaFx Script experiments.

One of the appealing features of JavaFx Script is that it has binding baked right into the language, it also sports the notion of triggers. You can attach any function on a trigger, whenever the trigger receives a binding update event the function will be called. This is akin to PropertyChangeListener and PropertyChangeEvent, only you don't see those classes in the open with JavaFx. So here goes, three simple binding/triggers examples on JavaFx Script and Groovy. The examples are not comprehensive, binding in both languages can cover a broader spectrum. It is important to note that binding in Groovy is provided by a set of APIs (SwingBuilder and the bind factory) not by the language itself.

The first snippet exemplifies binding between two components, the label's text will be updated every time text is written on the textField, first comes the JavaFx Script version
And now its Groovy counterpart

Maybe there is another way to setup the binding between the label and the textfield on JavaFx Script, but you can't define variables while building the content unless you do it inside a function, this means that those components are not built close to the place where they are inserted into the UI hierarchy. Clearly that is not a problem with the Groovy version. The next snippet introduces one level of indirection, a textModel. Now the label will bind to a third object that holds a text attribute. A button is also added to 'trigger' the update
The code is pretty much self explanatory, I would say the same holds true for the Groovy version ObservableMap is an utility class that fires up PropertyChangeEvents every time a property is added, updated and/or removed from it, in contrast observable beans usually fire events when a property is updated only (more options for you!). I can hear someone at the back saying 'but JavaFx Script does have triggers, why don't you use them instead?' certainly I will. So let's remove the button and bind the label, textField and textModel, adding a console printout just to show that the model is being updated as expected, and it in turn updates the label It only took two binding calls and one trigger, sweet. What about the Groovy version? well, we don't have triggers (yet) that make the code short but it is certainly doable Notice that a regular PropertyChangeListener has been registered with the ObservableMap, this is how triggers are implemente in Java/Groovy. Binding the textField's text to the textModel's text property is also a bit more verbose than before. As a matter of fact that syntax used to be the previous one, so you can see that binding has been improved, just a bit but good enough :-D I think it is possible to cook up a trigger dsl to reduce the amount of code required to create triggers in Groovy, don't you think? we have metaprogramming on our side after all.

Keep on Groovying!

binding groovy javafx jfx swingbuilder
Second part of the Java,Groovy,JavaFx series. The following table details the language features introduced in JSE 5 and how they may or may not be supported by Groovy and JavaFx.

Feature Java Groovy JavaFx
Varargs class Person {
   public void greet(Object... args) {
     // access the "args" array here
   }
}

note: works on JDK5+
class Person {
   public void greet(Object... args) {
     // access the "args" array here
   }
}

note: works on JDK5+

class Person {
   public void greet(Object[] args) {
     // access the "args" array here
   }
}

note: any array type will do only if it is the last parameter defined. Works on JDK4+
Not supported
Annotations @NotNull String field;
@NotNull String field;


note: annotations work in the same way as in Java, with the caveat that they can not be defined in Groovy yet, requires JDJ5+
Not Supported
Generics class MyComparable implements Comparable<MyClass> { }

Map<String,Integer> map = new HashMap<String,Integer>();
class MyComparable implements Comparable<MyClass> { }

Map<String,Integer> map = new HashMap<String,Integer>();


note: generics work in the same way as in Java, requires JDK5+
Not Supported
Static imports import static java.awt.Color.RED;
import static java.awt.Color.RED;


note: static imports work in the same way as in Java, requires JDK5+
Not Supported
Typesafe Enums enum Lang {
  JAVA, GROOVY, JAVAFX;
}
enum Lang {
  JAVA, GROOVY, JAVAFX;
}

note: enums work in the same way as in Java, plus they receive some extra behavior from the GDK
Enum definition is not supported, but you can access them as any regular Java class, requires JDK5+
Enhanced for-loop for( Type variableName : Iterable )
  // statements }
for( Type variableName : Iterable )
  // statements
}

Groovy has its own enhanced for loop syntax too

for( Type variableName in Iterable )
  // statements
}

note: a type must be defined in the first version (requires JDK5+), type is optional in the second version
JavaFx has its own enhanced for loop syntax, can chain sequences

for (album in albums, track in album.tracks) {
   if (album.title == track)
     // do x
   else
     // do y
}

it also accepts filters (with a where clause)
Autoboxing/Unboxing int i = Integer.valueOf(10);
Integer j = 42;
Everything in Groovy is an object. Still it will perform autoboxing/unboxing when calling Java code that requires either a primitive or a wrapper value. JavaFx does not have primitive types per se, rather they are called basic types: String, Boolean, Number, Integer, Duration (Basic Types table)


Clearly Groovy has a better integration with Java the language than JavaFx does, but I must remind you that is by design of both languages. Developers that find themselves comfortable enough with Java5 features should feel right at home should they decide to pick Groovy, those who choose JavaFx will find themselves relearning new ways to do what they are used to, which is not really a bad thing per se, just beware of the context switching when programming in 2 or 3 languages that sport considerable differences feature wise and syntax wise.

groovy java javafx jfx
A couple of days ago there was an announcement on this blog about jSilhouette's 0.1 release, followed by a comparison between the geom, scene and jfx demos (regular Java, Project SceneGraph and JavaFx Script each).

Things have changed a bit. Jacek Furmankiewicz brought to my attention that Project SceneGraph is licensed under GPLv2 (no classpath extension) which means both jsilhouette-scene and jsilhouette-jfx must use the same licensing scheme. But jsilhouette-geom does not, in fact it has been re-licensed to ASL 2.0, this means that starting with the next release commercial use of jsilhouette-geom is no longer a problem. The commercial usefulness of the remaining modules lies in Sun's will to re-license Project SceneGraph to GPLv2 with classpath extension.

Some other updates
Donut shape has been added to all modules. Donuts may be circular or polygonal. Default values have been added to some attributes in the jfx module, alleviating the pain of setting each attribute. Groovy demo (GraphicsBuilder based) available!
Here is an screenshot on the latest demo app

[image]

Nice Nimbus look &feel, you may be thinking that this is the new version of the jfx demo, but it is not! this is the Groovy version (ShapesDemoGroovy.groovy) ;-) , the green color is darker in jfx, remember? let's revisit the stats, shall we?

  geom scene jfx groovy
LoC 369 505 619 369
Tokens 1486 1855 2644 2194
Source file size (bytes) 16412 21000 20626 15311
Compiled code size (bytes) 104K 60K 76K 92K


The Groovy version beats the JavaFx Script version in almost all categories (the source file is even shorter than the Java2D version) but these numbers do not reflect how small the code can be in each version. For example I discovered that the jfx version has some commas (,) between attribute declaration (which bump the char and file size), I was surprisewd to find out JavaFx Script was happy with them as not even a slight warning is given by the compiler, nice!; the Groovy version harnesses the power of native syntax for Lists and Maps to reduce variable declaration; defaults values are not really used that much in all versions.

I also mentioned previously that making the second and third demo was quicker once the first one was done, in this case it was no different. The jfx version was copied almost verbatim, added some Groovy sugar here and there (even had to add a MetaClass hack due to how SwingBuilder handles look&feel in the 1.5.6 version (the new one is slicker :-D thank @shemnon for that)). Quick comparison between how the jfx and groovy versions initialize the frame, first the jfx one

Where each draw* function is of the form

Here I'd like to take the opportunity to mention that the function signature must have Void as its return type otherwise a compilation error will be thrown. If the return type is not specified then it will be the same type of the last evaluated expression, in this case Node[], SwingButton expects its action function to return Void. I'm sure a tool (like NetBeans' jfx plugin) would have drawn a red underline/popped an error/whatever under the offending code before attempting a full compile on the code by myself, but I went with the "manual" way: Vim + command line compiler, so there, had to be more careful :-P

Here is the Groovy version

Where shapes is a Map initialized like

The Groovy version requires some 'plumbing'
Fix SwingBuilder.lookAndFeel to accept a List of L&F identifiers (available in Groovy 1.6.x). Set the preferred L&F. Tell the frame where it should be located by default (locationRelativeTo: null)
The native syntax for Lists and Maps comes in our aid here. Iterating each entry (String,GraphicsOperation) it is a matter of hooking up the proper values on the button's text and action. Notice that each time a button is clicked a new GraphicsOperation is created (a group) that has a 'global' property applied to all its children (borderColor: 'black') and antialias is turned on. GraphicsPanel is smart enough to know when it should repaint itself (similar to JSGPanel and Canvas). Of course some would say you may iterate over a sequence in the jfx version in order to build the buttons in a loop, sure you can. You could also create a java.util.Map that holds each label and related function, but the code is not as concise as the Groovy one. Assuming hypothetical classes javafx.util.LinkedHashMap and javafx.util.MapEntry
Yup, hypothetical is more like it (my code that is, still have to learn more about JavaFx Script) but you get the idea. Back to jSilhouette, I'd like to have proper javadocs/javafxdocs in place before releasing the next version, so it will take a couple of days more.

Feedback is always appreciated.

graphics graphicsbuilder groovy java java2d javafx jfx jsilhouette
While experimenting with JavaFx Script I encountered a few gotchas switching from Java/Groovy, mostly related to my preconceptions of the language itself. Even though it is JVM language built with Java, being an specialized language for declarative UI building doesn't mean it will follow Java's steps all the way, nor other modern features brought into the JVM by Groovy. The following table summarizes many of the orthogonal features of the three languages, it is not a complete reference for any of them. The "official draft" of the JavaFXâ„¢ Script Programming Language Reference was used to learn more about the it. Disclaimer: I know Groovy better than JavaFx Script, if someone spots a mistake please let me know :-)

Update: fixed the embarrassing label (s/Scala/JavaFx/)

Feature Java Groovy JavaFx
Type System Static with few dynamic checks inserted as needed. Dynamic, optional static types. Static, with type inference. (chapter 4)
Comments /*
 * multiline comment
 */

/**
 * javadoc comment
 */

// single line comment
/*
 * multiline comment
 */

/**
 * groovydoc comment
 */

// single line comment
/*
 * multiline comment
 */

/**
 * javafxdoc comment
 */

// single line comment
End of statement ; a new line will do most in most cases. Use ; when ambiguous ;
Control Statements - if if (condition) {
   // statements
}

if (condition) {
   // statements
} else if (condition) {
   // statements
} else {
   // statements
}
if (condition) {
   // statements
}

if (condition) {
   // statements
} else if (condition) {
   // statements
} else {
   // statements
}

note: if may return a value in a future version of Groovy.
if (condition) {
   // expression
}

if (condition) {
   // expression
} else if (condition) {
   // expression
} else {
   // expression
}

note: if is an expression, not an statement, so it returns a value.
Control Statements - ternary operator (condition) ? true_statement : false_statement (condition) ? true_statement : false_statement
Elvis operator, a refinement over the ternary operator. If the condition expression is true then said condition expression will be the true_statement
condition ?: false_statement
if (condition) true_expression else false_expression
Control Statements - while while (condition) {
   // statements
}

do {
   // statements
} while (condition);
while (condition) {
   // statements
}
while (condition) {
   // expressions
}

note: curly braces are always required around the body
Control Statements - for for (init; condition; increment ) {
   // statements
}

for (Type t: iterable ) {
   // statements
}
for (init; condition; increment ) {
   // statements
}

for (Type t: iterable ) {
   // statements
}

for ( variable in iterable ) {
   // statements
}

Every single object in Groovy is iterable, default impl returns the object itself
for ( e in sequence ) {
   // statements
}

a for loop may accept related sequences

for (album in albums, track in album.tracks) {
   if (album.title == track)
     // do x
   else
     // do y
}

they also accept filters (with a where clause)
Control Statements - switch switch (target) {
  case constant_expr:
    // statements
  [break]
    ...
  default:
    // statements
}
switch (target) {
  case constant_expr:
    // statements
  [break]
    ...
  default:
    // statements
}

* target may be any object
* case statements may use same expressions as in Java plus Strings, Matchers, regular expression, closures, ranges, any object that supports isCase()
Not supported
Control Statements - conditions conditions must be evaluated in a boolean context conditions may be evaluated in many contexts, this is known as the Groovy Truth, some rules follow (this is not a complete set, please refer to Groovy in Action or Groovy's site) evaluates to false
false null references empty Map empty List Matcher with no matches
same as Java
String Literals "Hello Java" "Hello Groovy" // double quote

'Hello Groovy' // single quoute

"""Hello
Groovy""" // multiline

// variable interpolation
name = "Groovy"
"Hello ${name}" // evals to Hello Groovy
"Hello JavaFx" // double quote

'Hello JavaFx' // single quoute

"Hello
JavaFx" // multiline (both single and double quote work)

// variable interpolation
var name = "JavaFx"
"Hello {name}" // evals to Hello JavaFx
Class declaration class HelloWorld {
  // fields
  // methods
}
class HelloWorld {
  // fields
  // methods
}
class HelloWorld {
  // attributes
  // functions
}
Instance Fields [access_modifier] Type name

where access_modifier is any of
public protected private empty - means package protected [default access]
[access_modifier] Type name

where access_modifier is any of
public [default access] protected private
If no access modifier is provided then the field would be promoted to a property. Properties have their get/set methods autogenerated in bytecode which means that the following Groovy class

class Person {
  String name
}

Is equivalent to the following Java class

public class Person {
  private String name;

  public void setName( String name )
  { this.name = name; }

  public String getName()
  { return name; }
}

[access_modifier] attribute name [:Type]

where access_modifier is any of
empty - [default access] ? public protected private

Haven't seen access modifiers in blog examples, assuming they work the same as in Java
Class Fields (static) [access_modifier] static Type name

where access_modifier is any of
public protected private empty - means package protected [default access]
[access_modifier] static Type name

where access_modifier is any of
public protected private
[access_modifier] static attribute name [:Type]

where access_modifier is any of
empty - [default access] ? public protected private
note: Type may be optional due to type inference.
Global Variables Not supported. Every field/constant must belong to a class Supported only in scripts, otherwise follows Java rules Not supported. Every field/constant must belong to a class
Method definition class Person {
  [access_modifier] Type name() {
    // statements
  }
}

where access_modifier is any of
public protected private empty - means package protected [default access]
class Person {
  [access_modifier] Type name() {
    // statements
  }
}

where access_modifier is any of
public protected private empty - same as public [default access]
class Person {
  [access_modifier] function name() [:Type] = {
    // expressions
  }
}

where access_modifier is any of
public protected private empty - same as public [default access]
The type of the function may be optional
Static Method Definition class Person {
  [access_modifier] static Type name() {
    // statements
  }
}

where access_modifier is any of
public protected private empty - same as public [default access]
class Person {
  [access_modifier] static function name() [:Type]{
    // statements
  }
}

where access_modifier is any of
public protected private empty - same as public [default access]
Follows the rules of Class Fields and Method Definition
Returning from a method return expression;
return;
Same as Java, but can ommit the return statement - in that case the last expression evaluated is returned. Same as Java, but can ommit the return statement - in that case the last expression evaluated is returned.
Null null null - Guillaume Laforge notes that "Null Object Pattern" is supported in Groovy. See also: NullObject. So, you can call null.toString() for example. null

Looks like you can call methods on a null reference, the returned value will be default value the return Type accepts.

class X { function doit() { 42 } }
var x:X = null
java.lang.System.out.println( x.doit() )
// doesn't throw an NPE
// prints 0
Arrays int[] a = new int[10];
a[0] = 3;
int[] a = new int[10]
a[0] = 3
Not supported
JavaFx has Sequences (chapter 6), they are not Arrays nor objects. They do not support nesting, in other words the following are equivalent

var s1 = [1,2,3,4,5];
var s2 = [1,2,[3,4,[5]]];
Array Literals int[] a = {0,1,2};
a[0] = 3;
int[] a = [0,1,2]
a[0] = 3
var s1 = [1,2,3,4,5];
Lists Supported by the Collections framefork (JSL), not really part of the language List list = [0,1,2]
list[0] = 'Foo'
list[10] = 11

Lists can be heterogeneous
Lists grow as needed
Same as in Java
Hash Literals Not supported. (See java.util.Map) def hash = [key:'value', 'id': 1]
hash.key = 'value2' // bean like access
hash[key] = 'value3' // hash like access
Same as in Java
Object Initialization class Person {
   [access_modifier] Person( [args] ) {
     // initialize
   }
}

class Person {
   [access_modifier] Person( [args] ) {
     // initialize
   }
}

Does not support constructors, but has object literals

class Foo { attribute bar:Number; }
var foo = Foo { bar: 1 }

You may define a function that initializes the object with an object literal
Reference to current object this this this
Varargs class Person {
   public void greet(Object...args) {
     // access the "args" array here
   }
}

note: works on JDK5+
class Person {
   public void greet(Object...args) {
     // access the "args" array here
   }
}

note: works on JDK5+

class Person {
   public void greet(Object[]args) {
     // access the "args" array here
   }
}

note: any array type will do only if it is the last parameter defined. Works on JDK4+
Not supported
Extending another class class Employee extends Person {
}

class Employee extends Person {
}

class Employee extends Person {
}


note: supports multiple inheritance if the class is not plain (chapter 2)
Referring to super class method super.foo(); super.foo() super.foo();
Inner, neste and anonymous classes // Inner class
class Book {
   class Order { }
}

// Nested class
class Node {
   static class AndNode {
   }
   static class OrNode {
   }
}

// Anonymous class
class Main {
   public Runnable getRunnable() {
     return new Runnable() {
       public void run() {
         // code
       }
     };
   }
}
Not Supported.
Annonymous inner classes may be supported in a future version.
Closures may be used in most cases instead.
Not Supported.