Events Clock is an experimental visualisation for your Google Calendar. It shows your upcoming events as coloured slices around a traditional clock face.

The visualisation shows where the hour hand on the clock will be when each event is in progress. The calendars shhown will match the your existing selection of visible Google Calendars. The colours are taken from the colour you have selected for each Google Calendar, with the exception of events in the past, which are shown in grey.

If there is any doubt as to where the 12 hour period begins and ends, a dotted line is shown. Clicking on the events will send you to the page on for that event.


To view Events Clock as a stand alone web page, click here. If you don’t use Google Calendar, or don’t have any events in your calendar over the next ten hours or so, click here for a demo.

To add Events Clock as a gadget on your iGoogle page, click here.


The idea came from the desire to see at a glance what I was supposed to be doing over the course of the day. The original idea was for a mobile phone application. However, once I’d developed a Flash prototype, I discovered iGoogle Gadgets, and the two seemed an ideal fit. I adapted the visual design for the smaller area and it seemed to work well.

As an iGoogle gadget, you’ll see an instant pictorial representation of your day’s events whenever you navigate to your Google homepage.

Accessing Google Calendar data

Events Clock uses a method called AuthSub. This enables it to get access to your Google Calendar data, with no possibility of access to anything else from your Google account. When you click to grant access, a new browser window is opened pointing at a page on Here you can allow access to Events Clock. If you have to enter any passwords you are informing My site will never see this information. It can’t even see your user name, or email address. All it gets is a token from Google that allows it access to your calendar data. This token is stored, encrypted, as a cookie in your browser.

Note that the Google authorisation screen warns that Events Clock has not been configured for secure access. I have in fact developed secured access, but a possible bug in App Engine appears to be blocking the secure authorisation requests.

App Engine

I used Google’s new cloud computing platform App Engine to host Events Clock. This is possible now that App Engine supports Java. This allows my app to benefit from the scalable, and of course free, hosting. The development went reasonably smoothly, although there were some teething problems with the Google Data access.


Events Clock is a concept application, so I’d be very interested to hear your feedback, or reports of technical issues. Please leave comments on here on this blog.


For Android phone owners in the UK, BBC Listings is a viewer and search assistant for the BBC’s TV and Radio schedules.

Users select from a list of channels, then view the schedules for that channel, one day at a time. Clicking on a program shows you a synopsis, and allows you to add a reminder to your Google calendar. Sky+ users can set their Sky+ boxes to record BBC TV programs by a text message.

(This message is prepared by the application and sent from the phone, but requires the phone to be registered for the Remote Record service with Sky. Refer to the Sky website for how to register, and costs and limitations of the Sky+ text message Remote Record service.)


Because it gets its data from the BBC’s web services, internet access is required. Currently, one week’s worth of future listings and one week’s worth of past listings are available.

To search the listings press Menu and Search. Results are returned sorted by channel and then by date.


Look for the application in the Android market (requires a UK registered mobile) or download it directly here


This application is free software. Supported by


0.9.1 : The first published version.


If you have any comments or queries about this application, please leave them on this blog.

I’ve just released a simple utility QuickCalendar onto the Android Marketplace.

It’s a simple application that displays the current and the next (or the next two) events on the notification bar of your Android phone.

I wrote it because I miss a similar feature from my last phone, a Windows Mobile device. The trickiest part was getting access to the calendar data. There is a provider for calendar data, but unlike the contacts provider it is not part of the standard SDK. However the functionality can be obtained if you get the source (Android is open source), adjust the exported items and build your own SDK.

I may write an article on how to do this if there is demand. Also I will release the source for the application when I have OKed it with my employer. In the meantime you can use the application yourself by going to the Android Marketplace on your phone and searching for QuickCalendar.


Get it from the Market, or here


New Quick Calendar icon

