The Source for Java Technology Collaboration
User: Password:



Evan Summers's Blog

Community: JavaDesktop Archives


A short history of Web UI programming

Posted by evanx on June 26, 2008 at 07:18 AM | Permalink | Comments (12)

Web 1.0, XUL, Ajax, Laszlo, Flex and Silverlight have a common approach - declare the UI view using markup (HTML or XML), and use JavaScript to handle the UI events and manipulate the UI. JavaFX/Swing is a notable exception - which is exciting and/or risky?! 'Cos Web developers know and love JavaScript and HTML, so XML plus JavaScript is right up their alley.

If you're a Java UI programmer, there's GWT, Wicket and Echo. And with a great new Java plugin in the works, maybe Swing applets will be considered again in some quarters? But all web developers know JavaScript, and not necessarily Java, Groovy, et al, so probably JavaScript/Swing is a better bet than Java/Swing? Imagine having an XML schema for a flashy JavaFX/Swing toolkit, call it JavaFXml, with great JavaScript bindings, so make that JavaScriptFXml ;)

1008232_network_spheres.jpg Anyway, let's look at the short history of web programming...

HTML, CGI, Perl
The Web started with HTML. HTML forms could be submitted via a submit button. Apache's Common Gateway Interface (CGI) enabled server-side scripts to process the form data, and generate an HTML result page. Perl, being a popular scripting language at the time eg. with Linux system administrators, suddenly became the popular language for CGI scripts, and many "sysadmins" suddenly became "webmasters."

JavaScript, DHTML
Netscape invents JavaScript for client-side UI scripting in web browsers, "designed to be easier for non-programmers to work with." Microsoft adopts it too for IE, calling it JScript. So it becomes the de facto standard - the lingua franca of web designers everywhere. HTML plus CSS plus DOM plus JavaScript equals "Dynamic HTML" (DHTML). Web designers suddenly become "web developers."

Java Applets
While certainly suitable for experienced programmers, this was not so great for "web designers," despite promising books such as "Teach Yourself Programming, Java, AWT and Swing in 24 hours." Actually this stuff is not "for Dummies." Not to mention some technical issues with the plugin like startup time, browser crashes, download size, etcetera. So web developers stick with JavaScript, which they know and love, to do neat DHTML things on the client-side.

PHP
Web developers know HTML, some JavaScript for client-side scripting, and some Perl for server-side CGI scripts. PHP gives them embedded server-scripting in their HTML pages. Poifect! Web developers become hard-code PHP programmers.

Java JSPs, Servlets
Schools started teaching Java, and enterprises got Java programmers, and we started spreading our Java love across the internets and intranets. But the majority of the web developers are not gonna suddenly jump off the PHP bandwagon and onto the server-side Java supertanker, notwithstanding the availability of the above-mentioned books - because 21 days is quite a long time.

internetexplorer3.jpg Flash
Woohoo, let's add animations, interactivity and multimedia to spice up web pages!

XUL
Fantastic technology - XML UI markup plus JavaScript logic - way ahead of its time! If IE hadn't taken over the world and crushed Netscape, then maybe XUL would have taken over the Web?!

Ajax
Let's load content asynchronously, without having to submit and reload the whole page, and script the UI using JavaScript as per usual. Poifect!

Laszlo
Great stuff, inspired by Flash and XUL. If it was opensourced earlier, and/or bought by Adobe and renamed to Flex, or bought by Sun and renamed to JavaScriptFX...

Flex
Inspired by Laszlo, and currently taking over the RIA world, athough the Web is still owned by DHTML/Ajax.

Silverlight
Ditto.

JavaFX
Too early to tell. How is it gonna be better than Flex and Silverlight? What JavaFX tools for web designers?


Summary

Everything from HTML, through to XUL, Ajax, Laszlo, Flex and Silverlight, have a common approach, namely let's declare the UI view using markup (HTML or XML), and use JavaScript to handle the UI events and manipulate the UI.

1008231_network_spheres.jpg Given the predilection of web developers towards JavaScript and XML, one wonders if the JavaFX initiative shouldn't have embraced JavaScript with an XML thingymajig also, like Microsoft (XAML) and Adobe (MXML) chose to do, rather than introducing a new scripting language? 'Cos in any event, the visual aspects of an UI should be designed by designers, using a GUI builder tool, rather than programmed by a programmer?

With a great new Java plugin in the works, and other JavaFX-induced improvements for client-side Java, maybe Java/Swing applets will be the preferred option for many of the Java programmers out there, rather than moving to one of the available scripting languages on the JVM eg. JavaScript, Groovy, JRuby, JPython, JavaFX Script?

If we want JavaFX/Swing to succeed in the browser, surely we need a GUI tool to design those flashy UIs, generate XML, and be scriptable using JavaScript first, and otherwise Groovy, Java et al, for programmers that prefer those other JVM languages.


Further Reading

Taking a cue from the cutting-edge of EJB3/Seam programming, last week i wrote an article titled "Gooey MVnC" proposing a convention-over-configuration MVC framework for Swing GUIs - to eliminate boilerplate and glue code for beans binding, events and tasks. Everytime i revise that article, i might write a new blog entry, like this one, just so that i can link to it again, which is precisely the reason why i was inspired to write this blog entry!




MVnC architecture for Swing GUIs

Posted by evanx on June 19, 2008 at 06:52 AM | Permalink | Comments (0)

Rather than put our "application logic" in a "messy" view class, we create a separate "controller" class, with event handlers.

We wish this controller class to be as neat and tidy as possible eg. with minimal boilerplate or much else besides our application logic.

Let's explore how we might achieve this, using an annotation-driven application framework, with some AOP and convention-over-configuration.

Please submit your comments and suggestions for discussion below. This is an ideas-in-progress, without an implementation (yet). As such this article should be considered to be a first exploratory draft of a design-in-progress...

Next month, i'll whip up some kinda prototype, if it's deemed worth it, and if i'm still unemployed ie. with time on my hands.

 
Gooey MVnC Guidelines Cheatsheet
View  Controller  Model beans 
Code Messy Neat Trivial
Tool GUI Designer
Rules No logic No strings
Automation  Beans Binding Events & Tasks  Validation
Tricks Resource injection  AOP


Code Snippet

Our controller class includes annotations in order to enable our framework infrastructure to automatically map events from our GUI components to event handler methods, and to support background tasks and EDT-switching via AOP.

public class LoginController extends GBasicController {
   @View LoginView view = new LoginView(); // JPanel with components
   @FormBean User user = new User(); // for form fields auto binding
   ...
   @BackgroundTask void fetchUsers() throws DatabaseException {
      ... // long running task
   }

   @BackgroundTaskDone void fetchUsersDone() {
      ... // update GUI with results from task
   }

