Thursday, March 20, 2008

Swinging: BGGA style.

So, to continue on with my playing w/ java closures, I now present Swing event handling: BGGA Style. Again, to compile this you will need the BGGA prototype. You can run it using your installed jre.

First, i'll show you the java version:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");

public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});

}
}

I think you get the gist of what it does. Now the BGGA version.

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;

/**
* Created: Mar 19, 2008 7:35:15 PM
*
* @author Robert O'Connor
*/
public class BGGAGui {
JFrame frame = new JFrame("BGGA Frame");
JButton button = new JButton("Press me");

public BGGAGui() {
button.addActionListener({ActionEvent evt => System.out.println("Button pressed");});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
// thanks to neil gafter!
SwingUtilities.invokeLater({ => new BGGAGui(); });

}
}

What occurs within the the addActionListener() is that when you click the button, that closure is invoked; it does the same thing the java one does (print "Button pressed" to the screen). I'm not sure how to write the invokeLater() method using BGGA to reduce its verbosity. If anybody knows, could you tell me? When the code is executed; the closure is executed and a frame is displayed; yadda yadda.

Wednesday, March 19, 2008

Concise Instance Creation Expressions (CICE)

Another proposal CICE is being put out there for Java 7. To compile the code posted here you will need the latest cice prototype. You can run it using your installed jre. Now, let's get down to the code! First I'm gonna show you the current Java version, then I'll show you the CICE version.

Java Version

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingUtilities;

/**
* Created: Mar 19, 2008 5:48:43 PM
*
* @author Robert O'Connor
*/
public class UsualJavaGui {
JFrame frame = new JFrame("Usual Java Example");
JButton button = new JButton("Press me");

public UsualJavaGui() {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed");
}
});
frame.add(button);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {
public void run() {
new UsualJavaGui();
}
});

}
}

Now, the main problem people have with java is that it's overly verbose, and they're right in that aspect. CICE aims to reduce that verbosity; by making it more concise and to the point. Now you know the basics of that implementation; it's a simple JFrame with a button that when you click it will display a message in your console.

Now the same app but with CICE:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* Created: Mar 19, 2008 5:57:45 PM
*
* @author Robert O'Connor
*/
public class CICEGui {
JFrame frame = new JFrame("CICE Gui");
JButton button = new JButton("Press me");

public CICEGui() {
button.addActionListener(ActionListener(ActionEvent e){
System.out.println("Button pressed");
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(Runnable() {
new CICEGui();
});
}
}


The above is a lot less verbose; What's missing? You'll notice the difference primarily in the main() method and the addActionListener() method call to attach the event listener to my JButton.
What's missing? That's right the
public void run() { ... }
and
public void actionPerformed(ActionEvent e) { ... }
How can this be and how do I get access to the ActionEvent reference? Well notice the following:
button.addActionListener(ActionListener(ActionEvent e) {
System.out.println("Button pressed");
});
I passed in the ActionEvent parameter to the Concise Instance Creation Expression! Using CICE, I was able to eliminate the methods. Also note, that I was able to eliminate using the word new is not needed with CICE. I was also able to state my intent cleanly, and in a lot less verbose way. How many lines were eliminated between the Java version and the CICE version?

(rob-laptop)rob@~/playground/src/main/java$ wc -l misc/UsualJavaGui.java misc/CICEGui.java
43 misc/UsualJavaGui.java
34 misc/CICEGui.java
77 total
(rob-laptop)rob@~/playground/src/main/java$

Well, that's 9 lines! Why should you have to type out the method definition if there is only ONE method in the interface or abstract class?

Groovy is kinda really groovy

public class StringTester { 
    public static void main(String[] args) {
        System.out.println(new String("foo") == "foo"); 
    }
}

Now the above code will evaluate to false. However if I changed it to:
"foo" == "foo"
it will be true. Reason: Java interns String literals. This is precisely why using == on String isn't advised. However groovy converts all == instances to .equals() so we basically get the same result as if we interned the String in java. This makes sense, since in groovy there are no primitive data types; it uses the wrapper classes from java. Integer, Double, Byte, etc. More information about the wrapper classes can be found here.
class StringTester { 
    static void main(args) {
        println new String("foo") == new String("foo") 
        println new String("foo") == "foo"
        println "foo" == "foo" 
    }
}

All three cases will evaluate to true. Now we can modify the java code so that it behaves the same way groovy did:

public class StringTester { 
    public static void main(String[] args) {
        System.out.println(new String("foo").intern() == "foo");
        System.out.println(new String("foo").intern() == new String("foo").intern()); 
    }
}

Now both will evaluate to true! Interesting thing =)

For more information about interned Strings check out this

Monday, March 17, 2008

Closures in java: Fibonacci gets some closure

So, in my previous post I promised an example; it's a simple example. In order to compile it you will need to download the BGGA prototype. You can run it using your installed jre. I'll fiddle with it some more but i wanted to put this one up, so here we go:

public class FibonacciSequenceWithClosures {
public static void main(String[] args) {
int fib = {int n => fib(n)}.invoke(Integer.parseInt(args[0]));
System.out.println(fib);
}

/**
* Helper method to recursively calculate the
* n-th number in the fibonacci seqeunce.
* @param n
* @return the n-th number
* @throws IllegalArgumentException if you pass in a negative number
*/
public static int fib(int n) {
if(n < 0) {
throw new IllegalArgumentException("Must be Postive!");
} else if(n == 1 || n==2) {
return 1;
} else {
return fib(n-1) + fib(n-2);
}
}
}



What's going on here? Let's examine it line by line. First you've got your familiar standard class definition; I declare a variable named fib, I'm sure you're asking the what the heck is
 int fib = {int n => fib(n)}.invoke(Integer.parseInt(args[0]));
Answer: it's a closure! We'll examine that line closer.
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));
First, we have the parameters that we're passing into the closures, then you see
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));
and you're probably wondering what in god's name that operator is, it's the closure operator! Now, the final piece:
int fib = { int n => fib(n)}.invoke(Integer.parseInt(args[0]));
What i'm doing here, is calling the invoke method on the closure itself, and passing in the first argument passed to the program via a command-line argument. Finally, After all this is done, I print the value returned from the closure that i stored in the variable fib and we're done. You'll get a StackOverFlowException if you pass too large a number. I could probably fix this, but this is sufficient for a simplistic example.

