ULC Plugin for IDEA
Plugin for Rich Internet Application development with Canoo's UltraLightClient (ULC) library.
The ULC Plugin provides advanced support for developing UltraLightClient
applications with Intellij IDEA. It contains the following features:
- ULC Facet:
conveniently manage the ULC installations available on your computer (as you do for JDKs), assign a specific
ULC installation to a module, specify the ULC libraries to be put on the class path, specific for each module.
Easily switch between different ULC versions. Source code stubs and JavaDocs are automatically available.
- ULC Application Class Template:
use 'New' -> 'ULC Application Class' to create an empty ULC application class, configure the ULC file
template using 'IDE Settings' -> 'File Templates'.
- ULC Run Configuration:
simply configure, run and debug your ULC application class without the need for a main-method, configure
parameters such as carrier stream provider, data stream provider, coder registry providers, log level,
connection type, user parameters and init parameters.
- ULC Code Inspections:
increase productivity and reduce error count by using ULC-specific code inspections such as check for static
references to ULCProxy instances, missing dispatchers on ULCProxy subclasses and missing scroll pane around
ULC provides a server-side API to Swing and allows for developing Rich Internet Applications (RIA) that run on the
server side in either a Servlet or an EJB container, but still provide a highly-usable, responsive and convenient
user interface based on Swing on the client side. More information on ULC can be found on the
UltraLightClient website from Canoo
The ULC facet provides convenient support for configuring the ULC version for a specific module. ULC itself consists
of a number of different jar files, each containing classes for one specific aspect, such as server-side component
API, client-side UI delegates, support for different server- and client-side deployment scenarios (Servlet, EJB,
Applet, JNLP, command line) or functional testing.
The ULC plugin organizes these aspects in "scopes" and "modules".
These are orthogonal in such a way that each module may be present in different scopes. For example, the "base"
module contains both classes for the "client" and the "server" scope, as there is both a "ulc-base-client.jar" and a
"ulc-base-server.jar". Using the ULC facet, the ULC scopes and modules can be specified for each module of the
The ULC facet supports multiple ULC versions starting from ULC 6.1.x. ULC versions are managed as installations (a
specific ULC version installed at a specific location on the computer). ULC Installations are added to the ULC facet
in a very similar way as JDKs are. ULC installations are stored globally one IDEA installation. For each module
configured using the ULC facet, one specific version is selected from the list of available ULC installations.
Depending on the ULC version related to that installation, the scopes and modules can be selected on demand. The ULC
facet automatically manages the jar files, source stubs and JavaDoc entries. Behind the scenes, ULC creates a module
libary called "ULC" for each ULC-enabled module. This "ULC" library can also be exported to other dependent modules
when using a multi-module project.
When creating a new project or module in IDEA, the ULC facet can already get configured during the new project / new
ULC Application Class Template
The ULC application class template provides support for creating a new ULC application class that already extends
from the corresponding ULC framework class and implements the required callback method for starting the application.
The ULC application class template can get customized using "IDE Settings" -> "File Templates". The template is
available in the "J2EE" tab under "UltraLightClient".
The ULC application class template can selected using "New" -> "ULC Application Class"
ULC Run Configuration
Using the ULC run configuration, a ULC application class can get started without the need for a main method or the
so-called "DevelopmentRunner" (CTRL + SHIFT + F10). The ULC run configuration automatically configures the ULC
environment that allows for executing the client- and server part of a ULC application in a single Java VM. This
way, ULC applications can also get debugged using the same debugging infrastructure known for standalone Java
applications (SHIFT + F9).
The ULC run configuration also supports configuration of advanced, ULC-specific parameters, such as carrier stream
provider, data stream provider, client- and server-side coder registry providers, ULC log level, connection type for
bandwidth and latency simulation, user parameter and init parameters.
ULC Code Inspections
Various ULC code inspections further simplifies the development of ULC applications and reduces the likelihood of
hard-to-find bugs. Currently, the following inspections are provided:
Static References to Instances of ULCProxy
ULCProxy instances represent the server-side half of a distributed GUI component (according to the Half-Object
Protocol Pattern). Each proxy belongs to exactly one ULC session. Proxies have distributed state that automatically
gets managed by the ULC session. When proxies get shared between different ULC sessions, the state handling fails to
work properly. This may lead to hard-to-track exceptions. The most common error that lead to such exceptions is the
use of static references to instances of ULCProxy. This inspection is able to detect static references to proxies.
Missing Dispatcher for ULCProxy Extensions
In ULC, each server-side proxy has an inner class called "dispatcher". This dispatcher represents the API the
server-side proxy exposes to it client-side counterpart for state synchronization and event dispatching. Dispatchers
build up a class hierarchy parallel to the ULCProxy class hierarchy in the sense that, if a proxy A extends proxy B,
then the dispatcher of proxy A also extends the dispatcher of proxy B. Doing so, it is ensured that the API exposed
to the client-side counterpart of proxy B is also available to the client-side counterpart of proxy A. In addition,
added a correct dispatcher to a ULCProxy extension allows for later extenions (e.g. by application projects using a
extension). This inspection detects missing dispatchers on ULCProxy subclasses and provides support for adding the
Model-based Widget not surrounded with ULCScrollPane
As a Rich Internet Application framework, ULC provides a number of widgets that display that from potentially large
models. Such widgets are tables, tree, table trees, lists or text areas. Instances of these widgets are normally
surrounded with a component that allows for scrolling through the large amount of data, a so-called scroll pane.
Adding such a widget directly into a container (a panel) often leads to non-usable applications with less appealing
layouts. This inspection checks for model-based widgets that are directly added to a container (using a method
called "add") and provides convenient support for surrounding the widget with a scroll pane.
How To: Hello World using the ULC Plugin
Using the ULC plugin, it is very convenient to create and run a small "hello world" ULC application:
- Create a new project using "File" -> "New Project ...".
- Specify a project name, location and source folder just for any other Java project.
- On the facet wizard step, select the "UltraLightClient" facet. If no ULC version is listed or the the required
one is missing, click the "New" button next to the ULC version combobox.
- Choose the ULC installation base directory. The ULC plugin automatically checks whether the directory contains a
valid ULC installation and determines its version. The ULC version 6.1.x and 6.2.x are supported.
- Add more ULC installations, if required. Existing ULC installations can get removed or managed by clicking the
"Edit" button. The ULC installation manager then list all known ULC installations. Add or remove them as
- Back on the facet wizard, select the appropriate ULC version for your project (changing the version later on is
easily possible using the facet configuration in "Project Settings"). The click "Finish".
- In the newly created project, add a package to the source folder, if required
- Choose "New" -> "ULC Application Class" from the context menu on the appropriate package. Enter the name of
your ULC application (e.g. "HelloWorldApplication") and press "OK". The ULC application class get created and is
ready to be filled with ULC code.
- Inside the start()-method, add some code, e.g.
ULCFrame frame = new ULCFrame("Hello World Application"); frame.setDefaultCloseOperation(ULCFrame.TERMINATE_ON_CLOSE); frame.getContentPane().add(new ULCLabel("Hello World!")); frame.setLocationRelativeTo(null); frame.setVisible(true);
- Choose "Run HelloWorldApplication ..." from the context menu anywhere in the context of the ULC application
class. The "Hello World!" frame gets displayed. In addition, a ULC run configuration is created and selected in
the upper center of IDEA.
- Choose "Edit Configurations" from the run configuration combobox for saving and customizing the ULC run
configuration for the "Hello World" application. The "Basic Options" tab shows the known settings for any Java
application, except that there is no "Main Class", but an "Application Class" field. The class browser next to
that field lists all available ULC application classes. The "Advanced" tab provides configuration options for
advanced ULC settings such as various provider classes (use the corresponding class browser to lookup the
requested class), log level, connection type and user/init parameters.
- Choose the "Project Settings" dialog to browse to the ULC facet for your module. The ULC facet shows the
configured ULC installation and the selected ULC scopes and modules. Changing these settings (e.g. by choosing
(and maybe previously adding) a different ULC installation), the module class path is automatically modified
accordingly. That way, it is very convenient to run a specific ULC application under different ULC versions.
- Also use the ULC facet configuration to include new ULC scopes and/or modules (e.g. when writing custom
launchers for Applet or JNLP deployment).