   @EventHandler void okActionPerformed() {
      ... // handle OK button pressed
   }
   
   @EventHander void usernameEntered() throw DataException {
      ... // validate username exists in database
      view.password.requestFocusInWindow();
   }
   ...   
}

Annotations in our model beans, eg. User, relate to binding and validation, where we wish to support automatic binding of view components to bean properties, eg. by matching component names to bean property names.




Java Droid

Posted by evanx on November 21, 2007 at 02:50 AM | Permalink | Comments (2)

Recently i was travelling through Europe for three months without my laptop and/or its 3G wireless internet connection, sometimes cycling in the French Pyrenees, not knowing for sure if i would find a bed at the next town, after many hours in the saddle, running out of sunlight, not to mention energy. One of many things i learnt from this wonderful experience is that cellphones ought to have practical web browsers. They ought to negate the need for finding an internet cafe, but they don't, not mid-level handsets anyway. I bought one of the latest Nokia 3G feature phones in London for £89.99, with which i took photo's and sent SMS'es to my heart's content, but browsing the web was not practical eg. searching for accommodation, checking maps, train schedules, booking flights and what-not.

phone6-200.png Reading a few blogs et al, one gets the impression that everyone immediately assumes that Android will be a success. Arguably Google's brand, money, reputation, talent, web apps and userbase all but guarantee this, as illustrated by the size and scope of the Open Handset Alliance. However this alliance excludes Sun and Nokia for example, who have been investing in existing mobile Java platforms for quite some time. Might JavaFX Mobile eg. an opensource JavaSE/JavaME/Linux mobile stack, join the Blackberry, the iPhone and Android as a smartphone game-changer?

As we now know, Android is another opensource mobile platform, built on Linux et al, with an Apache-licensed Java'esque layer ie. Harmony, Dalvik VM and android.* which includes a brand new UI toolkit.

Many handset makers welcome this free offering from Google, who is vendor-neutral, and bidding on the 700Mhz spectrum to boot. Opensource OS'es aren't dominating consumer PCs, and consumers aren't crying out for opensource handsets per se. But phones that integrate well with your favourite Google services may be very attractive to customers. Nokia, RIM and Apple have their own smartphone software platforms, and so they aren't in the OHA, where handset makers commit to producing an Android phone. Carriers want to offer great phones to their customers, but also they are a conservative bunch, and concerned about VoIP and IM impacting their revenue, not to mention dual-mode handsets that can switch at wifi hotspots.

Are developers crying out for yet another mobile platform? If it affords total freedom on millions of truely open handsets, then for sure. I'm crying out for extending the PC platform to mobiles, so i can write once, run everywhere. Android steps in that direction, being a Linux-based mobile platform. But it is a divergence from mobile Java efforts and standards many years in the making, through collaboration by the major players eg. Sun, Nokia, et al. Android employs the Java programming language, but unfortunately is not a standard or complete Java platform, ie. it doesn't commit to JavaME or JavaSE. Having said that, JavaME is bound to be supported on many Android-based handsets, and in time maybe JavaSE too.

There are other Linux-based mobile platforms, and JavaME is pretty universal, so Android is a non-standardised upstart at this stage. We can only wait to see the market penetration of Android handsets in the years ahead, and how developers and other players respond, eg. Sun with JavaFX Mobile. Android's APIs might become a JSR which is then included in the JavaFX Mobile stack, and/or JavaFX Mobile might leverage Android's OS? Who knows!?

The hype around the Blackberry, iPhone and future gPhones is contributing to the rapid growth of the smartphone market in general. And today's smartphones are tomorrow's affordable handsets. To my mind the game then gets really interesting when common handsets have converged with personal computers, and these platforms become indistinguishable to consumers and software developers. Gimme a handset with Linux, Firefox, JavaSE, Swing and Webstart - otherwise it's just a gimmicky ol' phone, innit!?

What is Android vs JavaFX Mobile?

Posted by evanx on November 13, 2007 at 10:45 AM | Permalink | Comments (11)

So the "personal computer" platform with its graphics, internet et al, is converging with telephony handsets, and visa versa. It's nice. I'm trying to understand how Android changes the pace of this convergence, and how it's different to JavaFX Mobile.

Phone200.png So JavaFX Mobile is the mobile software stack formerly known as SavaJE. Looking at the spelling, we guess that SavaJE was about JavaSE on mobiles. Its apps are written in Java, including the telephony ones, 'cos it affords full access to the handset's telephony hardware functionality, eg. for making calls, handling SMS'es and what-not. Maybe JavaME offers relatively limited access to the hardware? Certainly it's not full-blown desktop Java either.

Yes please, we want the full JavaSE with Swing on mobile phones already. 'Cos these devices have the CPUs, RAM and display resolutions that our PCs had when Java first started practising its love all across the internets.

Some reading suggests that SavaJE was built on a minimal Linux kernel, and that JavaFX Mobile is a Linux/Java stack. Android is also a Linux/Java stack, so, um, can someone please tell me if Android competes with JavaFX Mobile, and what their differences, similarities and/or respective futures, might be?

Android is opensource, in fact it's Apache-licensed, and uses Apache Harmony's class libraries. (Linux is GPL, as are many of the native libraries in Android's stack, so it clearly isn't entirely Apache-licensed.) Is JavaFX Mobile to be opensourced? If it has to compete with Android, then i guess it will be GPL'ed.

It seems that Android does not put Swing front-and-center at this stage, and maybe that differentiates Android and JavaFX Mobile in their initial incarnations. Will Java developers have to choose between these two mobile platforms, or will handsets support both JavaFX/Swing and Android? That's hard to imagine, given that JavaFX uses OpenJDK and Android uses Apache Harmony, isn't it?

Credits: The image is a print of "Grandpa's Phone" by Hans Oosterban. One quote is inspired by Homer Simpson's "Oh, so they have Internet on computers now!" Another is a Bushism or two in disguise.

Gooey Table Model

Posted by evanx on October 02, 2007 at 06:33 AM | Permalink | Comments (0)

We introduce a generic table model supporting a list of backing beans, with simplistic "beans binding" facilitated by java.beans.PropertyDescriptor.


Demo

The following demo exercises our table models (and forms).

divvy.png

Launch   (PirateWarez, 150k/500k, unsandboxed, Java6)

Incidently, notice how the selection works, eg. click on the search icon to select the person, and enter a blank product ID to select some booty! ;) Later in this series, we'll look at a popup finder for entities.


Code Snippet

We implement a table model in our application as follows.

public class ProductMovementDetailTableModel extends GTableModel<ProductMovementDetail> {
    ProductMovementDetailInfo info = new ProductMovementDetailInfo();
    