I’ve had some nice comments and feature requests (always welcome). As a result I’ve fixed some bugs and added some features.

  • 0.9.29:

    Search button supported on devices that have a hardware search button.
    Corporate Calendar supported on Motorola handets.
    Widgets refresh immediately when calendar is modified, when preferences are modified, and when the screen is enabled.
    Progress indicator for main page.
    Widgets to not refresh when screen is off, to save battery.
    Refresh rate can be configured in preference screen.
    Bug fixed with widget font size.

  • 0.9.18 : Cupcake version! Gadget for home page available. Colored indicators in task bar. Also: German language support.
  • 0.9.17 : Bug fix release (service not starting on phone power up since 0.9.13).
  • 0.9.16 : 24hr (aka military time) format not used in category view unless is on in phone preferences.
  • 0.9.15 : Bug fix release (preference changes not taking effect).
  • 0.9.14 : Context menu selection for time events. Day group headings correct in all time zones.
  • 0.9.13 : Now possible to specify any time (up to 999 weeks) to look ahead for notifications and for the main event list. You are not limited to the pre-set durations. New notification icons more in keeping with the Android conventions. New choice of event list format of ‘grouped by day’ or the original classic layout. Events can be shown colored by the calendar color.
  • 0.9.12 : Fixed bug introduced in 0.9.11 (time zones didn’t work). Sorry everyone. Daylight savings time should also work properly now though.
  • 0.9.11 : Improved progress indicator. Attempted bug fix on calendar preference screen.
  • 0.9.10 : Search option – now possible to search calendars! Minor cosmetic improvements.
  • 0.9.9 : New icon from Darrel Austin. Another ‘all day’ event fix. Fixed problem with apk size.
  • 0.9.8 : All day events sort correctly in all time zones. All day events future day names correct.
  • 0.9.7 : Up two four alerts. All day events work in all time zones.
  • 0.9.6 : aDogTrack support. Notification icons can be enabled in preferences.
  • 0.9.5 : Less obtrusive notify icons. Start service on power on option.
  • 0.9.4 : Ability to select/deselect calendars to alert (where you have multiple calendars).
  • 0.9.3 : Fixed problem where the notifications stopped updating.
  • 0.9.2 : Fixed problem where the time zone was ignored.
  • 0.9.1 : The first published version.

The Google Data Java Client APIs provide a convenient way for Java prorgams to interface with Google’s public Data APIs, for Google calendars, contacts, and many other services.

It’s such a good abstraction, however, there is no clear way of seeing the underlying XML of the feed. When debugging, and for their interest, programmers may wish to see this data – it’s supposed to be human-readable after all.

After at least an hour of playing around I found the commands to enable the logging in the client’s initialization. Traffic will then be output to the console at run time.

The gotcha is that enabling verbose output on Java’s logging requires not just the logs to be set to Level.ALL, but also the underlying handlers.

Here’s the code.

  1. import java.util.logging.Logger;
  2. import;
  3. import;
  1. Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).getParent().getHandlers()[0].setLevel(Level.ALL);
  2. Logger.getLogger(GoogleGDataRequest.class.getName()).setLevel(Level.ALL);
  3. Logger.getLogger(HttpGDataRequest.class.getName()).setLevel(Level.ALL);

Consider a function that collects and returns a list of results. It might look like this:

  1. public ArrayList<String> retrieveAll(long requesterId);

Or even better, this, so it could use anything that implements Iterable<>:

  1. public Iterable<String> retrieveAll(long requesterId);

However, storing the results in a container which is then returned may be inefficient for the application. It may be better to enable the calling code to act immediately on each collected result rather than first waiting for all results to be collected and stored. If that were possible..

  • No memory would be used to store a list.
  • Results could be presented to the user straight away.
  • Calling code could abort the collecting process part way through based on its own logic – for instance if it already has more results than it can handle.

Custom iterators

One way to avoid an intermediate list is for the collecting function to construct a custom Iterable<> object, which constructs Iterator<> objects that contain the collecting logic. Each execution of next() calculates the next value and returns it straight away for the calling code.

The difficulty for the programmer is that this may require a significantly different structure of the collecting code. This code has to store any state from result to result as private variables inside the iterator. Call stack is reset with each result, so algorithms that use recursion are not possible.

More convenient for the programmer would be a technique that allows the collecting code to keep control of the machine state during the collecting process.

Yield return

C# has ‘yield return’ which allows a function to be structured exactly as if it is building a list. It may keep its own state in local variables and the call stack, but still present each value to the calling code immediately as it is found.

Java doesn’t have yield return, but another pattern that could be used is this:

  1. public void retrieveAll(long requesterId, ResultProcessor<String> collector);

