02 February 2009

Creating a Clojure GUI Application with SWT

In my explorations of Clojure, I have been developing a desktop GUI application that uses SWT, the graphics toolkit that Eclipse uses. Once you get going, SWT is fairly intuitive to program in with Clojure, but you might need a little help to get started. Here is an example of a barebones app in SWT:
(ns swttest
(:import (org.eclipse.swt.widgets Display Shell)
(org.eclipse.swt.layout GridLayout)
(org.eclipse.swt.events ShellAdapter)))

(defn create-shell [display shell]
(let [layout (GridLayout.)]
(doto shell
(.setText "SWT Test")
(.setLayout layout)
(.addShellListener
(proxy [ShellAdapter] []
(shellClosed [evt]
(System/exit 0)))))))

(defn swt-loop [display shell]
(loop []
(if (.isDisposed shell)
(.dispose display)
(do
(if (not (.readAndDispatch display))
(.sleep display))
(recur)))))

(defn begin []
(let [display (Display.)
shell (Shell. display)]
(create-shell display shell)
(.setSize shell 700 700)
(.open shell)
(swt-loop display shell)))

(begin)
On Mac, you will need to add the "-XstartOnFirstThread" command line option or your application will crash soon after launching.

Update:
I originally left out the line "(create-shell display shell)". The code above is now corrected.

See also:

20 January 2009

Google Code and Subversion

I recently started using Google Code for hosting a new open source project I'm working on (written in Clojure) in my spare time. Google Code uses Subversion for version control, which some predict is going to change soon to Git. While I am pretty familiar with the command line options for the Git version control system, I'm definitely not with Subversion. Maybe Google Code will switch to Git soon, but until it does, I needed to use Subversion, so I went looking for some GUI-based Subversion clients to simplify its use.

Windows

Finding a good Windows client was easy. TortoiseSVN is an Explorer shell extension that is free, stable, and complete. It worked right out of the box with Google Code and I didn't have to read a single line of documentation to become proficient at it.

Mac

The situation wasn't quite as simple for Mac. There are multiple non-free clients for Mac, but I wanted to stick with open source if possible. The closest thing to TortoiseSVN for Mac is something called SCPlugin, but it is incomplete and development on it seems to have stalled in 2005 or 2006.

SvnX is the one I ended up choosing. It is not quite as intuitive as TortoiseSVN, but it seems to get the job done. To get it working with Google Code, I had to run this command on the command line in order to accept the security certificate:
svn list https://GOOGLE_CODE_CHECKOUT_URL
That's it! Off to do some programming.

22 December 2008

My Favorite Mouse

As a programmer, I naturally spend a good portion of my waking hours--if not the majority--in front of a computer. This didn't seem a problem for the first quarter century of my life, but then about three years ago, I started experiencing pain in my mousing wrist. My first thought was that the beginning of carpal tunnel syndrome was setting in, which freaked me out.

I immediately set out to try more ergonomic input devices, and I switched to a pen input device at home and a radical ergonomic mouse at work. While the pen input device worked fairly well, the ergonomic mouse I chose proved to be the single greatest purchase I've ever made. Since starting to use it, I no longer have any pain in my wrist. I now realize that with the many viable ergonomic options for mousing that are available, no computer user should be using the very dangerous standard mouse.

Anyway, the mouse that I wholeheartedly recommend is the 3M Ergonomic Optical Mouse:



It is definitely a strange looking mouse, but the strange shape is what makes it work so well. This mouse fixes two problems with traditional mice:

1. Traditional mice force your arm to twist, causing your tendons to rub against each other, which causes inflammation and pain. By letting your arm sit in a much more natural arm-shaking position, the ergonomic mouse prevents this.

2. When using traditional mice, your wrist, with all it's delicate parts, does all the moving. The ergonomic mouse, on the other hand, keeps the wrist straight and the arm becomes the moving part.

So again, I highly recommend this mouse (or a pen tablet) to all computer users, and especially to programmers.



(Note: Just in case anyone thinks I am advertising for 3M, no, I am not in any way sponsored by or affiliated with them.)

16 December 2008

Industrial Strength Application Development in JavaScript

Inspired by the work of Douglas Crockford, I have been developing a JavaScript application using full blown development techniques. JavaScript is definitely a misunderstood and underestimated programming language, and I have found it to be a pretty good hybrid of object-oriented and functional techniques. I have even done some cool things with it that would not be possible in a statically typed language. I have found that with proper unit testing and debugging tools, its dynamic typing has caused me few problems.

So what tools can I recommend for industrial development in JavaScript? Everything below is an absolute must for my needs:

jQuery
  • What it does: Ajax, DOM-modification, and general utility functions
  • As Jeff Atwood pointed out, there is no good reason to write low-level JavaScript to manipulate the DOM with today, now that there are tons of high quality JavaScript libraries to help out.
QUnit
  • What it does: Simple unit testing, compatible with jQuery
  • I tried out a few other unit testing frameworks, but QUnit is the simplest one by far and just gets the job done.
JavaScript Lint
  • What it does: Identifies most textual errors in JavaScript files.
  • Indispensable tool to find that missing semicolon that is causing that weird error.
  • Note for TextMate users: Use the JavaScript Tools bundle instead of downloading it from the official site.
Firebug
  • What it does: Firefox plugin. In addition to excellent DOM manipulation, it makes a great JavaScript debugger.
In Addition, Mozilla's JavaScript Reference is a must for any serious JavaScript developer.