    GTableColumn productId = createColumn(info.productId);
    GTableColumn label = createColumn(info.label);
    GTableColumn productUnit = createColumn(info.productUnit);
    GTableColumn unitCost = createColumn(info.unitCost);
    GTableColumn quantity = createColumn(info.quantity);
    GTableColumn amount = createColumn(info.amount);
    
    public ProductMovementDetailTableModel() {
        super(ProductMovementDetail.class);
        ... // setEditable() on column objects
    }    
}

where we create column objects to contain metadata eg. column headings, types, et cetera.

Each row of the table has a backing bean, eg. ProductMovementDetail in the above example. As presented in the Gooey Beans Info prequel, we define metadata for the bean's properties in a "bean info" object, eg. ProductMovementDetailInfo. The column objects wrap "property info" objects which are created in the bean info class.

A controller is implemented to handle events from the table component, eg. row selection and cell editing. The beans and column objects are used in these event handlers to reference rows and columns.

Disclaimer: This design predates JSR 295 (Beans Binding), which is the future, and so will be presented in future, in this series' 2nd Edition ;)

Incidently, the days of my publishing an article every month in this Foundation series seem to have come to an end, because i've been travelling. Right now i'm in Germany, and from next week i'll be cycling across southern France and northern Spain (woohoo!) without a computer, so um, zero productivity...




what i read about today on the computer internet: OpenProj

Posted by evanx on September 05, 2007 at 10:29 AM | Permalink | Comments (2)

I was excited to read about OpenProj just now. This helps out the opensource desktop by providing an alternative to MsProject, innit.

But i got even more excited when i noticed it's a Java/Swing app, as can be seen from the OpenProj CVS. It's always interesting to invetigate how relatively large and serious Swing apps are cobbled together, and to try to pick up a few tips. So I look forward to checking it out, and maybe writing a blog entry or two, should i be so inspired.

Having said that, i've managed precious little time for anything serious since leaving Cape Town a month ago. I've visited friends and family in Johannesburg, London, and currently Russia. In a couple of weeks, Germany, and thereafter (hopefully) i'll be cycling across South of France, over the Pyrennes, and across Northern Spain!? That's still just a dream that i can't believe might actually happen next month, so...
    I'll be cycling sans my XP notebook obviously, and generally be totally disconnected from anything except my thoughts, which i hope will be centered on the background for a science-fiction book i wish to try to write... Maybe as a blog rather than a book!? Mmmm... crumbled up scifi blog entry thingies...

But i do have a Swing article to finish and publish next week or so, called Gooey Table Model. After that, i'll be under the radar for a month or two...

So has anyone tried out OpenProj? (I haven't cos i'm on an antiquated Windows98 machine right now, with a painfully slow dial-up connection, and no java...)

Hey the other thing that i invetigated today on the computer internet thingymajig was the H2 database. But i'll ramble incoherently about that tomorrow...

Gooey Goals

Posted by evanx on July 26, 2007 at 05:26 AM | Permalink | Comments (1)

So i gave this talk, discussing the following stuff:

  • JSR 296
  • JSR 295
  • Swing - "the State of the Nation" according to um, Me!
  • The Problem with Strings
  • Gooey (my upcoming thingymajig in the near future)
  • Meme (my upcoming thingy in the far distance)
  • Technical writing
  • Opensource

JSRs 295 and 296

I gave an overview of what and where JSR 295 and 296 are, with special emphasis that both have public java.net sites with active mailing lists, where all the excitement is happening, and open to everyone to join the fun, which is "A Very Good Thing" :)

"It's the way of the future, It's the way of the future, It's the way of the future..." (Howard Hughes' character in the Aviator, loosing it.) I used to say that incessantly to my niece to irritate her. Then i left somewhere for three weeks, and returned, lapsing immediately into "It's the way of the future, It's the way of the future..." as soon as she entered my vicinity. Heh heh. No, i hadn't been mumbling it for three weeks! ;)

I suggested that JSR 296 was well scoped to address basic good practice of Swing development, namely Lifecycle, Resource Injection, Actions/Tasks, and Session State.

I suggested that i wasn't sure about JSR 295's scope, because on the one hand it is designed to be "beans binding for everything" ie. to bind one property to another property generically, and on the other hand it is implemented specifically as "beans binding for Swing components." I think it might be layered as such, eg. basic property-to-property beans binding (and groups of bindings), and building a Swing layer on top of that, or next to that, which might reuse/extend some basic interfaces, but otherwise is very specific eg. to JTable et al. I've lost track a little bit there, with all the frenetic activity :)

Swing

I suggested that Swing is onwards and upwards at the moment :)

  • Netbeans is shaping up very nicely, eg. with Matisse, and next up, JSRs 296 and 295 support in Netbeans 6.0.
  • WebStart is a potentially fantastic technology, and hopefully it's shortcomings (eg. scalability, i'm told) will be ironed out, so that it can deliver on its awesome potential.
  • Swing potentially fits in very well with the JEE juggernaut, eg. using WebStart, webservices and/or JPA et al.
  • Consumer JRE, perhaps prompted by JavaFX, will benefit Java/Swing too, and other languages on the platform, eg. Groovy/Swing et al.

Strings

I was banging on as usual about the problem with string references eg. for properties for binding, JPA queries (in strings), component names for resources, et al - they're not toolable as in refactoring, auto-completion...

I suggested that software naturally degrades, and without refactoring, a broken window left unrepaired will lead to a horribly run-down building before very long.

Test coverage is meant to address this ie. to make refactoring feasible. But what about maximum assistance from the IDE, eg. auto-completion et al, when it comes to referencing properties, resources, XML elements, in JPA queries, et al!?

In an ideal world, the language together with the tools will enable totally safe refactoring on one hand, as well as maximum productivity on the other, ie. prompting, auto-completion, and error highlighting. And of course we always want compile-time errors rather than runtime ones eg. caused by unresolved string references.

Gooey

After a year so in development, i'm getting to stage where i want to whip this dodgy framework of mine into some kinda state, to release on gooey.dev.java.net. My goals are to address my requirements as follows ;)

  • A "container for worksheets," ie. a frame with a menu bar, tool bar, status bar, and main tabbed pane, with lifecycle support eg. for launching worksheets as new tabs. (See Framewarez altho out-of-date - Gooey Frame due in coming months.)
  • Simplistic beans binding, as in a "presentation model" approach for forms, and tables. (See Gooey Bean Info et al.)
  • MVC architecture, where Netbeans is used for the View, ie. designing pretty forms, but our controller is the main event, and has no generated uneditable code. (See Gooey Beans Form.)
  • For forms, we use bound "input component adapters" to enable the controller to control components in the View, eg. setEnabled() and what-not, ie. via delegation. These are bound to the Model beans on the one side, and the Swing components on other ie. in the View. (See Gooey Beans Form, and upcoming Gooey Table Model in August.)
  • Support for basic automated layout eg. of beans-bound forms, for rapid prototyping, while fully expecting to switch over to Netbeans' designer at a moment's notice when things get real. (See Gooey Beans Form, and Group Layout Therapy.)