Closures in java

I have the tendency to come off as a real idiot sometimes; and I tend to evangelize anything that looks remotely cool; and that's true, but BGGA closures, looks interesting to me. However, after I watched Josh Bloch's The Closures Controversy [slides] a few weeks ago, I got very turned off. The latest prototype looks a little bit better. I'll fiddle with it and post the code I wrote up here. Once again, I've yet to play with it, but perhaps it's better? All I know is that the groovy-like syntax for the closure operator piques my interest.

Monday, February 18, 2008

Groovy isn't groovy when it comes to access modifiers in java

Last night, I was mucking around and noticed something odd -- Groovy ignores access modifiers of your class properties (members). What's worse is that it's known, and yet the developers and designers don't seem to wanna be bothered right now. Isn't that lovely?

Sunday, February 17, 2008

a Groovy Utility class :)

I wrote a Groovy utility class to help with setting Bindings for the GroovyShell. Additionally, I wrote a method that completely encapsulates the GroovyShell entirely.


import groovy.lang.Binding;
import groovy.lang.GroovyShell;

import org.codehaus.groovy.control.CompilationFailedException;


/**
* Created: Feb 17, 2008 3:31:44 PM
*
* @author Robert O'Connor
*/
public final class GroovyUtil {
/**
* Utility method to set up bindings.
*
* @param bind the string you're binding
* @param obj to bind to.
* @return the Binding object
*/
public static Binding bindTo(String bind, Object obj) {
Binding b = new Binding();
b.setVariable(bind, obj);
return b;
}

/**
* Utility method to get a shell with the specified binding
*
* @param bind the binding
* @return the shell instance.
*/
public static GroovyShell getShell(Binding bind) {
return new GroovyShell(bind);
}

/**
* Execute a Groovy script.
*
* @param bind binding String
* @param obj Object binding
* @param code script code.
* @throws CompilationFailedException if the compilation fails.
* @throws IllegalArgumentException if you do not specify the bindings.
*/
public static void exec(String bind, Object obj, String code)
throws CompilationFailedException {
if ((obj == null) || (bind == null) || bind.equals("")) {
throw new IllegalArgumentException("No binding specified.");
}

GroovyUtil.getShell(GroovyUtil.bindTo(bind, obj)).evaluate(code);
}
}