Well, I hope this gets you started. If you have any other suggestions, let me know!

02 December 2008

Javascript's Undeclared versus Undefined

I learned the hard way that undeclared is different than undefined. If you try to test the simple way for an undeclared variable, you get an error, which in my environment means an annoying pop-up.
/* var a; */  // undeclared
var b; // undefined

// This would cause an 'object undefined' error
/*
if (a) {
alert("a is defined");
}
else {
alert("a is undefined");
}
*/

if (typeof(a) == "undefined") {
// this will be executed
alert("a is undeclared or undefined");
}
else {
alert("a is declared and defined");
}

if (b) {
alert("b is defined");
}
else {
// this will be executed
alert("b is undefined");
}

if (typeof(b) == "undefined") {
// this will be executed
alert("b is undeclared or undefined");
}
else {
alert("b is declared and defined");
}

24 November 2008

Greasemonkey-ing with Gmail's Styles

Last week, Google finally gave us some options to customize the look of Gmail. Excitedly, I went through each theme trying to find my replacement for the boring old "Classic" one. Many of them are graphically appealing, but unfortunately, most of them also have poor contrast compared to "Classic". I finally settled on the "Mountains" theme, but one thing still bugged me about it: the text color of mail titles were too light.

Determined to fix this, I broke out Firebug, the trusty HTML/CSS inspection plugin for Firefox, and found the offending CSS:
.AnqB9d {
color:#3F586D;
}
Then, I created this little Greasemonkey script:
function addGlobalStyle(css) {
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}

addGlobalStyle(
'.AnqB9d {' +
' color: black ! important;' +
'}'
);
Viola! Readable mailbox items! Check out before and after shots:

Before:


After:


Related Links:

07 November 2008

F# and Functional Language Respect

I have been experimenting with Microsoft's F# language, their version of ML / OCaml for the .NET Framework. Microsoft recently announced that F# will become an official part of Visual Studio, up there with C# and Visual Basic. I had never really used an ML-based language before, so I was not sure how big the learning curve would be, but I find that my knowledge of Haskell gets me far enough to feel comfortable writing simple programs after looking over the documentation for a few minutes. On top of that, the current pre-release version of F# has near perfect integration with Visual Studio, including an interactive REPL, debugging, and syntax completion. If you are in the market for a good functional language and are in the Microsoft developer ecosystem, F# seems like a great choice.

I'm not sure how much I will use F# at work, if at all, but it is good to see that functional languages are being taken very seriously at Microsoft now. Not only are the developments of F# encouraging, but each new version of C# adds more functional features, and I find myself using those features daily in my work.

Recommended Sites:

29 October 2008

Developing on iPhone and Android

When the iPhone SDK came out early this year, I was one of the first to sign up for the beta program. I was excited by the possibility to develop on the platform and quickly started reading through the documentation and watching developer videos as I began development of what was to be my first iPhone app. Unfortunately, Apple put one too many roadblocks in place, making the iPhone an undesirable platform for me to work on:
  1. Apple prevented all discussion of iPhone APIs by developers. I tried to ask a simple API question on an Apple developer board, and although a nice explanation why no one could answer me was sent to the board (see the mailing list archive), I actually received obscene emails attacking me for having the audacity to break the SDK's non-disclosure agreement. The draconian NDA clause was removed a few weeks ago, but even then was long after the beta period was over.

  2. Apple charged a fee just to get the developer kit working on an actual device, but then never gave many developers, including me, the unlocking codes to do so until long after the beta period ended.

  3. Apple is still playing games with developers by occasionally pulling legitimate applications off the App Store.
In the end, I gave up and decided to work on Google's Android instead. First of all, Google got Android right by making the tools free and the restrictions few. Another nice benefit was the rich tools available to Android developers due to the Android SDK's use of Java (which has the added bonus of letting me use Scala for Android development!). So far, developing for the Android has been great-- straight-forward APIs, good tools, good documentation. Maybe someone got mobile OS development right.

Related Links:

25 October 2008

Bad Code

Every programmer has experienced it. Code that is so bad, you have to share it with someone. Here are some recent gems I have encountered.

Poor man's comments.
If 1 = 0 Then
...
End If
Is nameString empty?
if (nameString + "x" != "x") {
...
}
Hmm, is the comment wrong, or the code?
// Comma-separated list of numbers
string configurationIds = "254:762:2:236:23:5:21";

20 October 2008

JUnit Testing Scala in Eclipse

Being a fairly new convert to agile development methods, including test driven development, I knew the first thing I would want to get up and running with Scala was a unit testing framework. The NetBeans plugin has built-in JUnit support which served me very well. But I also wanted to get some unit testing working with the Eclipse plugin. It took me a while to get JUnit testing setup with Eclipse, mainly due to my lack of experience in the Java ecosystem. To help future explorers down this path, here are a few lessons I learned.

Put the your tests in a separate source folder. See this tutorial on setting up JUnit in Eclipse for more information.

Add JUnit to your project's build path. Select the project and choose "Build Path" -> "Add Libraries...". Then choose the JUnit jar.

Add the output directory of your project to your build path. See this short guide from the makers of Spec.

To get you started, here is a simple test:
package tests

import junit.framework._
import org.junit.Assert._

class FirstTest extends TestCase {
override def setUp() = {
}

override def tearDown() = {
}

def testOne() = {
assertEquals(1, 1)
}
}