Meme

This will be an experimental ORM using meta entity objects, and entity property objects to reference "tables and columns" for queries, ie. so that entities are refactorable, without fear of breaking queries. (See the Dog House article.)

Technical Writing

I do technical writing as a design exercise. When you write about code, you notice areas for improvement. It's like a self review mechanism, innit. Aiii.

Also writing reinforces my "Simplicity through Multiplicity" principle. The more classes, and the more methods, the better. If it's easier to explain, then it's probably easier to read and understand too.

Opensource

I discussed the difference between the GPL and Apache licenses, and suggested that people license frameworks and such-like under Apache, so that companies can reuse their code, without having to track what they're changing - which potentially makes it impractical to assimilate your framework into their code-base. "If you love something, set it free." ;) It's counter-intuitive that it's best to surrender control, but invariably that turns out to be best option, in hindsight.




Gooey Bean Proxy

Posted by evanx on July 23, 2007 at 06:39 AM | Permalink | Comments (0)

We expose a "presentation model" bean using an interface, used to create a dynamic proxy, with a backing Map of property/values eg. for GUI prototyping, or otherwise a java.bean.


Code Snippet

We expose the properties of the presentation model using an interface as follows.

public interface PersonInfo extends GObservableBean {
    GProperty<String> username();
    GProperty<String> firstNames();
    GProperty<String> lastName();
    GProperty<String> displayName();
    GProperty<String> email();
    GProperty<Date> birthday();
    GProperty<Date> lastLogin();
    GProperty<BigDecimal> score();
    GProperty<PersonTitle> title();
    GProperty<PersonGender> gender();
    GProperty<PersonMaritalStatus> maritalStatus();
}

In this case, we can use "dynamic proxies" (from java.lang.reflect), to access our bean properties, rather than looking them up using string literal references eg. via BeanInfo. Our proxy object will use the Method name to look up the property.

Also, we have the option of not creating a backing bean for starters, which lends itself towards rapid prototyping, since the above property interface is clearly quite concise.




Half Baked Beans

Posted by evanx on July 20, 2007 at 03:37 AM | Permalink | Comments (2)

Let's define a minimal property interface.

public interface Property<V> {
  public void set(V value);
  public V get();   
}

where its implementation wraps a java.bean.PropertyDescriptor.

Now baked beans...

public interface BakedBeanInfo<B> {
  public Property getProperty(String propertyName);
}

where its implementation wraps a java.bean.BeanInfo, and constructs a collection of the bean's Property instances.

Now the trick is we expose our bean/properties as an interface...

public interface PersonInfo {
   Property<String> username();
   Property<String> displayName();
   Property<Integer> age();
   ...
}

where we use dynamic proxies to create a bean, and/or bean info, without worrying about the implementation (eg. QBeanInfo presented in Gooey Bean Info et al).

   PersonInfo personBean = GBeanFactory.createObservable(PersonInfo.class);
   ...
   GTableModel<PersonInfo> tableModel = new GTableModel(PersonInfo.class);
   GForm<PersonInfo> form = new GForm(PersonInfo.class);
   ...
      logger.info(tableModel.getSelected().displayName().get());
      form.set(tableModel.getSelected());      

where we bind to a backing bean instance (eg. Person.class) ie. a POJO/java.bean with accessors/mutators - or not eg. just use the proxy instance as our presentation model.

Lemme repeat... For prototyping, we might not worry about creating a Person.class, but just use the bean info interface to create our observable beans (via dynamic proxy), with built-in PropertyChangeSupport.

Our Property implementation might let us specify (default) presentation properties (eg. label, display width, format et al) of that property, and attach validators, as in Gooey Bean Form.

waddaya think?!

PS. The next installment on Gooey Beans is immiment at last, about JTable's, since i got the demo working, as in the following sneak preview, woohoo! :)

divvy.png

Launch   (PirateWarez , 150k/500k, unsandboxed, Java6)

Notice how the selection works, eg. click on the search icon to select the pirate, and enter a blank booty barcode to select some booty! Later i'll look at a popup finder for entities, rather than switching tabs as it currently works.


Before all that, i'll implement and write an article on the above baked beans, to publish this month in Gooey Beans - and then publish the TableModel article in a coupla of weeks, before i set off on my travels to UK, Russia, Nepal, Ireland et al - Eet's nice... very very frikkin nice! Woohoo! Mmmmm.... Planet Earth...




My usual blah blah blah

Posted by evanx on July 18, 2007 at 01:50 PM | Permalink | Comments (10)

In The future of Windows should be open source, the author suggests that "the desktop is becoming obsolete." This always gets my back up! (If you ever want to get a rise out of me, just say exactly that!) My comment was a regurgitation of what i always say on this subject, which is getting so frikkin boring, that i'm boring myself to tears, but since i wrote such a long comment, i thought i would cut and post it, and here it is again. I know, gutting.

iTunes is a desktop/internet app. Expect to see more such apps, ie. "internet apps" which are also "desktop apps" - that run outside the browser rather than within it. If you think it's possible to implement the rich Office experience using HTML/Ajax... you're stupid, no offense ;) What about an IDE as an ajax web app - ouch!

One can try to emulate desktop apps with web apps, but you'll never get a richer, more responsive user experience, with the same multitude of features - and of course OpenOffice, Kontact et al are improving all the time. And broadband means... click-and-run (and auto-update). Download times are a rapidly diminishing concern...

KDE2.png We have great opensource desktop software like OpenOffice, KDE, GNOME and all their apps - to suggest that we are just going to throw all that away and be left with a single app, the web-browser, as a single full-screen window, with all our apps running inside it, ie. supplant the likes of KDE and GNOME with just Firefox on X, is just silly.

And why even try to supplant great opensource apps with half-baked web apps full of ads?! Rather make the opensource apps like OpenOffice more "webby." Cos why can't apps run outside the browser? Why does everything have to run inside the browser - including Office, email et al - that's just silly!

The web browser (eg. Firefox) will never match the abilities of the OS/desktop (eg. Linux/KDE/GNOME) in terms of managing resources, processes, application windows, eg. tabbing, switching, minimising, exposing, etcetera, etcetera. Why try to turn a cute 5Mb browser into the 100Mb gorilla of a full-blown graphical desktop environment, when the likes of KDE and GNOME exist?

