Contents
Introduction
Since its release in August 2005, the Solaris 10 Operating System has generated huge interest. With over 6 million registered downloads, the Solaris OS has become a real target for desktop developers to create and deploy their applications. Key drivers of this success include the tremendous technical innovation in the Solaris platform, with features such as Zones, DTrace, Predictive Self-Healing, and ZFS, as well as the open sourcing of the Solaris OS on OpenSolaris.org. To what desktop will these developers be deploying? They will be deploying to GNOME, the new alternative desktop in the Solaris 10 OS to replace the now-aging CDE. GNOME offers a modern, contemporary desktop that can help developers to showcase their best-of-breed desktop applications. The GNOME community has widely agreed that to attract more desktop developers it is important to be able to offer alternatives to developing desktop applications in C. C is a rather low-level, nuts-and-bolts language that does not have all of the productivity features of a modern object-oriented language, such as interface-based programming, automated memory management, exception handling, and so on. The programming language you will be looking at is one of the most successful object-oriented languages in use today, namely the Java programming language, whose popularity should only continue to grow now that it has been open sourced under the GPL license. It should also be noted that in addition to offering the aforementioned language features, the Java programming language, and in particular the Java Development Kit (JDK), gives developers access to a huge wealth of rock-solid Java platform APIs that can greatly simplify many of the non-UI tasks that modern applications need to tackle, such as working with various data streams, parsing XML data sources, interacting with the network, and so on. Naturally as 95 percent of the GNOME desktop is written in C, many will still continue to develop desktop applications in C using the support of modern IDEs such as the Sun Studio software, NetBeans with its C/C++ module, and Eclipse, but this article will not address this audience. Plenty of online documentation is available for GNOME C-based development at gnome.org for these folks. In this article, after a brief introduction of the choices for Java developers who want to create GNOME desktop applications, the focus will be on one particular technology, namely the Java GNOME bindings. These bindings are targeted at those developers who are already familiar with the GNOME platform, but who want to move away from a C-based application development to use the Java programming language. The bindings are available as part of Solaris Express, Developer Edition 2/07. Choices
When Java software developers want to create a desktop application in the Solaris OS, they need to create an application that will integrate well with the existing GNOME desktop. Such an application should share the same native look and feel as the desktop theme, use the native system dialogs, use the native configuration engine, and in every respect look and behave like a native GNOME desktop application. A number of choices are available to developers. They can use an application framework such as Swing that is part of the Java Platform, Standard Edition (Java SE) or the SWT framework provided by Eclipse. However, if they are already GNOME developers and familiar with Glade/GTK-based development, then they will have to learn yet another framework, which can of course be very time consuming. The Java GNOME bindings offer another alternative. This is a set of Java bindings for the GNOME platform libraries and the Cairo 2D drawing engine from freedesktop.org. The bindings allow GNOME and GTK+ applications to be written in the Java programming language, making use of Java Native Interface (JNI) support to bridge between Java technology and the underlying native GNOME platform and Cairo C libraries. It should be stressed that choosing to use the Java GNOME bindings means giving up the flexibility offered by other Java UI frameworks such as SWING to "write once run anywhere," because of this tight coupling to the underlying GNOME platform and Cairo libraries. However, if high fidelity and native GNOME integration are key design constraints, then this is a reasonable trade-off. Java GNOME bindings simply give Java technology developers another choice when developing their desktop applications. It is up to developers to weigh both their knowledge of the platform APIs/frameworks and their cross-platform and native integration requirements when choosing the appropriate framework for their desktop application development. The rest of this article will explore how to use Java GNOME bindings to develop Java technology-based GNOME applications. The examples will be developed using the NetBeans IDE, but you can of course do much the same in Eclipse if you want (refer to the Java GNOME demo listed in Recommended Reading) or any of the other IDEs out there, such as IntelliJ, jEdit, Emacs, or even vi. What Are Java GNOME Bindings?
As mentioned earlier, this is a set of bindings to the core libraries you need when developing GNOME and GTK+ applications. The bindings provide a Java API that exposes the underlying platform C APIs using the Java Native Interface support in the Java SE platform. The bindings are shipped as a set of Solaris packages containing:
How Can I Get Them?
The good news is that these bindings are already part of the Solaris Express, Developer Edition 2/07. The installed Java GNOME packages for the Solaris OS are
Java GNOME and the NetBeans IDENetBeans is a powerful Java technology-based IDE that can be downloaded from netbeans.org. Java GNOME and the NetBeans IDE can readily be used together to create Java GNOME desktop applications and you can use this IDE along with the Java GNOME API to build a number of sample programs mentioned in this article. Java GNOME Library in the NetBeans IDE To give your application access to the bindings, you need to create and add a Java GNOME Library to the NetBeans IDE which references all of the Java GNOME API jars, source jars, and Javadoc. Once this has been created you just need to add the library to any new projects you create to give them access to the bindings. Java GNOME Library Setup in the NetBeans IDE Follow these steps to manually set up a JavaGnomeLib for your projects to use.
To simplify this setup, we are creating a Java GNOME NetBeans plugin, which is scheduled to be available shortly on the OpenSolaris.org Java Desktop System project downloads area (refer to Resources). When this is installed it will create the JavaGnomeLib automatically. Note that your application might not require all the Java GNOME API jars, but it is very convenient having a single JavaGnomeLibrary to add to any of your Java GNOME based projects. Creating Java GNOME "Hello World"
Launch the NetBeans IDE and create a standard Java application.
Name it "hello" and set it up to use the JavaGnomeLib.
Now you are ready to cut some code. Start with a simple "Hello World" just to be different!
First you import the various APIs you want to use from the GTK+
bindings. (Refer to the Java GNOME man page, which is listed in the
Resources section, for a full listing of the
API imports.) If you want to browse the API sources, just right-click
on the import statement and select Go To -> Source. All of the
source files from the jar will be displayed in the Project panel, which
can be very handy when you are not quite sure which API you want. The
NetBeans IDE also supports code completion so just typing In Hello's constructor you create a top-level window and add a button to it with a "Hello!" title, then set its size and show it. The main routine initializes GTK, calls Hello's constructor, and then runs the main GTK event loop to process user input to the display application.
For the sake of brevity I have not shown you how to add a It's not very exciting but you've just created a native GTK application running in the Java programming language that will respond to any GNOME theme change you make on the desktop. Try it and see what I mean. In GNOME use Start Menu -> Preferences-> Theme to switch between Nimbus and Blueprint.
Responding to the User
When you click the button nothing happens, so you need to add an
action handler, just as you would in any Java desktop application
framework. This is an
Add the following button listener to the
If there are any issues in your code, the NetBeans IDE will
make suggestions through a little light bulb that appears to the right side of the code as you type.
Note that you can also open these code hints by typing
Ctrl-Space. So as you type in the aforementioned code, a light bulb
will appear. Clicking on the light bulb prompts you to add an import
statement for
Running the application now and clicking on the Hello World button will generate the "Hello cruel world!" output on the standard output.
Mix in a Little Glade
You can continue to build up your UI programmatically as you have done previously, but this can become rather tedious to say the least when you are dealing with a complex real-world desktop application. Wouldn't it be much better to be able to separate the UI definition from the code that manipulates it? This is exactly what Glade is designed to do. It is a GNOME UI designer that allows you to create your UI in a WYSIWYG editor and save it out in a UI XML specification file. This Glade file can then be loaded in any GNOME application that supports the LibGlade API, which is also part of the Java GNOME bindings. So now you can create a little more complex UI than your Hello World application in Glade and load it in your test application, thanks to Andrew Overholt, whose Flash demo I shamelessly copied (see Recommended Reading). Launch Glade
The Main Glade Window will appear along with a Palette, Widget Tree, and Properties Panel.
Now from the Palette "GTK+ Basic" section choose Window. Add a Vertical Box with three rows to this window (just hover over the palette items to see what they are called). Then into the top row add a Label, into the middle row a Button, and into the bottom row a Text Entry widget from the palette. To change any properties of the created widgets, just select them in the Widget Tree or the displayed window and edit their settings in the Properties panel.
Hooking Up the Glade UI and the Application
To get your GNOME application to use the new Glade UI you need to load the Glade file in our application constructor.
The NetBeans IDE will prompt you to add your import for So this is certainly a simple way to create a UI but it's not doing very much at present. What you need to do is somehow pass user events to your application code where you can respond to them. Glade signal handlers provide the tool needed. Signal Handlers -- Glade's Action Handlers
In Glade if you want to have your Java code respond to any user interaction, you need to associate a signal handler with the widget in Glade and then provide a signal handler implementation in your code, in much the same way as you set up action handlers in the first example. You can associate a broad range of signal handlers with any given widget in Glade. These signal handlers can then be implemented in your application code and will be triggered whenever the appropriate user interaction occurs within the running application. It should be stressed that the signal handler and the Java implementation must have exactly the same name for all this to work. You can take the default name Glade and generate or modify it in Glade to something else as long as your Java method implementation has the same name. Extend the TestGlade application so that upon clicking the "Press Me!" button it will display a message "Button Clicked!" to the standard output window. First go back to your Test Glade project in Glade.
This creates a handler
Here's a screen shot of Glade being used to set up the button1 signal
handler
Go back to the NetBeans TestGlade project.
Run the TestGlade application and click on the "Press Me!" button to see the signal handler in action. Accessing Widgets
When your application responds to user interaction in your signal handlers, you may need to access one or more of the UI widgets to modify the application in some way. For instance, when you click on "Press Me!" rather than just typing out a fixed message, you'd like the application to display on the standard output whatever text the user has entered in the Text Entry widget.
To do this you need to get a handle to the Glade widget and store this internally
in the class for reference by the
When you type in the previous code, the NetBeans IDE will prompt you to
"Create field entry in
Doing a Little More -- Calculator Example
As an example of a little more interesting application I took the NetBeans BlueJ Calculator example (created by David J. Barnes and Michael Kolling) and ported it over to use a Glade UI and the Java GNOME API. The core calculation CalcEngine is essentially unchanged. For code listings refer to the conclusion of this article.
Since the engine only supports addition and subtraction, I modeled the UI on the GNOME Calculator in the Solaris OS using Glade and just set the Sensitivity to "No" to disable unsupported buttons (Properties Panel -> Common Tab). If you look at the code it is worth pointing out a few things. GNOME application -- This is a GNOME application as opposed to a GTK+ application. This means that when you create a GNOME application in Glade you can create an application window in the Palette "GNOME" section as opposed to using a plain window as your starting point. The application window has a top-level menu, a toolbar, and an app bar (status message) that you can edit as required. This is initialized slightly differently than the GTK applications
already discussed using
Passing named objects to the signal handlers -- Sometimes you need to associate a given object with a signal handler and have it passed to the signal handler when it is triggered by the UI. In the calculator example for instance, rather than having a separate signal handler for each function button, you wanted to have just one signal handler and process the user input depending on which button the user had pressed. The way to do this in Glade is when you set up the signal handler for a button, also set the Object field to the name of the button. In this way the named button will be passed to the signal handler. To process this object just use the overloaded signal handler signature in your Java code, which takes the appropriate Event widget and a generic target Object, which must then be cast appropriately to use.
GConf -- This is GNOME's configuration system and should be used by
applications to store user application preferences and data. In
addition it can also be used by applications to retrieve GNOME
system-wide data that are of use to the application, such as network
proxy settings for a networked client. To demonstrate the use of GConf
a number of functions have been added to
You can also add a Going Further
There is a lot more to do. Check out the examples provided with the Java GNOME bindings. In particular, look at the following TestGtk and TestGnome applications:
GConf and Glade examples are also found under the Conclusion
The Java GNOME bindings offer developers who are already familiar with Glade-based GNOME/GTK+ application development a viable route to developing these types of desktop applications in the Java programming language. At present you can find reasonable coverage of the core libraries, but there are some obvious omissions, such as GNOME applet support and system tray support. The Java GNOME community is already in the middle of a redesign of the bindings to allow a more automated generation of the bindings. This will help to provide nearly 100 percent API coverage of all the underlying GNOME platform and Cairo native libraries and ensure that they stay in sync with future releases of the GNOME platform. Be sure to check out the community site for the latest updates. The community is always happy to get new contributors to the project. So get hacking in Java GNOME! About the Author
John Rice is a staff engineer at Sun who has been working with the OpenSolaris Desktop group over the past number of years. Before this he spent time with the OpenOffice team, helping to automate migration of macros from Microsoft Office to OpenOffice. He has more than 18 years of development experience in the software industry, mostly in the area of document management and desktop application development. A member of the GNOME Advisory Board, John lives by the sea on the east coast of Ireland and can be found at unseasonably early hours of the morning running along the nearby shore, preparing for his next marathon. Recommended Reading
Resources
Solaris Express, Developer Edition 2/07 - Java GNOME 2.16 installation:
Example Code Listings
Sample code listings are available in the
Note: Files ending in | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||