Where ResultHandler<> is a simple interface to an object invoked by the collecting code to return individual results as they are collected.

  1. public interface ResultHandler<T> {
  2.   void handleResult(T value) throws CollectionAbortedException;
  3. }

It is left up to the calling code what ResultHandler<> implementing object to supply, and how to handle the data. Anonymous classes would be quite neat here. For instance, a caller could output the results to a console like so:

  1. retreiveAll(myId, new ResultHandler<String>(){
  2.   public void handleResult(String value) {
  3.     System.out.println(value);
  4.   }
  5. });

The collect() function may abort the collecting operation part way through by throwing a CollectionAbortedException.

The disadvantage to this approach is that it is a little less convenient from the perspective of the calling code. The function has a novel pattern, taking ResultHandler<> as a parameter rather than the more familiar Iterable<> as a return value.  Logic has to be embedded inside an anonymous or specially constructed ResultHandler<> class.

Unlike the case of returned Iterables, the calling code can not use ‘for each’ loops on the result. Nor can it store or pass around the Iterable<> to other systems as a parameter.

Solution : The yield adapter

A best-of-both-worlds solution would allow a collecting method based on ResultHandler<> to be automatically adapted at run time to an implementation based on Iterable<>. A data-collecting function implemented in this form (convenient for the collecting code) …

  1. public void retrieveAll(long requesterId, ResultHandler<String> collector);

.. would be adapted into this form (convenient for the calling code)..

  1. public Iterable<String> retrieveAll(long requesterId);

This would provide the same benefit C# programs get from yield return. Namely, the ability for both collecting code and calling code to have their own machine state and callstack control throughout the entire collecting and processing operation. It is not necessary for either side to separate logic into methods inside anonymous classes. Collecting code can use complex recursion algorithms. Calling code can store and defer use of the Iterable<> used to collect results, or pass them as parameters to other functions.

Approach Collector controls flow Caller controls flow Requires list Caller can abort collect Uses new thread
Collector builds and returns list in form of Iterable<> yes yes yes no no

Collector returns Iterable<> containing logic

no yes no yes no
Caller passes in ResultHandler<> yes no no yes no
ResultHandler<> wrapped to Iterable<> with yield adapter. yes yes no yes yes

How it works

I am not the first engineer to attempt to bring yield to Java. Aviad Ben Dov’s article in 2007 describes a way to do this using bytecode manipulation and classloader modification. My view is that a solution in Java alone would be more practical as a portable library.

My starting premise was that if calling code and collecting code are both to have their own call stack, this could only be achieved with the use of multiple threads.

In addition, I was aware of a Java collection SynchronousQueue which is designed to allow two threads to pass values between each other, each in turn yielding control to the other.

The Yield Adapter simply makes a new custom Iterable<> which is returned to the calling code. The iterable creates iterators on demand, which also starts a new thread for the collection, and makes a SynchronousQueue for communication between the two. Results are wrapped in message object and, .put() into the queue on the collecting side. The iterator side uses .take(). There is also some extra logic to ensure that incomplete reads do not result in leaked resources.

Please note that although the adapter uses threads, the code does not normally need to be ‘thread safe’ in the classic sense. That is because there is never a time that both threads are executing simultaneously. One thread always ‘yields’ to the other. The exception to this is if multiple iterators were ever in effect at once.

Source and demos

The adapter source can be found here with the interfaces employed all here.

A demo here shows how the adapter can be used to allow a recursive scan of files and directories, returning the result through an iterator.

A more complex demo here returns all possible ways the letters in a word can be rearranged, without repeats.

The library source can be downloaded with Subversion or your browser here and the tests and demos are here.


I hope that this small library will allow people to develop complex algorithms that present results to calling code as iterators.

If you have any comments on the code, please add them as comments on this article.

Update Feb 2009

Many thanks to Dominic Lachowicz who brought to my attention the fact that the SynchronousQueue does not in fact stop both threads running at the same time. A revision checked in today uses a Semaphore object to achieve the desired behaviour.

A project I’ve been working on required a random selection of postings to be shown to users. The entries were to be drawn from a larger list : a cache of references to posts held in memory.