No one will ever again develop a graphical desktop environment, from scratch, that can catch up to KDE and GNOME, or would want to... MacOSX is NextStep legacy underneath, and Windows is also legacy proprietary rubbish underneath.

So to summarise, rather than desktop apps going away, desktop apps will become more leveraging of the internet and leveragable via the internet, eg. launch from the internet, persist settings et al to the internet eg. using REST, ie. be everything that is good about web apps. Desktops apps already auto-update from the internet which you might have noticed, so... onward and upward!

PS. With the advent of internet retailing, eg. amazon.com and the like, people started falling over themselves saying, "This is the future! Bricks-and-mortar retailers will surely all close down!?" Well they didn't. They took what was good about the internet, and added it to what they already had, which was good, and they got better all around. I'll warrant it's gonna be the same with the desktop. Life goes on much as before, just better.

PS. So I think the category "web apps" should make space to include both "browser apps" as well as "webby desktop apps" eg. Webstart Swing apps that use webservices, and not the local filesystem (except for caching and cookies, like a browser).

My checklist for the next year

Posted by evanx on July 14, 2007 at 05:43 AM | Permalink | Comments (4)

Things to Streamline

I recently started writing a Swing feed reader (FeedTrove.dev.java.net) - which i was on my checklist, so that's ticked - but i have still more things to do there...

  • Rather than using an HTML JTextPane, i want to try to render all the stories on a canvas, to get full control, anti-aliased font's, etcetera. Another option would be to use Flyingsaucer, but that is quite big, and quite a few jars which confused me when i wanted to give it a try. Anyway, it's a Swing app, so i guess i should be using Swing graphics rather than XHTML/CSS!?
  • Ditto, for the console. I have an HTML JTextPane console in QuiteGooey - but i wanna try using Swing to render LogRecord's using beautiful fonts and colors and layout. I need this for other Swing apps too, eg. cute RIAs like a chat client...
  • Add more components into the app, like a JTable (showing feeds), and form (with JTextFields et al, for settings and options) - just for the sake of rounding off the framework i'm spinning out of it (called Gooey.dev.java.net, which is an AppFramework-based minimalist rehash of QuiteGooey - which i am also currently refactoring and simplifying on it's own, so all quite confusing, innit?!)

More Swing

Besides a feed reader, i have a few other "small" swing apps i want to write (desperately!)

  • A simple chat client, which may be the beginnings of a Swing-based social network RIA type application?! (Hey, I want to a billionare too! ;)
  • A calendar/reminder "desklet" - a name i'd like to "coin" for Swing desktop apps that are launched from the internet ie. WebStart, and interact with an internet server using REST, rather than the local filesystem - ie. they are "stateless" on the client-side, in the sense that a web-browser is stateless app.
  • A workflow/bug/issuetracking app, like the numerous web-based ones, but in Swing, using REST to backend servlets.

Wheels to Reinvent

Even though i know the future of web development is JEE/JSF/Seam, because it's standardised, i like interesting approaches like Wicket and Echo2, ie. using Java code (rather than XHTML et al) to build user interfaces ie. a hierachal composition of components. So i started a research project (divlet.dev.java.net) to experiment with that. Having done the basics, I still have two or three big issues to solve in my mind and implement in my svn, but no rush.

  1. Composition of pages ie. templating.
  2. Componentisation, eg. flexible, extensible InputText, DataTable components.

Things to Finish

The "Gooey Beans" series on aptframework.dev.java.net has temporarily stalled because of two many things on my plate! But i want finish that off in the next few months - with an article per month - including this month! So I got back into it this week, after a few months' neglect. Actually it'll never be finished, but i want to solve some "big" remaining issues for me...

  1. data bean bound JTable's
  2. Componentisation of lookup fields, eg. for entering/finding persistent entities, eg. using a combination of a JTextField, "search by..." dropdown, maybe high-volume auto-completing JComboBox and/or popup JTable et al for high-volume multi-column scanning, with JLabel to display the selected entity after all that, all as one "field" eg. PersonFinderField, to plop onto all your forms were a Person has to be specified, and use as a JTable cell editor, and similarly for every entity you have!

Also "outstanding" but much less of a priority for me is "Hyper Beans," where i want to address describing a printable/viewable document using java code (rather than XML), in order to produce HTML, Excel and/or PDF output - using iText and Apache POI. And after that, ODF. This is for business "documents and reports" eg. invoices and such, and also the results of database queries and such, innit.

In the "Jelly Beans" series, i got so many things i want to do, i won't even start! OK, i'll list some of them quickly....

  • write about JPA (which i've eventually starting using in the past few weeks for a JEE/JSF/Seam web project)
  • build a transactional REST server servlet backend framework for (my) Swing client applications
  • implement a new experimental ORM, and using property "objects" rather than annotations, to enable native queries, ie. no strings attached, as in the previous blog entry
  • implement an in-memory engine for the above, ala Prevayler

un-Java-ish Things to Do

  • Visit friends and family in UK, Ireland, and Russia.
  • Cycle from Dublin to Cork, via counties Wicklow (beautiful mountains), Carlow (visiting a friend), Laiose (my relatives). I might then cycle up the West Coast to Galway! I've done much of these routes on two earlier occassions, and want to do it again!
  • Trek in the Annapurna in Nepal, and visit Tibet.
  • Cycle from South of France, over the Pyrennes, taking the French Way of St James, a traditional pilgrimage across Northern Spain. (Very overdue!)

Now that my goals are set, i begin the task of trying to achieve them innit! But before i start, it's time for me to cycle around Cape Point, for the third time this week, it's nice! Which reminds me, my other blog is called "Getting Fit, Aiii".

Because, yes it's true, i'm not really a Java professional. Actually right now, I'm trying desperately to break into the fitness instructing field - much less deadlines and zero stress - and you get to exercise while you work!

The position i'm applying for (spinning instructor), requires you to "work" zero or otherwise 45 minutes a day, yeah baby, yeah! And you are encouraged to shout out things like "yeah baby yeah" at the top of your voice every minute or two, which is another perk! ;)

The other seven hours of the day... Actually I would like to be building a real Swing app for real people, using Netbeans 6.0, AppFramework (not aptframework), WebServices and/or JPA - so gimme a bell if you got simple requirements and plenty of bucks!

Chronicles of the Trove: Fixing by Deprefixing

Posted by evanx on June 17, 2007 at 07:42 AM | Permalink | Comments (1)

I have one very simple rule for design, namely to create as many classes as possible! Let's name this "Evan's Rule of Simplicity by Multiplicity."

So I just noticed a simple cue to refactor out a class. Consider the following GUI construction.

public class MainView {
    JTabbedPane mainTabbedPane = new JTabbedPane();
    ...
    DefaultMutableTreeNode categoryRootTreeNode = new DefaultMutableTreeNode(new CheckBoxModel("All", false));
    DefaultTreeModel categoryTreeModel = new DefaultTreeModel(categoryRootTreeNode);
    JTree categoryTree  = new JTree(categoryTreeModel);    
    ...    
    public MainView() {
        categoryTree.setEditable(true);    
        ...
    }
    ...
}    

You see we have a few related components categoryTree, categoryTreeModel and categoryRootTreeNode. They all start with the same prefix ie. category, so as to distinguish them from other trees.

So the clue is when seeing such prefixes, refactor them out to a class so as to "de-prefix" them, as follows.

public class CategoryTreeView {    
    DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode(new CheckBoxModel("All", false));
    DefaultTreeModel treeModel = new DefaultTreeModel(rootTreeNode);
    JTree tree  = new JTree(treeModel);
    
    Map<Category, DefaultMutableTreeNode> treeNodeMap = new HashMap();
    Map<Feed, DefaultMutableTreeNode> feedTreeNodeMap = new HashMap();
    
    TreeCellRenderer renderer = new CheckBoxTreeCellRenderer();
    CheckBoxTreeCellEditor editor = new CheckBoxTreeCellEditor();
    ...
    public CategoryTreeView() {
        tree.setEditable(true);
        ...
    }        
    ...
}    

So let's name this "Evan's Rule of Fixing by Deprefixing."

A further step might be refactoring this to extend something eg. JTree or DefaultTreeModel, rather than being a composition.

We hook up that class, to a now simpler MainView.

public class MainView {    
    JTabbedPane mainTabbedPane = new JTabbedPane();
    ...
    CategoryTreeView categoryTreeView = new CategoryTreeView();
    ...        
    public MainView() {
        ...
    }
    ...
}    

So our increasingly complex system progressively devolves to a collection of increasingly simple classes. It's nice!

PS. Here is (another) sneak preview of this feed reader toy that's been distracting me of late, and the actual reason i wrote this blog entry, ie. as an excuse for this postscript, as will be the case with all entries in this series - I know, gutting.

PPS. That's from The Office when David Brent says, "Well, there's good news and bad news. The bad news is that Neil will be taking over both branches, and some of you will lose your jobs. Those of you who are kept on will have to relocate to Swindon, if you wanna stay. I know, gutting. On a more positive note, the good news is, I've been promoted, so... every cloud... You're still thinking about the bad news aren't you?"

Launch   (FeedTrove, 1M/350k, unsandboxed, Java6)

There seems to be the odd GUI feeze-up but i don't know why!? I'm doing every GUI-ish thing on the EDT as far as i can see. Personally i suspect JEditorPane! ;) Anyway, one can dispose the frame into the system tray, and pop it up again.




Chronicles of the Trough: Sneak Preview

Posted by evanx on June 07, 2007 at 01:18 AM | Permalink | Comments (4)

Here is a sneak preview of a trivial feed reader app using the Java6 SystemTray. It checks a few preconfigured (Java) feeds every 10 minutes, popping up a message when a new article is spotted.

Launch   (FeedTray, 1M/250k, unsandboxed, Java6)

The feedtray app itself is small (18k using pack200), but depends on ROME and AppFramework and their dependencies ie. jDOM and SwingWorker, so the total packed size is around 250k, and unpacked, well... much more!

Note that when you minimise or close the window, the frame is disposed, but the app still runs in the SystemTray. You have to right-click on the TrayIcon and choose "Exit" to exit the app and dispose its JVM instance.


Resources