My first effort at the selection code simply copied the original list, shuffled it, then selected the first ‘n’ entries (where ‘n’ is the number of required postings). A colleague remarked that this was hardly an optimal use of time or memory. So I decided to write a a general-purpose function to select ‘n’ unique entries from a list of ‘m’ entries – using as little memory and processing time as possible.

A naive solution

The most obvious solution to the problem is to repeatedly draw random entries from 0.. n of the list. To reduce the repeats, keep a record of the indices of the random entries already selected. Then, as each new item is selected, the existing list is checked to see if the entry was already taken.

The problem with this is that as more entries are selected the likelihood of such a collision increases. The execution time of the function cannot therefore be predicted. In some cases where the number to select was very large this could make the function quite slow. You could speed it by using different containers and such, but a better approach seems to be avoid collisions in the first place.

Consider a case of selecting five random entries from a list of ten. The first entry index can be found by picking a random number between zero and nine. When making the second selection however there are now only nine remaining unselected entries. So if we pick from zero to eight, then find a way of converting this number (the index of unused entries) into a full source table index, we have avoided the possibility of collision altogether.

The method

My solution calls for items chosen using a random number generated between 0 and m-c where ‘c’ is the number of already selected items. This represents the relative index of unchosen entries, not the actual entries themselves. This number is then converted into the actual entry index by an algorithm.

This algorithm involves iterating backwards through the list of already picked random numbers. The principal is at each iteration to convert the index from 0… m-c space to 0 .. 1+m-c space. In other words the space of the previously selected element. One single operation can do this, and at the same time avoid any potential collision with the last drawn entry in its target space. The operation says “if the already selected entry’s unchosen entry index is the same or less than the current index number then increment this index by one.”

When all already selected entries have been processed in this way, the resulting index is guaranteed to be in 0.. n space and clear of any collisions with already selected entries.

The method has an order of execution n*m / 2, and temporary storage requirements of n indices. This is stable and predictable however so it is a in improvement on collision avoidance methods that would mean repeating random selections.


Here is a ready-to-use implementation in Java.

  1. import java.util.List;
  2. import java.util.Random;
  3. import java.util.ArrayList;
  5. public class ListUtil {
  7.     /**
  8.      * Create a new list which contains the specified number of elements from the source list, in a
  9.      * random order but without repetitions.
  10.      *
  11.      * @param sourceList    the list from which to extract the elements.
  12.      * @param itemsToSelect the number of items to select
  13.      * @param random        the random number generator to use
  14.      * @return a new list   containg the randomly selected elements
  15.      */
  16.     public static <T> List<T> chooseRandomly(List<T> sourceList, int itemsToSelect, Random random) {
  17.         int sourceSize = sourceList.size();
  19.         // Generate an array representing the element to select from 0... number of available
  20.         // elements after previous elements have been selected.
  21.         int[] selections = new int[itemsToSelect];
  23.         // Simultaneously use the select indices table to generate the new result array
  24.         ArrayList<T> resultArray = new ArrayList<T>();
  26.         for (int count = 0; count < itemsToSelect; count++) {
  28.             // An element from the elements *not yet chosen* is selected
  29.             int selection = random.nextInt(sourceSize - count);
  30.             selections[count] = selection;
  31.             // Store original selection in the original range 0.. number of available elements
  33.             // This selection is converted into actual array space by iterating through the elements
  34.             // already chosen.
  35.             for (int scanIdx = count - 1; scanIdx >= 0; scanIdx--) {
  36.                 if (selection >= selections[scanIdx]) {
  37.                     selection++;
  38.                 }
  39.             }
  40.             // When the first selected element record is reached all selections are in the range
  41.             // 0.. number of available elements, and free of collisions with previous entries.
  43.             // Write the actual array entry to the results
  44.             resultArray.add(sourceList.get(selection));
  45.         }
  46.         return resultArray;
  47.     }

An SVNWatch desktop alert

Part of my last job involved some management of a large code base. I wanted to keep an eye on activity on the Subversion source control database. In particular I wanted to know as soon as someone had checked in and what the changes were.

There are many plug-ins available for Subversion (also known as SVN) that will email interested parties when the repository changes, but my experience with these is that they create so many emails that people end up turning them off. Also, they need administrator access to the database which not everyone will have.

I hit on the idea for a “notifier” application for Subversion that would act like the gmail notifier, letting interested parties know as soon as an SVN database is changed. The Windows balloon alerts are ideal for this sort of thing, so I wrote an application for Windows Forms .NET 2.0 which I am ready to publish today.


SVNWatch is a Windows application that provides desktop alerts when nominated SVN repositories are changed.

The application runs in the status bar. Alerts when the repositories change take the form of messages in status bar ‘balloons’, and a change in the appearance of the status bar icon.

Clicking on the status bar icon will display a list of the new SVN log entries since the last scan operation.

The application can watch an unlimited number of SVN repositories.


SVNWatch requires two other components to be present on the user’s PC:

  1. The .NET Framework version 2. Vista comes with this pre-installed. For XP, this can be downloaded from the Microsoft website here.
  2. The Subversion Windows client software (“SVN.EXE”). This can be downloaded from the Tigris/Subversion website here.

    This is required because SVNWatch invokes the SVN.EXE to interface with the repositories, rather than using an internal static library. I had poor results getting the same results out of the standard API that are available through the SVN.EXE route.

The main dialog

The main dialog lists the watched repositories, provides options to manage the list and gives information about forthcoming scans.

The main SVNWatch window

Click on the ‘Add Repository’ toolbar button or from the Repository menu select Add.

A New Repository dialog will be shown. Under Monitor Url enter the URL of the repository, for instance

Click OK to add and start monitoring the repository.

First time connection

SVNWatch will fetch and display the first batch of logs. If there is a technical problem connecting to the repository or fetching the logs, this will be displayed in the bottom of the main SVNWatch dialog.

Regular scans

As long as SVNWatch is running, it will regularly scan repositories for new logs
to report. The frequency of scans can be changed in the Settings.

When new logs are available a notification balloon will be shown in the task bar. If just one new log is seen, a quick summary of the check in comments will be shown. If more than one log is available, the number of logs available will be shown.

An alert just displaying the number of logs received

Clicking on the bubble will show a full and detailed list.

A full list of new logs

In addition, the task tray icon will change to indicate there are new logs that have not been viewed by the user.

If new logs are available, they can also be viewed by clicking on the View New Logs button.

Edit repository settings

Repository URLs or other settings can be edited at any time by selecting the repository in the main list and selecting Edit Repository.

The user can also view when the last scan was performed and what the outcome was. This can be useful for troubleshooting problems to do with database connection.

The Maximum Fetch value indicates the largest number of logs to download. This is necessary because some long-established SVN repositories are very large.


Settings, which include the repositories scanned, are automatically saved and retrieved. They are stored for each Windows user.

The settings file can be found in a location such as C:\Documents and Settings\User Name\Application Data\SVNWatch\settings.bin where User Name is the current logged in Windows user name.

The settings can be edited by selecting the Edit menu then the Settings menu item.

The settings dialog

  • Minimise to tray
  • When the application is not in use it is only shown in the system tray, not the taskbar.

  • Scan every
  • The interval in which to scan each SVN repository for changes.

  • Time out
  • The amount of time to wait for remote operations to complete before giving up.

  • Run on startup
  • When checked, the program will start running as soon as the user logs into Windows.


Download SVNWatch as an executable installer from here. Before running SVNWatch, go to the Tigris official Subversion website and download and install the Windows Subversion client (used by SVNWatch).

Alternatively, you may obtain the source code from my own SVN repository here. The project can be built with Visual Studio 2005 C# Express or other later versions of Visual Studio. SVNWatch and its dependent projects are open source, licensed under the LGPL.

C# .NET provides a standard mechanism for programmers to inline XML documentation in their programs. Classes, functions, properties and more can be augmented with comments, and the build system creates amalgamated XML files accompanying the program output. A variety of tools such as Sandcastle can build help files from the data. Visual Studio 2005 and 2008 also supports the scheme with keyboard shortcuts and optional build warnings for missing comments.

  1. /// <summary>
  2. /// An example C# class
  3. /// </summary>
  4. /// <remarks>
  5. /// This class illustrates how a class can be marked up with inline C# comments
  6. /// </remarks>
  7. class SomeExampleClass
  8. {
  9.     /// <summary>
  10.     /// An example of a property
  11.     /// </summary>
  12.     public int ExampleProperty
  13.     {
  14.         get { return somePrivateVar; }
  15.     }
  16. }

Unfortunately, many programmers have observed that there’s no way to discover these comments at runtime by reflection. All manner of alternative information can be accessed with reflection – but not the XML comments.

The solution

This documentation can be discovered at run time with a little extra code, as I will demonstrate. The reason the comments can’t be discovered by reflection alone is because they are not included in the .NET assemblies (.EXE or .DLL files), but are conventionally included as .XML files to accompany the assembly files.

I’ve provided a simply class library for .NET 2.0 called DocsByReflection that will when possible return an XmlElement that describes a given type or member. This can be used to easily extract comments at runtime. Here’s an example of how:

  1. XmlElement documentation = DocsByReflection.XMLFromMember(typeof(SomeExampleClass).GetProperty("ExampleProperty"));
  2. Console.WriteLine(documentation["summary"].InnerText.Trim());

This would ouput “An example of a property”, extracted from the code comments in the code fragment at the top of the article.

The class works by locating the .XML file accompanying the assembly that defines the type or member (discovered using reflection). Then the .XML file is loaded into an XmlDocument, and the ‘member’ tags are scanned to find the one that refers to the target type or member. This tag is returned as an XmlElement which contains the free form XML that these comments can contain (e.g. including HTML markup).

This method relies on the existence, on disk, of the generated XML. It must have the same name and location as the generated .EXE or .DLL accompanying it – with only the extension changed. This will happen by default when building with Visual Studio, once documentation is enabled (see below). If you are distributing your program and expect the distributed version to discover the comments in run time, you must also distribute the XMLs alongside the executables. This is commonly seen in any case. Note that many of the framework executables (for instance those found in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727) are accompanied by documentation XML files.

How to use

Download the library source as a zip file here, or use Subversion to update to the very latest version here and here.

(Updated 18/3/08 for bug fix – see comments).

Load the DocsByReflectionDemo.sln to see a simple example of how to use the library. This gathers and prints information about a class type, some functions, a property and a field.

Using in your own code

In Visual Studio, set up your own project that includes XML comments.

(Note that the XML documentation output is not enabled by default in Visual Studio. Go to your project properties, select Build, and under the Output section check the box that says XML Documentation File. It is very important that you do not change the location of the XML file or this method will not be able to locate it at run time.)

If you have not already, add the comments in Visual Studio. By default, pressing forward slash three times when the caret is positioned before the start of an element you wish to document (such as a class or method) will insert a documentation template for you before the start of the file.

Add the DocsByReflection project to your solution and a Reference to it from your project. Add the line “using JimBlackler.DocsByReflection;” to the top of your .CS file. The call se the functions DocsByReflection.XMLFromType() (for classes, structures and other types) and DocsByReflection.XMLFromMember() (for methods, properties and fields) to fetch XmlElement objects that represent the documentation for that type or member.

Query the returned object to read the documentation. For instance, xmlElement[“summary”].InnerText.Trim(). This locates the summary node, and uses the InnerText property of XmlElement to strip out any XML formatting that may be embedded in the comment. Also, Trim() or a regular expression can strip the unwanted whitespace from the comment.

Comments or problems

If you have any comments or problems with the library, please add a reply to this blog post and I will answer them here.

A simple application overriding enter and return in a TextBox

Many applications feature text input boxes that used to accept input for immediate use by the program. For instance, a program might provide a dialog allowing user to search for text in a document. This would feature a text box to enter the text, and a button next to it labelled ‘search’ that would immediately act on the supplied text.

However many users will not want to click the ‘search’ button, but simply press Return or Enter after entering the text.

How can this be done in a C# .NET 2.0 Windows Forms application? One way is to set the Accept property in the parent form to refer to the ‘search’ button. This will make Enter / Return automatically press the button, when pressed in any child control on the form.

The events to override in the designer

This doesn’t always offer the level of control the application developer wants. Any control could activate the press, not just the relevant text box. It requires a button, which might not always be desirable. Also it is not trivial to allow multiple textboxes on a single form that all accept Enter / Return in that way.

The best way that I have found is to add a KeyDown event to the textbox and compare the pressed key with Keys.Enter. Then, act on that key and set SuppressKeyPress in the event arguments so that the system does not try to do anything further with the keypress. (Typically what happens otherwise is that an ‘error’ beep is played).

  1. private void textBox1_KeyDown(object sender, KeyEventArgs e)
  2. {
  3.     if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.None)
  4.     {
  5.         // do something with textBox1.Text
  6.         e.SuppressKeyPress = true;
  7.     }
  8. }