You can browse the code for this exercise at feedtray.dev.java.net.
See the classes FeedTrayApplication (and it's resource file), FeedSystemTray, FeedManager, FeedReader.

FeedTray requires rome.dev.java.net (which requires jdom.org),
and AppFramework.dev.java.net (which requires swing-worker ie. org.jdesktop.SwingWorker).

Also see "New System Tray Functionality in Java SE 6," on the Sun Developer Network,
and "Displaying messages in the system tray," by Michael Nascimento Santos.




Splash Screen

Posted by evanx on April 25, 2007 at 01:44 AM | Permalink | Comments (0)

If it's gonna take a while to start up our Swing app, then we probably wanna display a splash screen.

It's easy with Java6 - just add a -splash command-line option.



Code Snippet

We initialise a SplashScreen instance and get its Graphics2D as follows.

public class SplashTest {
    static Logger logger = Logger.getLogger(SplashTest.class.getSimpleName());
    final SplashScreen splash = SplashScreen.getSplashScreen();
    Rectangle splashBounds;
    Graphics2D splashGraphics;
    
    protected void initSplash() throws Exception {
        if (splash == null) {
            throw new Exception("no splash image specified eg. -splash:mysplash.png");
        }
        splashBounds = splash.getBounds();
        splashGraphics = (Graphics2D) splash.createGraphics();
        ...
    }
    
    protected void updateSplash(String status, int progress) {
        if (splash == null) return;
        drawSplash(splashGraphics, status, progress);
        splash.update();
    }
    ...
}    

where in drawSplash() we draw a progress bar ourselves over the splash image using the Graphics2D instance.




Screen Capture

Posted by evanx on March 28, 2007 at 06:52 AM | Permalink | Comments (6)

For documentation purposes (and perhaps remote support), we need snapshot images of our application. So let's build such support directly into our application itself.


Code Snippets

We can capture whole desktop, and save it to a PNG file, as follows.

    public void captureScreen(String fileName) throws Exception {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = new Robot().createScreenCapture(new Rectangle(screenSize));
        ImageIO.write(image, "png", new File(fileName));
    }

Alternatively, we might capture our JFrame, including its window decoration, as follows.

    public void captureFrame(JFrame frame, String fileName) throws Exception {
        BufferedImage image = new Robot().createScreenCapture(frame.getBounds());
        ImageIO.write(image, "png", new File(fileName));
    }




Interview with Mono's Miguel de Icaza

Posted by evanx on March 26, 2007 at 04:47 AM | Permalink | Comments (9)

i was just reading an interview with Miguel de Icaza, creator of Mono.

He mentions their "Mono Migration Analyzer" tool for users to see the coverage for their (Windows) .NET apps. They collect automated reports generated by this tool to see what features of Mono are missing for most real world applications in the wild, and this is used to prioritise Mono development. He mentions they expect to support 50% of current applications with some minor incremental updates, and Novell is staffing up the Mono team for a big push.

Mono 2.0 will support ASP.NET 2.0, but Windows.Forms 2.0 will come later. (When is Mono 2.0 scheduled?)

On the opensourcing of Java, he says Mono is targeting the .NET crowd who are typically not using Java, for migration of .NET apps to Linux, so it doesn't impact them. But naturally it will make Java more ubiquitous in the opensource space.

He suggests that for desktop applications, Java still has to address its memory usage limitations. (Don't other high-level runtimes like .NET and Mono also have relatively high memory usage compared to native C/C++ apps? I thought this was the trade-off for easing development.)

He doesn't seem to like WPF. Although it has some great elements to it, it has some "ugly" ones too, he says. For now they are focussing on Windows.Forms, because people have adopted that in droves, whereas WPF is too new, so not used much yet. (How do these GUI toolkits compare to Swing?)

PS. If Netbeans supported Mono, and automatically converted the uppercase method names to lowercase ones, then i'd give it a try ;) That is, if Windows.Forms compares favourably with Swing?

Google vs the OpenSource Desktop

Posted by evanx on March 24, 2007 at 03:47 AM | Permalink | Comments (0)

i was just reading a blog "Google Hasn’t Improved Search" (to kill some time before the South Africa vs Australia cricket match starts shortly). The author says,

Whenever they release a new product, it does nothing to improve the existing search offering. Whenever they do something to change the existing search offering, it's a minor layout move. Whenever there's a new product in labs, it's no longer outlandish, it doesn't make me think and again; is no improvement or change to their core offering: SEARCH.

I agreed and added the following ranting comment about Google, which i repeat below.

But enough about you, let's talk about me, what i think

Google don't seem to have a cohesive plan except to hire anyone who's anyone, away from other companies who need them eg. Sun et al, for what purpose? To take over the information world, to displace and replace everyone else? It doesn't feel right.

Rather than leverage and contribute to opensource projects such as Thunderbird and OpenOffice, to web-enable those as stateless RIAs or something, they develop web-based apps for mail, calendaring and docs which are relatively poor in terms of usability and features compared to the opensource desktop equivalents. But at least the web apps have ads! ;)

Why don't they use Thunderbird/XUL for gmail? Why not add "G-drive" integration to OpenOffice? And throw in ads somewhere to pay for it.

So i think they are taking the industry backwards with their "web-browser-hobbled desktop knock-offs" when they could be driving the whole rich opensource desktop forward to leverage their internet infrastructure, and not just the browser.

But enough about my thoughts, let's talk about my plans

It looks like i'm back on the road again. Every six months to a year, i decide to switch locations from Johannesburg and Cape Town or visa versa, and it seems that time has come again.

I'm gonna be spending the next few months flitting around the country between Johannesburg, Durban and Cape Town, visiting various family and friends, with my two notebooks and my backpack. One "notebook" is a computer with GSM 3G connection, so i'm good to go. My other very important notebook is paper-based. Cos I find the best way to design software i want to write, is in a coffee shop with pen and paper and a double cappucino or three.

After i've overstayed my welcome and exhausted the hospitality of my family and friends once again, i'm thinking of heading over to Europe and getting a job like my mom says i should. I'm justing waiting for Netbeans6 with its minty goodies like JSR295, JSR296, JPA... Ooo, what a good time to reenter to job market! :)



Tipsy Snipsy: Forward Focus Traversal

Posted by evanx on March 15, 2007 at 04:59 AM | Permalink | Comments (5)

As you've noticed, when you press Enter on fields like JTextField et al, an ActionEvent is generated, and focus is not transferred to the next field in the focus cycle.

But what if you are not interested in ActionEvent's on fields, and would rather Enter have the same effect as Tab, maybe because your users are used to having to enter data with the Enter key?

    protected void setDefaultFocusTraversalKeys() {
        Set set = new HashSet(
                KeyboardFocusManager.getCurrentKeyboardFocusManager().
                getDefaultFocusTraversalKeys(
                KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
        set.add(KeyStroke.getKeyStroke("ENTER"));
        KeyboardFocusManager.getCurrentKeyboardFocusManager().
                setDefaultFocusTraversalKeys(
                KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set);
    }   

But then we aint gonna get those ActionEvent's no more, which may or may not be a problem.


References

Setting Focus Traversal Keys for the Entire Application on JavaAlmanac.com.

Using the Swing Focus Subsystem on the Java Tutorial.




System Properties

Posted by evanx on March 01, 2007 at 07:25 AM | Permalink | Comments (0)

Let's use reflection to set a bunch of configurable values via the command-line using "system properties."


Code Snippet

We put our configurable properties into a separate object, specifying the default values, as follows.

public class CommandoDemoProperties {    
    public String host = "aptframework.net";
    public int port = 80;
    public int sslPort = 443;
    public boolean useSSL = true;    
    public String clientKeyStoreFileName = "keystores/client.private";    
    public String serverKeyStoreFileName = "keystores/server.public";    
    ...
}    

We create the following helper to inject any command-line parameters via reflection, according to the field names, eg. -Dport=8080.

public class QSystemPropertyHelper {
    ...
    protected void injectSystemProperties(Object properties) 
    throws IllegalAccessException {
        for (Field field : properties.getClass().getFields()) {
            Class type = field.getType();
            String key = field.getName();
            Object defaultValue = field.get(properties);
            Object value = defaultValue;
            String string = System.getProperty(key);
            if (string == null) continue;
            if (type == String.class) {
                value = string;
            } else if (type == Integer.class || type == int.class) {
                value = Integer.getInteger(key);
            } else if (type == Boolean.class || type == boolean.class) {
                value = Boolean.getBoolean(key);
            } else {
                logger.warning(key, type);
            }
            if (value != defaultValue) {
                field.set(properties, value);
            }
        }
    }    
}

where we support properties which are strings, integers or boolean values.




Dumbed Down WWW

Posted by evanx on February 24, 2007 at 11:26 PM | Permalink | Comments (4)

The "Google Operating System" blog entry "Google Docs & Spreadsheets vs Microsoft Office" quotes a Writely post as follows.

"One of the reasons the web is so nice is that the page UI is simple... a few things at a time, a very easy metaphor, etc. It passes the 'mom' test - I can usually just tell my mom to go to a site, and she usually can figure it out. I can't remember the last time I could do that with a desktop app. So, even though the windows desktop is 'richer', it's not necessarily better."

grannybehind.JPG My translation of that is, "Let's dumb down this whole computer software thing because people don't know how to use computers."

My mom is 60 year old granny who has been working on a Linux desktop, using OpenOffice, Thunderbird and Firefox every day for years. Prior to that she used a Win95 computer for email and browsing BBC's Food website, when she was housekeeper and cook in the UK, for Richard Branson's parents, actually :)

OK, she didn't setup her Linux desktop herself - my brother did it for her. Well, I don't service my car myself, does that mean i shouldn't be driving a car?! Well in that case, if i was limited to riding a donkey, I'd name it Ajax ;)

So that blog tries to imply that the browser is the web, as in collaboration, contextual search and what-not. Shame, maybe they haven't heard of Webservices, which can be consumed by Java RIAs, which can be launched from the browser using WebStart?

It's time to start thinking beyond the "browser is the web" paradigm, because the web can be so much more than the browser! In future, our favourite opensource desktop apps like OpenOffice, Firefox and Thunderbird, might get web-enabled and transformed into caching, stateless web clients, eg. using Amazon S3 for storage, and mashing up a bunch of other webservices.

But some people believe the web should be so much less than the desktop, dumbed down to the lowest common denominator. When their vested interest is around web ads, can we expect otherwise?

By the time they figure out that ultimately people want more than that, and are better at using computers than they than give them credit for, maybe they'll be classic victims of the Innovator's Dilemma.

Gooey Event Hub

Posted by evanx on February 16, 2007 at 08:36 AM | Permalink | Comments (6)

Gooey Event Hub

We implement a event listener list singleton supporting weak references. Then we can add listeners to an object we wish to observe, and fire events to its observers, without implementing any such support in the observed objects eg. addListener(), removeListener(), fireEvent(). We can choose to fire an event in a background SwingWorker thread, or in the EDT eg. using invokeLater() or invokeAndWait(). So we might use this event hub as a basic event/message bus.



Code Snippet

We create BackgroundEvent and UpdateGuiEvent classes to enable some EDT switching as follows.

    public EventHubDemo() {
        ...
    public void actionPerformed(ActionEvent event) {
        if (checkForNewMessagesAction.equalsActionCommand(event)) {
           checkForNewMessagesAction.setEnabled(false);
           eventHub.fireEventInBackground(new BackgroundEvent(this, event));
        } ...
    }
    
    protected void doInBackground(ActionEvent event, JProgressBar progressBar) {
        if (checkForNewMessagesAction.equalsActionCommand(event)) {
           try {
              ...
              eventHub.fireEventAndWait(new UpdateGuiEvent(this, event));
           } catch (Exception e) {
              eventHub.fireEventAndWait(new ExceptionEvent(this, event, e));
           }
        } ...
    } 

where we wish to handle checkForNewMessagesAction in a background SwingWorker thread, and once completed, switch back into the EDT to update the GUI.


Demo

Launch   (EventHub, 150k/500k, unsandboxed, Java6)




Bound Gooey Beans

Posted by evanx on February 05, 2007 at 03:07 AM | Permalink | Comments (0)

Bound Gooey Beans

In the Gooey Beans Info prequel, we explicitly declare properties. Now we allow a bean info instance to be bound to a specific bean, in order to support bound properties ie. firing PropertyChangeEvent's.


Code Snippet

In our bean, we instantiate a bound bean info class with PropertyChangeSupport as follows.

public class BakedBean {
    public final BakedBeanInfo info = new BakedBeanInfo(this);
    
    private BigInteger barcode;
    private String label;
    private Integer bakingTemparature;
    private BigDecimal medianLength;
    ...   
    public BakedBean() {
    }
    ...
    public void setBarcode(BigInteger barcode) {
        this.barcode = barcode;
        info.barcode.firePropertyChanged(barcode);
    }
}

where we use property "literals" from our bean info to firePropertyChanged().

We can add PropertyChangeListener's as follows.

public class BakedBeanDemo implements PropertyChangeListener, Runnable {
    BakedBean bean = new BakedBean();
    ...
    public BakedBeanDemo() {
        ...
        bean.info.getPropertyChangeSupport().addPropertyChangeListener(this);
    }
    ...    
}   

bakedBeansDemo




Unhybridising RIA development with Swing

Posted by evanx on February 02, 2007 at 11:28 AM | Permalink | Comments (26)

Our editor highlights Bruce Eckel's Hydridizing Java.

nasa What i don't like about web development is hydridization, ie. Java/JScript/HTML/CSS. I think having to program and integrate multiple hetergeneous languages with relatively limited IDE support, is distracting. Another common ubiquitous example is Java/SQL, mitigated by JDO, JPA et al. Having said that, i love HTML/CSS and SQL, and enjoy representing these as Java objects to leverage my IDE.

The timing for Java (applets) for internet clients for Web 1.0 was too early. The bandwidth, RAM and CPU of the common users and their PCs were insufficient for anything other than a browser rending HTML. Naturally this led to the current popular technologies eg. PHP, AJAX, server-side Java, which leverage HTML/browsers. Of course the efforts of Sun et al followed the money to the server-side.

However, with megabits of broadband, gigs of RAM, and multicore multigigahertz processing becoming the norm, I contend that events are shaping up for Swing to live up to its potential as a serious candidate for Web 3.0, with Netbeans as one of its many allies. 50megs in the scheme of 2gigs is not relevant, and multi-megabyte WebStart downloads via multi-megabit broadband is worth a few second's wait for a killer application you use regularly.

Java/Swing/Netbeans potentially allows developers to deliver RIA and desktop functionality with rapid ease. There are engineering problems to be solved (and killer applications to be developed). But fortunately there are lots of engineers, not least ourselves. And it's opensource, so... Let's do this! :)

Gooey Bean Aspect

Posted by evanx on January 15, 2007 at 06:36 AM | Permalink | Comments (4)

Gooey Bean Aspect

We use CGLIB to enhance a half-baked Java Bean with no firePropertyChange() invocations in its setters, into a bean that does fire PropertyChangeEvent's from its setters.


Code Snippet

Our QBeanInterceptor registers the PropertyDescriptor's setters methods into a setterMap.

public class QBeanInterceptor extends QInterceptor {
    BeanInfo beanInfo;
    Map<Method, PropertyDescriptor> setterMap = new HashMap();
    BeanPropertySupport beanAnnotation;
    boolean fireByDefault;
    ...
    public Object invoke(Object target, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        Object oldValue = null;
        Object newValue = null;
        PropertyDescriptor propertyDescriptor = null;
        if (args.length == 1 && fireAtWill(method)) {
            newValue = args[0];
            propertyDescriptor = setterMap.get(method);
            if (propertyDescriptor != null) {
                oldValue = getOldValue(target, propertyDescriptor);
            }
        }
        Object result = super.invoke(target, method, args, proxy);
        if (propertyDescriptor != null) {
            QBean bean = (QBean) target;
            bean.getPropertyChangeSupport().firePropertyChange(
                    propertyDescriptor.getName(), oldValue, newValue);
        }
        return result;
    }
    ...
}    

where if the method is a key to an associated PropertyDescriptor in setterMap, then we invoke firePropertyChange() to fire a PropertyChangeEvent.


Demo

Here is a trivial demo that is hardly worth downloading. And it's quite large, because it depends on a CGLIB jar.

Launch   (BeanAspectDemo, 250k/850k, unsandb