However if you implement that code and run the application, you’ll find nothing happens when you press Enter. The reason is that the Enter key press never reaches the KeyDown event. This happens because certain key presses are reserved for system use. The solution is to supply a PreviewKeyDown event in the textbox. This gives the opportunity to override the system override as it were, and allow the key to reach the KeyDown even in the textbox.

  1. private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
  2. {
  3.     if (e.KeyCode == Keys.Enter && e.Modifiers == Keys.None)
  4.     {
  5.         e.IsInputKey = true;
  6.     }
  7. }

I’ve provided source for an example application as a zip file. Requires Visual Studio 2005 or later, C# express will also work.

Download source code

Mac and Java 1.6 (or the lack thereof)

Java SE provides a great opportunity to create applications that will run on Windows, Linux and Mac from the same single .jar executable file. All the end user needs is Java installed, and this is installed as standard for many OSes.

Unfortunately at the time of writing, Jan 2008, there is a problem with targeting Macs. Even the latest version of the Mac operating system OSX 10.5 (Leapard) does not include the latest version of Java, 1.6, that has been the default in Windows-based Java IDEs for a year at least.

A beta can be downloaded but this requires registration on the developer sites, cannot run on OSX 1.4 (Tiger), requires an Intel 64 bit processor, and has other restrictions. Right now it’s far from ideal for a mainstream application, and it’s hard to imagine that even when released officially 1.6 will reach a critical mass of deployment until 2009 at least.

The Windows NetBeans to Mac problem

Unfortunately GUI applications developed with the latest Windows NetBeans 5.5 (the free Java API from Sun) require some configuration to allow applications to be developed that run on out-of-the-box Macs. This is not just because of the OSX Java 1.6 problem, but also some glitches with the “backport” targeting in NetBeans. This affects GUI applications developed with NetBeans GUI editor which uses Swing, a cross-platform GUI layer for Java.

It is not enough to set the source level to 1.5 in the project properties, but to continue to use the 1.6 JDK. This will not run on OSX with 1.5 JRE. The error in the Console will be:

java.lang.NoClassDefFoundError: javax/swing/GroupLayout$Group

The problem is that when using NetBeans’ Swing editor with the 1.6 JDK will create code that won’t run on machines that have Java 1.5. This is because it inserts references to javax.swing.GroupLayout, which only exists in 1.6 onwards. Misleadingly, it does this even if ‘source level’ is set to 1.5.

The solution

This can be fixed by downloading the 1.5 JDK (aka the Java Development Kit 5.0 Update 14) and set your NetBeans project to use it. When new Swing GUI elements are created with this JDK set, the IDE uses the org.jdesktop.layout.GroupLayout class instead. This is not built into the JRE but the additional files can be bundled in your .jar. More about this in a second.

The file you require is jdk-1_5_0_14-windows-i586-p.exe and can be downloaded from Sun. Once installed, in NetBeans select Tools->Java Platform Manager. Click Add Platform and choose C:\Program Files\Java\jdk1.5.0_14.

In your applications, in the properties panel, select Libraries, then set the Java Platform to Java Hotspot(TM) Client VM 1.5.0 14-b03 which should now be available. It is important that you do this before you add any Frames as the act of doing this generates the code that must use the correct version of GroupLayout.

The last step is to ensure that the files that 1.5 users (i.e. Mac users) will require are bundled into your .jar, follow the instructions here.

In conclusion

Following these instructions will results in a .jar file that can run on any out-of-the-box installation of OSX, Windows (with latest Java), or Linux.

A great benefit of cross-platform Java SE with Swing is that you can create applications that use all the standard “native” GUI controls for the platforms on which they run. The end-user will have little idea that Java was used, they’ll just see it as an application that looks like it was developed for their choice of OS. To make your Swing applications use native look and feel, follow the instructions under “Programatically Setting the Look and Feel” here

« Older entries § Newer entries »