Main

Java Archives

September 30, 2002

My First AspectJ Experience

Even though this is happend about a month ago I just started my blog today so it seems like a good enough topic to do a log entry about.  Let's just say AOP (and AspectJ as the tool) is really kewl.

At my job one of my tasks is to write a GUI to do the editing of some rather complex configurations.  So naturally I had written up my own meta data to do this (more later).  One of the problem I had was that on some of the screens the code I had written to do the layout were sucking up a lot of time just to do the layout of what should be some eimple pages (and even longer for some pages that were not so simple).  While at the same time some of the larger pages were just fine.  

So how does one go about debugging this?  I suppose I could sync up the model in UML and look at the collaboration diagrams, the problem is when you get much past the high level operations UML begins to look like a first gade scribble fest, and that is before you turn on the auto-formatting.  (Perhaps a subject for another future entry about how some things should be left out of UML diagrams because they just clutter things up).  I guess since I wrote this code I should know what was wrong.  But let's face it, nobody outside of training exercises intentionally writes O(exp) code (which is what it was behaving like).  

As it turned out about two weeks earlier I had picked up a book Aspect Oriented Programming with AspectJ while my wife and I were killing time before a Friday Night Movie.  So I decided to try applying the profiling aspect to my layout code (but totally hacked up to get the stats I needed).  All I have to say is that it was incredably cool.  To get the sort of stats I was getting confirmed that it was exponential process: one method was being called 2 million times on my CPU killer test, 16K, 33K and 66K on my check it at each step test as well.  Almost a perfect 2^n cost of computing.  But what schocked me was what was causing those huge jumps... a property listener.  I was re-calculating parts of the layout in response to the addition of a layout element, which was causing other items of the tree to be re-calulated for each addition.  Being basically a binary tree the size growth makes sence as I add one more item.  Without this knowledge I would in all likelyhood be re-writing that code today.

So anyway what I thought was the coolest was that all of this diagnostic code was dropped at every method invocation in my select classes for the areas I was worried about.  It truly was a seperation of concern because I usually do not care how often a method is called or how long it takes.  But when I care I really care.  And applying a 30 line aspect to 15 some odd classes and loading it into MS Access so I can do some SQL queries is a whole lot easier than insturmenting it by hand.

October 4, 2002

Developer Testing

I was going to write a big old rant about developers who refuse to test their code or feel it is QA job or who feel that we need to hire someone to write these junit tests. But it would have been a pointless and long vent that went no where. So let me just say that I am a big advocate of the apporach that XP has to Testing. not jus thte unit test everrything but the whole additude that the developer is the principal responsable agent to chatch bugs. They cannot catch everything, so you have QA people to help there (but QAs real job IMHO should be to test things like scaleability, durability and non-happy-path items the developers tend to developed blinders for, not test-script monkeys). A Developer who doesn't test their code is like a gun without a saftey: an accident waiting to happen.

So waht brought this on? Well testing one's on code can brign greate peace of mind. I am mantianing and expanding on some code that I inherited after a layoff when the previous owner got re-assignemd. Some code changes can have effects across thousands of generated xml files when I intendede them to have effects in a few. To combat this I use a set of validation programs to make sure that all of the XML is internally consistant with what I expect and a diff tool to diff it against a previous know good generation. It is a load off of my shoulders when I can run it agianst the 4,000 some odd generated XML files and find out that, yep, only the 40 files I ment to meddele with were indeed the only ones that got changed. Which reduces the number of files I need to examine by hand 1000 fold.

Testing increases quality and saves time and money. And I sure am liking the saves time part right about now.

October 14, 2002

JView Swing Suprise

Color me suprised! I downloaded Swing 1.1.1 from the java web site and ran it against Microsoft's JView program, and my splash stuff worked with only Java 1.1 level tweaking! I also ran the SwingSet test and was suprised that the performance was fine! (1Ghz and 512MB of ram may have figured intot that however...)

The upshot of this is twofold: first I will be able to comply with the Apache Ant Task Design Guidelines and write the Inform.ant portions to conform to Java 1.1. Second is that Inst.ant can be writting to run on a "stock" Windows machine without having to got to an AWT parallel solution. Just include the classes in swingall.jar and you are good to go. So the odds of seeing a SWT version also fell to near zero as well since I won't be plugging anything but console and GUI, where GUI means swing. Being able to run on JView was the whole point of designing with multiple GUIs in mind, so now I can go with a "write once, debug many times" solution.

October 16, 2002

Response: Rickard's AOP thoughts

Rickard posted some thoughts on AOP and I must say it is amazing how some of those items could be done in non-java without the pre-processors (thought not in the same language). To me AOP is just like OOP and structured programming before it: principally a practice. It is also a practice that is re-enforced and simplified by language constructs.

(However I would like to say that EJB is an example of seperation of concers; as long as what you are concerned about what EJBs are concerned about.)

Here goes. AOP, to me, is two things: first, you get to pick objects apart into smaller parts each of which has a nice clearly defined purpose. These parts can then be assembled to form big objects. [ Random Thoughts ]

As you go on to read further what started registering in my head was *hushed*tone* Multiple Inheritance *gasp*. What it is closer to however, is the OOP pattern composition. I haven't seen this achieved that often except in rather brittle examples. When you think about it though composition is a OOP way to achieve separation of concerns. It was the casting example that made me jump out and say that it can also be accomplished via multiple inheritance. But in that case you lose the possibility of composing the object of sub-classes of the pieces, like a V-8 engine for a Denali v.s. a 3-cylinder for a Geo Metro. At a cursory glacne it appears that using AOP to gain this type of composition also suffers from this flaw. What if I want Unix type User-Group-Other ACLs on some and NTFS every-possible-permutation style ACLs on other objects? You could flatten out the classes and make two ACL type. But this false when that choice varies not based on type of object but arbitrarily per object. For example: some pages kept on client A's extfx system and some on client B's NTFS but both aggregated in the same place. That's why I don't see how (ACL)page has any intrinsic value (other than aesthetics) over page.getACL(), in fact it seems that the latter is better in that sense.

However, this is a red herring over what AOP is providing, in that when following the principals of AOP you can do either to achieve composition. What is important is that you don't litter the ACL code special cases in with the other items and keep ACL code i the ACL. It seems to me that if you cannot keep ACL code in one place perhaps the concerns are not separated properly or they are not separable. Keeping the concerns separated is alot easier when the language and framework are designed with separation of concerns in mind.

Second, AOP is also about what most people would call "interceptors". That is, doing stuff before and after a method call on an object. [ Random Thoughts ]

What came to my mind from this paragraph is function pointers, or as Microsoft calls them toady delegates. Also C macros are quite crafty in that regard. For function pointers you could write a method to do the work around the method and then call the other method, and store it with the other method. But to do it arbitrarily to arbitrary code you would need (1) to make all function call through pointers and (2) some place to store what the previous function was. To accomplish 2 you would need to pass some overhead like a pointer to a stack of methods to know what the next one is, which is exactly what AspectJ and what Rickard's code example do.

It is crucial to remember here that while the object being referenced in client code may implement 10 interfaces, there is no class (beyond the dynamic proxy class) that actually implements all of those. They only implement one interface, and the AOP framework takes care of the routing from this big happy I-got-it-all "object" to these smaller objects. All of that is transparent to the developer though. [ Random Thoughts ]

One object that can accept any message... hmm... doesn't SmallTalk allow any message to be sent to any other object? Seems to me more and more AOP languages are talking the shiniest pieces of other languages and making them their own. Sure you could do it in C, but you wouldn't want to since void * is a great way to fumble the memory heap.

This feels like going through the candy store and throwing out the blue SweetTarts, M&Ms with peanuts, and anything made with dark chocolate. How can anyone like dark chocolate?

October 20, 2002

Productivity is the name of the game

Last night while I was starting to write some of the GUI code for inst.ant I initially tried to code it all by hand, to be as IDE agnostic as possible. However I came to the (not so quick) conclusion that coding guis by hand sucks. So after a brief struggle with my ReplayTV I came back and fired up the GUI editor on NetBeans 3.4 and within half an hour was a lot longer along than I had been all night with coding by hand. After a little more work today I've got some more of the frame working like I want it, and I feel it would have taken me two to five time as long as by hand. The downside of this is that some of the generation stuff is going to wind up in the CVS tree. But after getting so much done I don't care as much as I used to.

It's not that I am a neanderthal and feel that machine generated code is the spawn of the devil. At my paying job I use the NetBeans GUI designer any time I do GUI work. But since the only other guy doing UI coding comes from a MFC background machine generated code is not a problem for him (as long as it comes from a wizard). And if any of the other people I work with have a problem with it (which they haven't yet ) I would just say that "If you want it done your way then you better do it yourself." and laugh as they work self-inflicted 80 hour weeks. Back in the day when GUI meant AWT I would always code my GUIs by hand, but that is because back then GUI editors sucked real bad.

It's amazing though how ingrained the feeling of "if it's not hard I am not really coding" can be sometimes. It makes me remember the time I was in Chemistry class arguing with one of my friends at the time the merits of high level languages over assembly (I was on the side of C++, this was pre-java). He just wasn't getting that time==money, and argued that you could do anything with assembly that could be done in any higher level language because it gets compiled to that anyway, so why not jsut start with assembly? He also had a hard time grasping the concept of showering daily to impress chicks.

But once the light bulb turns on it can become a blinding searchlight. A little less than a year ago a Windows consultant realized that "The power of Java (and therefore the power of .NET) is that it provides a major productivity boost for the programmer." (He directs the rest of the blog entry at dot net granting the same power). A coherent toolkit for the right problem can be like dynamite is to mining ore. Yes you could use a pick axe to build a tunnel, but if you had dynamite you could safely use you wouldn't want to.

(edited after a good nights sleep for comprehension)

October 22, 2002

AOP and polymorphism again

It looks like my ramblings have been noticed. A post where I was discussing how several AOP patterns could be done in non-AOP frameworks and languages (much like OOP and non-OOP) was responded to in a fashion of "My AOP is not like that! AOP is the second third fourth coming of High Level Language Nirvana!" Ok, it really wasn't that extreme but it was really fun writing and editing the last sentence. However I do feel that some of my comments were misunderstood in the response.

Rickard's response focuses entirely on my composition comments, first starting with my analogy of the Denali and the Geo Metro.

When you think about it though composition is a OOP way to achieve separation of concerns. It was the casting example that made me jump out and say that it can also be accomplished via multiple inheritance. But in that case you lose the possibility of composing the object of sub-classes of the pieces, like a V-8 engine for a Denali v.s. a 3-cylinder for a Geo Metro. At a cursory glance it appears that using AOP to gain this type of composition also suffers from this flaw.
It doesn't, not in my framework anyway. You can either specify a default implementation for an interface, or you can specify that a particular implementation of an interface is to be used in a specific composition. This accomplishes what is outlined above. [ Random Thoughts ]

My analogy wasn't perfect, although it serves some purpose. A better example may be a Saturn VUE. You can get one with a 4 cylinder or V6, and you can get 4WD or AWD. A few sentences after the quote rickard had I mentioned that this can be solved by flattening out the hierarchy, as Saturn does. All four possible compositions have their own class. At this level the combinatorics aren't that bad. Now let's consider that each car can have any of 3 stereo systems, 2 interior colors, 7 exterior colors, and about 5 other options. 2*2*3*2*7*2*2*2*2*2=5376 possible ways to have your saturn. Now what if we added a third type of braking system (Anti-Injury Inertial Dampening Brakes)? One of those 2's become a 3 and we need over 2000 more ways a car can exist, and creating one class per car type is expensive in the hierarchy alone!This is what I meant from flattening the hierarchy. (Full disclosure: we are 2 Saturn family, but don't own a VUE.)

Having not seen Rickard's code, I cannot be sure if he is creating a concrete class for each combination, but there are two possibilities I see from reading his posts. The first is that he is only creating the 10 particular concrete instances he would use out of the huge combination space. Which is fine if you can statically prove that those 10 would fit your needs. The second is that he is storing them and the class is actually a proxy, and the cast to (ACL) is casting to a proxy that forwards all requests to the concrete class. Instead of writing or dynamically generating that big old proxy class why not just write one interface ACLable with one method, getACL()?

Neeext.
What if I want Unix type User-Group-Other ACLs on some and NTFS every-possible-permutation style ACLs on other objects? You could flatten out the classes and make two ACL type. But this false when that choice varies not based on type of object but arbitrarily per object.
I don't think that is very realistic. What is realistic is that a bunch of objects in a system are somehow similar and have the same way of handling the ACL interface. [ [ Random Thoughts ]

It wasn't the realism I was trying to address with this example, which was not about how the files are stored but about the ACL itself. In the next section Rickard describes how he solves this is to flatten the hierarchy into 3 cases, which is what I described as well more or less. I could find a more realistic example but apparently they are not in your system. I was trying to describe a composition that was not binary (ACL v.s. no ACL) but had more complexity, in this case trinary (Unix ACL, NTFS ACL, no ACL). The fact that the example dealt with file systems and storage was what was focused on rather than the implications of the different ACL schemes that they have. Both can validate create, read, update, delete permissions but have wildly different ways of coming to those decisions and different data sets to draw from. But this seems to be more the realm on the Strategy Pattern that the Composition pattern, which is another design pattern that can use and abuse polymorphism and late binding. Objects requiring arbitrarily changeable components may not be the case in your system, but when you really need them you really need them.

Well, I really need to get work done today.

October 29, 2002

Eclipse and Ant

If you use Ant with Eclipse , you might want to check out these two new plugins Antview and Planty.

The Eclipse folks liked both these tools so much, they've asked the author if the would consider donating them to the project. It looks like Antview's author has accepted, so the next release 2.1 will include some or all of AntView [ A cup of joe ]

I may have to actually look at eclipse again. Support for ant like what they had in the screenshot was my #1 complaint about it. Now if they just had keyboard shortcut re-mapping.....

October 31, 2002

Loads of Ant 1.5 Goodness

At my work we finally got around to getting Ant 1.5 into the build process and taking advantage of the new features, which are just what we need. As a co-worker said "Ant seems to be writing the solutions to the problems we are having in the build as we develop them." I've only had a chance to put two of the major new features in, and boy are they good ones:

  • filterchain expandproperties
    This has eliminated about 200 lines of build.xml, all of them lines like <filter name="property" value="property"/>. This also eliminates a point of breakage where a config file depends on a new property, and we forget to put the values in wherever they are needed.
  • classfileset
    This eliminated another 100 lines of build.xml. And also helped get rid of about 100 classes from the applet jar we have. And if we create a new dependency to some class in a different part of the code tree? No build file changes! I used to use jini's classdep tool to ge this data but now I can just have Ant do it automatically, as a fileset even!
Given features like this it amkes build maintenence a treat to watch things optimize themselves, rather than haveing a dedcated makefile engineer.

November 1, 2002

Some Sneaky AOP Talk

John Lam was remarking about how OOP and such are mostly used for abstractions now rather than for re-use when he said:

But is it enough? As most of you reading this have experienced, there are limits to what you can do with Patterns, OOP, and structured programming. You find that there are features that cut across your well-designed class hierarchies and object graphs. These are the warts in your program that spring to life innocently enough, but then spread as your program becomes increasingly more complex. It is these warts that make it hard for you to comprehend your software. It is these warts that make it hard for you to extend your software's functionality. [ IUnknown.com ]
That is almost exactly the typical rational for AOP. And he didin't use the words "Aspect" or "AOP" once. If anyone needs a non-hostile justificaiton of AOP to give to someone (say, a boss) this would be a good article to send.

November 5, 2002

Referr Logs are Fun!

The strange things you find in referrer logs: someone did a Yahoo search for "some ones hacked me.how can be free and he does not has hacked me?in farsi" and all they got was my page. I guess that's better than ANT & Install & Errors.

December 4, 2002

Belated Solicited Opinion of NetBeans

Well, my mis-adventure with marketing folk has prompoted Oliver to write about their experience with NetBeans, so maybe I sohuld post my opinion that I was unkindly solicted about. First I'll start with the nits that anny me:

Startup Time
Yes, it is dog slow. Apparently they have a guilty consince about it since it was mentioned in the first e-mail without any real provocation. Seriously, what is it doing at start up? Re-hashing the file indexes or something? It is slow and it grinds my hard drive. And it's not inadiquate setup either, I got 512MB, 1Ghz, and -Xmx256m. Once it starts it's fine, so I just usually surf the web when it's starting up.
Bad Attitude about Bugs
I have one case and point for this one: using F12 on an ant build does not give the same support as if you used the built in java compiler. It worked in 3.3, the bug was know and a fix known before 3.4 shipped. But it didn't make the code freeze so it got shipped without it, jsu so they could make a date (that already slipped a week). The analysis in the bug said that it only affected users who were using keyboard only, and they could get the same effect with the mouse. The truth is that it's a lousy excuse not to include it because it's plain old anti-user. We are talking about funtionality that existed in a previous release that was lost in a future release, and it was wll known how to fix it. I have to agree with oliver that the atttiude towards some bugs needs to imporove, and featuritus should take a back seat to fixing bigs that break existing functionality.

So those are my problems, now a marketing type survey might be interested to know what I see in other competing products like, say Eclipse, that might send me to that camp...

Dating the New Girl
No doubt Eclipse is the new toy in town, and as in High School there is someting to be said for dating the new girl (or getting asked out by the new boy, to be gender neutral here). Having the latest and greatest is nice, but even cars loose their new car smell, and it's just another car after a while
Built in Code Quality Checks
The code quality checks in Eclipse are nice, especially the context sensitive import searches. Much nicer than anything NetBeans has. Because it is integrated into the errors list clicking on it behaves like you would expect it to... it focuses the cursor there, and you can use the next error hot key to get there too. NetBeans+Checkstyle (the closest thing) is not integrated into F12 next error, it only highlights the line green. It also doesn't focus the cursor, and the green highlihgt does weird things when you edit it (like being half there). And it isn't sensitive to edits in the source file, so you have to work from the bottom up usually. I can also only check one file from the IDE at a time, rather than being able to click on the explorerer and check an entire folder at once. This would be somehting I would like to see improved in NetBeans. [See my entry on PMD, it addresses this issue]

But given all of that I prorobly won't be going over to Eclipse 2.1, even with the new ant integration features, why?

Performance is a Red Hearing
The performance thing is over-blown, So Eclipse uses native widgets, the java backen still gets over-loaded and all the widget re-paints still get bogged down in the event displatcher. And I've seen more non-startup slowdowns in Eclipse than in NetBeans, especially when I do somehing little like change a propject preference, sometimes it takes 3 minutes for the chagne to take! That's because it insists on re-compiling all 2000 java classes in the project I have loaded, all of them, from scratch, just because I added a new jar library! Anyone who thinks Eclipse is better performing than NetBeans must be working in small projects, or is micro-benchmarking, or believes anything marketing says.
Swing Editor
The NetBeans Swing Editor blows the one Eclipse has out of the water. Why? Eclipse doesn't have one! Not that I can find anyway. To extend the anti-Swing bias to the tools provided is inexcusable by Eclipse. Swing apps don't all look ugly and perform like crap and now that people are starting to code more rich clients since Web Interfaces are intrincically limited, more and more rich clients will be written.
Ant Integration
Elipse is getting better with bringing in AntView to 2.1, but it still doesn't have the holy grail of ant integration I am looking for: I want to take one (or more targets) and make a toolbar button or keyboard shortcut to execute them. And I want multiple targets for each build file, not just one. And Ant runs noticeable slower in Eclipse than in NetBeans. Incramental compialtion may enable some cool beans stuff but it is not being used for the cannonical builds on the build machine so I want to use the cannonical build while I develop. One thing Eclipse 2.1 has I wish NetBeans had is code compleation for the ant tasks. That's probobly feature #2 that would be nice (better checkstyle suport is #1, with all features not breaking previous funtionality being feature #0).
These last two items will in all likelyhood keep me with NetBeans, despide concerted effort to drive me away or lull me over to something else. If Eclipse could do those better than NetBeans then I would take a nice week-ling test drive of eclipse rather than the day long one I did a couple of weeks ago.

December 10, 2002

PMD for NetBeans/Forte

I think I found the missing piece from my entry about what NetBeans needed. Enter PMD, (the acronym stands for many things. It has what I was looking for: F12 (next error) integration, and intelligent line positioning (meaning I can delete the emtyp constructor and F12 or clicking on the error takes me to the correct line, even thougg it is 3-4 lines higher now). You can even write your own custom rules and plug them into PMD. But no product is perfect, some of the parameters (like how deep it should go before freaking out over deep if statements) don't seem editable, and there is no "use spaces and not tabs" rule. But it's still in beta.

This is a project that should be added to the netbeans master auto-update when it reaches FCS even though it's not a netbeans-owned project, it's that good.

December 20, 2002

Eclipse does Swing!

And I saw it with my own eyes, I even got a screen shot!

eclipseswing.png

Well.... April Fools (in December none the less). I just used the Eclipse 2.1 M4 GTK version and set the GTK theme to metal. So if what was keeping you from using Eclipse was the "Oww My Eyes It's Purple" UI then here you go!

Note however that Eclipse still is missing a good a usable a functional any Swing GUI Editor. What's even funnier is that I can't find one for SWT or JFace either! As long as you only want people to write server side and JSP type then what Eclipse has is fine, but if you want people to write real GUIs with it, tools matter.

January 11, 2003

Users Group Presentation on Ant

For those of you who may be remotely interested, I will be doing a presentation on Ant at the Pikes Peak Java Developers Group in Colorado Springs on Tuesday. Even if you aren't going feel free to peruse the slides and send me comments on them. And be as brutally honest as you desire.

January 16, 2003

Netbeans does SWT

AndI got the screenshot again, look!

netbeansswt.png

Well, April Fools again, at least this time it's a bit closer to the date than last time. What you are seeing is a feature of NetBeans that is not aggressivly documented, if you open up ide.cfg and add a line "-ui com.sun.java.swing.plaf.windows.WindowsLookAndFeel" in there. And BAM no more "owe my eyes it's purple."

One piece of code in there that is not april foolery is the Ant code competion, sceduled for the 4.0 release of netbeans, which is... ummm... going to be relased in June, really! Actually looking at the scedules it looks like it's achieveable, feature freeze in about a month and three to four months of what I like to term "quality time" with the code.

Ray mentioned that he didn't like the "swingy" look of NetBeans, and this does a good job of getting rid of it. The same option is available in NetBeans 3.x as well. You are not limited to Metal or Windows, there are other look and feel options such as Kunststoff and Metouia. But since the client I am writing is supposed to look best in Windows, I use the Windows look and feel so the GUI designer uses it by default.

January 20, 2003

PMD/NetBeans config

My little nit on PMD got some notice,

...the "deeply nested if statements rule" can now be configured to trigger only after hitting a certain depth:
http://pmd.sourceforge.net/xref/net/sourceforge/pmd /rules/AvoidDeeplyNestedIfStmtsRule.html
It's a bit of a pain to configure, since you have to edit the rulesets/design.xml file and change the "problemDepth" property, but, anyhow, it works :-)

Well, it works for stand alone running, but inside of netbeans it is not configurable...

pmdconfig.png

That cell in the table is un-editable, so I cannot change the depth. It's sitting there, taunting me and laughing at me! (OK, maybe not, I should reduce the caffine intake and get some more sleep). It's really funny it tells you what the optuion is but it won't let you chagne it. I've even tried looking for the pmd module configurations and for those rules.xml files but i cannot find them for the life of me. So I just don't care about that rull and throw it out.

However, the ant task looks to be editable (at least according to t he docs), so it is integratable to a build process easier. I could just create an at task shortcut to run it, and we can keep the rules files in the source control tree, so we get consistent results.

January 22, 2003

NetBeans 4.0 and Swing Themes

Well, for those of you who are running on non-windows platforms and noticed that my tip about adjusting the look and feel won't (legally) work on linux, enter the Netbeans Themes feature "Ouch my eyes it's purple" not bad enough for you? How about "Run for the Hills it's EarthTones!"

nbtheme.PNG

The themes page describes how to do it, but the Readers Digest version is to drop an appropriately formatted themes.xml file into $HOME/.netbeans/dev/system/. It's not perfect, as you can see the window titles in the embeded windows don't catch the theme, they still got the "ouch it's purple" look to it. And this is currently living in the dev tree, so who knows if the code will make it into the "Real" 4.0 fork. Time will tell.

January 23, 2003

NetBeans listens

It looks like one of my previous issues about NetBeans is getting some resolution, that of a bad attitude about bugs, at least in this anectotal case.

I posted a feature request for NetBeans 4.0 (Issue #29467) to add code comletion to Ant Build scripts. I saw that they added it for XSLTs so how much more difficult can the stock Ant 1.5 tasks be? It took about a month from open to working code in the 4.0 dev codeline. It seems to work in the limited bases I have tested it in. I won't use it for day to day work because I have an alergic reaction to beta-quality code I can't or lack the time to get inside of and fix easily.

Granted, if I got requests for changes like some people have I might have a bad attitude about "community" requested features too. And I am seing some more responsibility taken WRT quality and releases. NetBeans 3.4.1 is about a month late. Why? There were several bad bugs identified in teh release candidates that were put out that were deem worthy of stopping work and fixing. One of the decisions in software development is deciding that whether or not it's fit for public consumption as a release. Depending on the scale of the use the threshold of bugginess moves, but it looks like NetBeans is taking the road less traveled and saying "Too buggy, the release date be damned!" rather than releaseing a 3.4.2, then a 3.4.3, etc. etc. Not that I've had any personal experiences with that kind of a release schemdule ;).

January 30, 2003

JUnit Exception Handling

Gherhard Froehlich was wondering if there was a better way to do positive JUnit exception testing than something like this:

public void testAddService() {
    try {
        setUp();
        TRACER.trace("--- Testing addService() ---");
        ssgConnectorProvisioning.addService(serviceData);
        TRACER.trace("--- End of test ---", "\n");
    } catch (Exception e) {
        if(e instanceof SSGConnectorException) {
           TRACER.exception("Test OK, because Exception was controlled", e);
        } else {
           TRACER.exception(e);
           fail(e.getMessage());
        }
    }
}

There is, the thing to do is to take advantage of the fact that java will only use one exception block, and it will match the first one that is an assignable class of the exception, so you could do this...

public void testAddService() {
    try {
        setUp();
        TRACER.trace("--- Testing addService() ---");
        ssgConnectorProvisioning.addService(serviceData);
        TRACER.trace("--- End of test ---", "\n");
    } catch (SSGConnectorException sce) {
        TRACER.exception("Test OK, because Exception was controlled", e);
    } catch (Exception e) {
        TRACER.exception(e);
        fail(e.getMessage());
    }
}

Let's hope he get's this via a Moveable Type pingback. (I've wanted to see if I have it working or not).

Update: I was kind of myoptic when I looked at the post Gherhard had and realized it was missing something this morning. Charles Miller also noticed it last night: the test should fail if no exception is thrown. steve tried to trim it down to a single catch:

public void testAddService() throws Exception{
    try {
        TRACER.trace("--- Testing addService() ---");
        ssgConnectorProvisioning.addService(serviceData);
        TRACER.trace("--- End of test ---", "\n");
    } catch (SSGConnectorException sce) {
        TRACER.exception("Test OK, because Exception was controlled", e);
    }

fail("We expected a SSGConnectorException");
}


Except in this case the test will fail if the exception is throw! (a false failure). And this also assumes SSGConnectiorException is the only exception thrown. If your tests are written so that only one test is done per test method (a good practice IMHO) you could fix this by putting a return statement in the catch block or moving the fail inside of the try block. Otherwise (such as cases where the exception is just a set up for the real test) you will need two fail statements or catch statements or continue the test in the catch block.

Java String Tricks

Raible:

if (request.getParameter("checkbox") != null &&
request.getParameter("checkbox").equals("true"))

With StringUtils.equals(String, String), you get a little less coding:

if (StringUtils.equals(
request.getParameter("checkbox"), "true"))

If you're using Struts or some other library that already depends on commons-lang, why wouldn't you use it? Possibly performance reasons, but I doubt it causes much of a hit.

Actually, the latter implementation will perform better. It has half the hash lookups and HotSpot can inline the method invocation. [ crazybob ]

Actually, even easier than that....
 if ("true".equals(request.getParameter("checkbox")))
The string class already does the null check inside of the equals call and requires no exteranl library. I got this from an old C trick where whenever you are comparing somethingto null you put the null on the left side. If you accidentally type an assignment then the compiler will crash because a constant is not a valid LValue for an assignment.

February 4, 2003

SWT Claims: Show me the money

Yesterday Jon Lipsky posted a nice real world comparison of Swing v.s. SWT. A Sun emplyee also had a rather lenghty comparison It looks like people are starting to verify some of SWTs high claims.

One of the biggest problems I have with SWT is that the implementation is not cross platform, but is a sperate undertaking for each platform. This leads to wildly differnt user experiences! The applicaiton I am baseing this statement is Eclipse 2.1 M4 build, under both Windows 2000 and Redhat 8 with the GTK build. The first thing I have to say is that the performance and user responsiveness is so different it's like I am using two differnt applicaitons. On Linux doing multiple ctl+clicks on the source tree takes about 2 second per click for eclipse to repsond to. I can get way ahead of the appplcation, and this leads to ghost un-selections because SWT gets confused. And then a tree update from a mass "organize imports" has massive flashing on the tree. Blech! But on windows it responds just fine. But both platforms still freeze updates to the GUI when doing large operaitons, like compiling the 1023 in my current project when I change one seemingly innocent preference about code quality checks. (As an aside, responsiveness is so importaint that Sun dedicated a entire chapter to it in their Java Look and Feel: Advanced Topics book.)

Another area is that by using the native widgets you immediately upen yourself up to inherent differences of user experience. Like adding jar files to the extrnal library list: on Linux you get a tree control where you can do multiple selections across directories. Windows gives you the standard one directory look. And on windows I can click a column top to get that column to re-sort automatically. Not so on linux, you got to use some wierd triangle menu to change the sort. Stuff like this is why a look and feel that is consistant across platforms is so good. If you don't need to behave the same across platforms then why aren't you writing it with kylix or C#? You get all the native widget goodness you need out of that. If you're going to whine about native performance use native coode then!

And then there is the unproven marketing hype, such as this gem:

The real question isn't about what results expert programmers can get using Swing vs. SWT, but rather what results *average* programmers will get using Swing vs. SWT. In this light, Swing doesn't compare to SWT. [ a comment on jason]

The though of threading your own event queue and disposing of your own object is going to make the *average* java programmer run away in fear. And then manageing all of the paltform specific GUI nuances is going to eat up whatever time they may have saveed assuming they have saved any. Since the person who wrote this is a vendor for an unreleased SWT GUI Builder the perhaps he will be able to show me the money. Then we can judge for ourselves when the product is released. It's got some stiff competition with existing mature tools such as the GUI builder in NetBeans, it'a like codeing a GUI in visual basic, except for the part where you write the visual basic, which is to say it's nothing like visual basic, but I digress.

February 13, 2003

Where's the $$ in Java

Yesterday while browsing around a new weblog I found I came across this statement/question. I must admit I have a similar question. What areas of java pay more or are in more demand? And I wonder that not in the traditional role (architect/VP/Sr Developer/Jr Developer) type thing, but in a specialized knowledge type thing. Crowbar seems to indicate that developers who develop Swing apps are paid less just because of that skill. I certianly hope not since I've been kind of backed into that role through chance, but fortunately the stuff I did is provable magic and not simple VB form builder stuff. Another local guy got loads of contract work just because he let his contract handler know he was playing around with web services. It's not like he only knew how to spell "Whisdel," he actullay had some good knowledge to back it up, but sometimes it makes wonder if Buzzword Bingo is the way to job security. That and the experience we had with some (not all) of the contractors we used to use proved that just because you can monkey around with J2EE middleware doesn't mean you are worth one tenth of the money that is spent on you. So I throw this question out to the blogshpere... Where's the $$ in Java at?

February 21, 2003

JTree Woes (or why src.jar is a ture gift)

Nothing is worse than inexplicable behavior. Obscure behavior is close, but decidedly better.

So I've got this bug in my GUI code relating to changing names in a JTree, basically the structure of the JTree stays the same but the length of one of the names of one of the nodes expands significantly at times. The problem is that the new text is not displayed! (or actually, only 4 pixes of the new text is displayed, for another obscure reason).

My natural inclination is to blame my own code, so I dig into the debugger and stop it durring a swing rendering of the tree (two moniters would sure be nice for this). The first rendeering is perfect. The preferred size on the second (larger) rendering is also perfect. WTF? So after a few failed attempts to move stuff around I think to look at the rendering Graphics object, and lo and behold the clip is set to the first rendering size! This has me really confused, becuse I never have to handle passing around the Graphics object and I have become used to trusting that the rigght clipping is set up (that's a magical black box labeled "Efficient dirty region rendering" in my world). So then I (properly) conclude the causal factor is outside my code. Too bad, 'cause I still have to fix it.

This is where I am truely thankful that Sun ships most of the Java code that comes with the JDK in src.zip. I can crack open the implementation classes and look around and find what the real culprit is: JTree is caching the preferred sizes of the tree nodes when it is drawing it, and it's called an optimization. When you are using straight GDM code on a 200Mhx Pentium MMX running Windows 95 I suppose that optimizations like that make sense, but that is, like, so last millenia.

The problem is that this is a faulty optimization, because it clearly isn't keeping up to date or allowing for a hook to change the size of the widgets. Fourtionlatly my diging around also gives me anoter clue: when JTree.setLargeModel is set to true these cachings are ignored. I've always wondered what that property did! But the documentation is so... vauge. It was a real.... bummer. Six hours of head scratching work and the A-Ha moment comes and all I have to show for it is one measaly line of code.

There is still one last mystery in this though: this fix requires largeModel to be true and for rowHeight to be set to a non-zero value. Using the Windows Look And Feel sets this row height automatically, but not for Swing, and for the life of me I cannot find that code in the Windows Look and Feel code. So I just set the value to a previously rendered value when I am done with my data load thread, and it's all good on Linux. So a total of three lines changed (the second change was quite long, and I had to wrap it onto the next line).

February 26, 2003

NetBeans.org Want You to Click My Links!

Download NetBeans!

NetBeans is embarking on a community based marketing push as of late, as seen on their Move the needle! page. Actually it started, like, nearly a month ago. I was going to do this a month ago, but I'm actually starting to do some interesting stuff at work. But do me a favor, click on my main blog page and click on the netbeans link.

So what's in it for you if you click the link above? Nothing, unless you actually download netbeans and use it. What's in it for me? Probably a book I won't read and will just sit on my bookself in my cube looking importiant. It's not like I'm selling out, anyone who has been reading my blog knows that currently NetBeans is my IDE of choice, and that I have looked elsewhere *cough*eclipse*cough*, and NetBeans is currently the pair of sneakers that fit most comfortably.

Also, I am going on a short vacation tomorrow. I can tell this because my mind has basically already turned off, I'm even going to leave my laptop at home and jsut bring along my game boy. Once I get back (or sooner, it's that or work) and my brain turns on I'm going to add links for the other tools I actually use.

March 5, 2003

Java Language Triva...

Here's an interesting snippet.....

String s = null;
boolean valid = s instanceof Object;

So is valid true or is valid false? The answer may suprise you: valid will be false. Why? Well, static type analysis may be tempting to use, and the fact that every reference type must be an Object is another tempting conclusion as well. But nether of these can be used because of the defniniton of the null object reference. C++ doesn't really have this, becuase the convention is to use 0 or NULL to "null out" a pointer. But when you build a construct into a languate you have to be explicit.

Java defines two unique properties for null, first that it is castable to any other type. You probobly knew that already. But the second unique property is that any evaluation of the instanceof operator with a null object will result in a false result. So the null object can be cast to any object but it has no type. Meditate on that one for a while...

This isn't totally useless trivia either, I use it all the time to eliminate redundant null pointer checks. Cosinder this code snippet...

public void tweakElement(org.w3c.dom.Node n) {
    if (n instanceof org.w3c.dom.Element) {
        // do random tweaking here
    }
}

What if the user calls tweakElement(null)? How will it behave then? Well, the same thing as if they pass a org.w3c.dom.Attribute: it's a no-op. Since the null check is built into the instanceof check I can go along in the tweaking code block assuming that not only do I have an Element, but that I have a non-null object as well. It's not a substitute for != null, but if you are checking class at the same time it's already done for you.

March 8, 2003

Use The Source, Duke!

As a continuation from my Problems with JTree I cam a cross another gem for the Obscure Java Nuances list: How do you override an existing keybinding on JTable to make it do something else?

Here's the real-world use case, I'm createig a frame that shows a long list of tabular data that the user may want to drill down on to get more specific info that what is available in the table columns, you know, like multi-paragraph data? So I gout the double and right click menu stuff wokring and while playing with it I came to the conclusing that a user using the keyboard to navigate the table may want to uset the enter key to bring up the dialog. Very standard situation UI... use the keyboard to navigate to the widget in question and press the enter key to interact with it. Simple enough?

So the obvious first course of action, use the NetBeans GUI editor to listen to keyboard events on the table and act when I see the enter key. Should be a 2 minut hack right? Worng. The listener will never see the Enter key typed action because of Input Map, Action Map, and the standard key assignments for JTable. In the spreadsheet work that JTable is based off of enter means "go down one row" rather than "do the default action." Which is all fine and dandy except for the fact that like any good UI I am perverting teh default compnent sets for my own purposes.

InputMap and ActionMap aren't a problem for me, I've used them before and it's merely a hassle writing a few more lines of code. Add the action, bind it to to the VK_ENTER KeyStroke, compile run and... WTF!? It's still going to the next row!? Drop in some code, so I see what I am overriding in the Input map, nothing, look to see what other actions are mapped in the InputMap, nothing at all. A quick internet search using the Google(tm) search engine service reveals that people are more interest in doing the oposite of what I am doing. At this point I heard a Alec Guinness whisper to me "Use the Source"

It never ceases to amaze me how when you are looking for the question to a very specific answer how much more information you can get from looking at source code for something that you may not understand than from reading all of the documentation in the world. The reason for this I assume is that no one can ever document every possible question a developer may ever have. However when you do something non-standard that should be a clue that you should document it.

Deep in the bowels of the basic plaf implemenation of the JTable UI in a method that hasn't been used since Java 1.2.2 I find the answer in a comment...

// We register all actions using ANCESTOR_OF_FOCUSED_COMPONENT
// which means that we might perform the appropriate action
// in the table and then forward it to the editor if the editor
// had focus. Make sure this doesn't happen by checking our
// InputMaps.

It turns out that all of the default key bindings for a JTable are stored in the InputMap for when it is an ancestor component and not the focused compnent. On deeper reflection it makes sense when you think of the cell editors and such. But without that information it is difficut, ney impossible to make that logical leap since it is at it's core a design decision.

So where is this documented? In the JavaDocs? No. In the JTable tutorials? No. In the default key bindings for JTable? Even though it would make sense no. Thank goodness that Java ships the source to exposed classes, or else I never would have made the leap. When all else fails... Use the Source, Duke.

May 9, 2003

Independent Developers and the JCP

Share Me Technolgies recently wondered How Many Independent Developers Join JCP? Well, I used to be a member, back before I got married, but not any more. Here's my experience:

First, as an individual you don't have to pony up $2000 to $5000 if you want to join as an individual. It's something on the order of $100 (this was back in Y2K, so things may have changed). But they will ask to make sure you are truly joining as an individual and not for your company as a way to save money. That's one of the biggest reasons it's not publicly listed. And it's not like a magazine subscription, don't forget to renew or cancel (unless you want some cratchety lady calling you up and berating you when you say "oh I thought I'de just let it expire").

What do you get when you pay? First you get earlier access to some of the specs that come outt of some of the JSRs, but it's not like a public draft, these are under NDA so you can't tell anyone or do aonything public with them. These are the community drafts. And that's all you get ... unless you get involved in a JSR.

JSRs are where the real action occurs. The loweset level of JSR involvement (that can be termed involvement) is as a member of the expert group. Basically all that does is it means you get even earlier access to the JSR drafts (and are under an even tighter NDA for them) and you get to talk on a mailing list to the spec lead who is responsible for delivering the spec (they usually write it as well). Getting in on al call for experts can be pathetically easy or incredably difficult, it depends on the spec lead. And then there is no process check or balance immediatly requiring them to listen to the experts in the group, so some groups have more sway in the spec and some have essentially none. The only real check and balance is political pressure ant the final approval vote.

Beyond that unless you are willing to pony up massive ammounts of time there really isn't much more for independent developers in the JCP. That's why I just let my membership expire.

June 14, 2003

Swiss Army IDE Problem

The approriately names BileBlog was spewing some bile about IDEs lately...

There's also the gui editor issue. I despise it, and will gleefully delete it from my plugins dir once it shows up there. It's such a shame that market forces demand junk like this. To be fair though, I have some sympathy to it being added as a lot of big companies demand bloated shite like this, so it makes sense from a business perspective. Although it's particularly amusing seeing the various comments that have been made about it. A whole bunch of 'well I never use swing but I tried it and blahblah' rubbish. Serious swing developers I suspect are likely to scoff and stick to using their own hand rolled magic. Still, I'm sure java needs yet more ignorant mediocre inexperienced developers dabbling in swing eh? [The BileBlog ]

There's a couple of things I want to address in this little bit. But Wow, in four short days he's spewed a lot of bile that really chaps his hide about java in gerenal. I've probobly got enough for three posts off of this.

Issue #1 : IDE Bloat. Yea, I've noticed this alot lately. All the IDEs need to have some fangleled spangeled tool to do the latest programming fad. Well based on what was said at JavaOne I'de say it's only going to get worse. The 20% that can do without it are probobly using Emacs or TextPad anyway. But if sun wants that other 80% to come over (you know: those other 7 Million developers they want coding in Java instead of VB) They live and breate by and IDEs slick add on tools. And they want it all in the same program.

The type of slick progams they want are stuff like the new Project Rave (and hardcore developers will yawn, principally because it's not for them). Be ready becuase if Sun is serious about those developers they will have to cater to their whims. We're talking about the corperate IT guys who only write software for their department and other such "internal use only" tools that extist because of VB. What's going to happen is that if developing something is not easy they'll put it back on their never ending stadk of stuff to do and work on something else or (more likely) use some other tool.

It's like dating: You'll generally go for what's available and (given a choice) you avoid stuff that's difficult to deal with (or go without). And if it dosen't fulfull your needs you're likely to move on. Sun wants Java to appeal to the lowest common denominator by being flexible, without attachment, and easy!

June 16, 2003

The Follies of IDE Selection by Checklist

Back on the issue of IDE bloat. Sometimes corperations pick IDEs by commitee. And that leads to the check list syndrome. Group A requires Feature A and Groups B, C, D ad infinatum. Add in another common feature of "corperate standards" where development "needs" to standardize on one IDE. So what usually winds up getting picked is the IDE that can meet the biggest check list. In the interest of not losing revenue the IDE developers try to fill all of thoese check list items as is inhumanely possible. But the problem is that the IDEs become a Jack of all Trades, and are sadly the master of none. More often than not what winds up getting picking is an IDE that no one is happy with. But it was done in a very egalitarian fashion, meaning that everyone's equally screwed in that case.

Situations like these remind me of the early days at my current job. We initally had some big fuzzy discussions about coding practices and build environments and one of the things that came up was IDEs. One person with alot of clout (that immediatly eliminates me) insisted we all use Visual Cafe because it integrated with WebLogic. At the job I had just before this one I tried to use what was a current copy of Cafe for a week. I had liked it before, but then again this was after not using it for two years while I was experementing with Linux in College (don't we all experement with stuff in college? Since I didn't experement with drugs I had to experement with something...). Anyway, I quit rather quickly because of it's horrible JDK 1.2 integration. That, and it crashed alot. I voluntered that information but it was freely ignored. Weblogic Integration was the most importaint thing (perforce integration was second) and thus the standard was Cafe (I didn't use it, I stuck with NetBeans).

This was before WebGain crashed and burned. In the year since I had abandonded it Cafe hadn't seen any major changes (despite the new major version number since WebGain bought it). A year and half later I walk into a phone confrenece where he's whining about Cafe crashing again and about what a piece of crap it was. I had to have a chuckle to myself because that's exactly what I had told him over a year earlier. It was still a piece of crap, but the piece of crap integrated with WLS.

Moral of the story? Trust experience over a marketing checklist.

June 17, 2003

GUI Design Tools are Not Just for the Weak

Now on issue #2 that I see with monsuier BileBlog's rant on IDEs. The most relevent poriton of that previous quote is as follows.

Serious swing developers I suspect are likely to scoff [at IDEA's GUI designer tool] and stick to using their own hand rolled magic. Still, I'm sure java needs yet more ignorant mediocre inexperienced developers dabbling in swing eh? [The BileBlog ]

I suspect that he's never done serious Swing development, I also suspect that a serious OSS developer would use an an OSS version control system as well (and by suspect I mean "I'm speaking out of my ass here"). There is no doubting that hand-rolled magic is sometimes the only difference between a sophomore CS project and a shrink-wrapped product. But if I were going to write a GUI in nothing but hand-rolled magic I would need at least two to three times the schedule to accomplish it.

Why? Well, as I blogged nearly eight months ago productivity matters. There are times that you want to spend a lot of time tweaking the little tidbits, and there are lots of times you could honestly care less. That's why I like start out in the GUI designer rather than blank java class. Yea, I could do all the GridBagLayouts by hand. I could also make the vertical FlowLayouts line up nicely inside multiple BoxLayouts by hand, and I could even write my own layout manager to deal with my personal nits if I wished (in fact that was one of the first things I did with Java GUIs more than seven years ago). But why should I visualize the insets, gridwidths, and weightxs in my mind when I can visualize them with my eyes? GUI designers also speed up the tweak/compile/run loop we all get in just to see if you got a titled border on the right component or to see if you fill propertu on a component needs to be GridBagConstraints.HORIZONTAL or GridBagConstraints.BOTH or whether that box layout looks silly with an alignmentX of .96.

GUI designers are not just about layout stuff either (something the reviews indicate the IDEA designer focuses on exclusively). It's about basic wire-work as well. Do I really want to write the boilerplate code to attach some method to a actionPerformed listener added to a JButton or would I rather jump right into the code preping the data for the SOAP call? (the latter, because it's gonna have to be written anyway). When code is truly boilerplate (like button presses and menu selections) and can be automated it should be, wether it's as a language feature, an API convienece, or as a feature of the development tool.

Believe me, there are many times where hand-rolled magic is the way to go. But that time is not when you are saying "JTree here, JButton there."

June 28, 2003

Use Resource Files for GUI Text

This may seem like an obvious statement for people who do a lot of GUI work, but I will say this because it simply cannot be said enough. Don't hardcode strings! That falls into the good old "no magic constants rule" (unless that constant is the 32-bit signed int -1258207934). How do you go about it?

  • Take all your strings and save them in some file that is not part of your main code. There are several options: you could put them all in a code file full of constant values, you could put them in a properties file, or (my favorite) you could put them in an internationalzied resource bundle.
  • Use meaningful names. SC_EN_000854 may be just the same to a compiler as LOGIN_DIALOG_LABEL_USER_NAME, in fact it's shorter and probobly compiles just a millisecond faster. But take my advice: use the human readable form
  • Use some consistent strategy to create these names. Ther are at least three things it should include: what part of the application it's in, what particualr GUI element it applies to, and some indication of what it says. The order doesn't matter and you can even use short varients or (for location and type) encoded varients. But be consistent! The previous exampel could just as easily be LB_D_LOGIN_UID if you are coding it as type/location/meaning.

So why are these importiant? You mean I can't say "that's just the way you shold do it?" Ok, ok. There is a point to this blog entry rather than random rules. Why do I consider this importaint? Any guesses? Umm... you there, yea the one waving his hand up and down and shouting out "internationalization," you can sit down and calm down because you're wrong. Yes it is a very nice side effects but I think there are better reasons. You there, on the front row. "Maintainable code?" Well, it is maintanable code, but that's not the only reason we do it. Anyone else? How about you. Yes, the cynical one sitting in the back corner. "Management!" Ok, close enough, I'll take it.

It's not just management; it's tech writers, QA, marketing folks, and even other coders with better grammer and speling skills then you. To be more precice it's everyone else who wants to put their fingers in the GUI that isn't actually writing the GUI code. If you mis-spel a word and the strings are all over the code good luck finding the string. You could just search on the mis-speling and fix all occurances of that one. But in those cases people only catch the problems they can see, so the biggest stinkers may get over looked because they don't come up that often (for error dialogs they may never come up). With a centralized set of string files you can run a spel checker over it, but don't try this with java code bacuse signal to noise goes down. You can even hand it off to someone with linguistic skills who can fix all the bad grammer as well. Oh yea, I almost forgot. It's easier to internationalize as well, but you'll probobly have the other problems sooner if you are in anything but the smallest development teams.

Even though my reasons for this are entierly prgamatic it won't end all the problems. While some people care about colons v.s. hyphens for separator cues others care about what shade of grey the background is. Should it be windows grey, swing grey, or bike shed grey?

July 7, 2003

How Would You Like Your Three Panes?

Diego is considering going to a different three pane layot for the next release of Clever Cactus (a java based PIM/Mail application). The old school of three paned navigation was useherd in by Netscape Communicator's e-mail program, and Outlook and Outlook Express lead the charge. It is now such a common idiom that almost all off-line rss aggrigators use the old school three pane navigation of channels on left, news item summary on the top right, and the full news items on the bottom left. The new trend seems to be to left middle right three panes. FeedDeamon defaults to three column, and the betas of Outlook from the new Office Betas start out in three column view. Diego is considering going that rout for Clever Cactus and has spent Another weblog entry hashing over more of the detals. However I am of the opinion that three column navigation won't fly. Why?

The most importiant issue in my eye is the issue of the center point. Like a fine piece of art, the content in a gui window should draw our eye to the most relevent or used area. The middle (actual middle or precieved middle) of the window should contain the most used window in the applicaiton. In the three column layout that is going to be the level 2 navigation, not the content pane that is going to be banished to the right side of the pane. Which for western readers the right side is the side most likely to be ignored. (Theater and broadway musicals use this fact to great effect). But there are other areas where we are trained to focus on the middle column of a three column layout. Look at most weblogs out there, most either put perifiery information to the left or the right of the main entry, and some put the info on both the left and the right, even Diego's own weblog uses three columns and places the most relevent content in the middle. Most (all?) modern software IDEs follow this ideal as well: the main editing pane tends to be in the middle while all of the auxiluary informational panes are scattered around the left, right, bottom, and top. It's BorderLayout to the extreme.

Another issue is that a usable three column layout requres a lot of horizontal real estate. We don't all have 16:9 apple cinema layouts so we have to deal with the 4:3 layout of most monitors. And not veryone likes to run every application maximized. About the only application I maximize is NetBeans, and that is because there is usually a lot of non-linier information I need accessible at once. Everything tends to take up about half to three quarters of the horizontal space with the widest content pane taking up about a half of the real sceen space. All the windows also take up 75% to 90% of the vertical space. By adding more horizontal exclusive space it requries me to widen my window.

It also adds more un-needed information to the window. I don't need to see all 30 options on the second level of navication, I am almost exclusively intereted in the top few from that stack. And the few time I do need that space in outlook (usually when I am seraching manually) I tend to make the preview pane much shorter. But as long as the current item is focused in the level 2 navigation I can minimize the needed space to use that level.

Finally it's been tried before. NeXT tried it first and moved it to early builds of the Aqua interfaces and there moans and moans of how hard it was to use. Part of it may have been resistance to new stuff in the new MacOS but if you look at all of the other UIs apple has done since basically none of them do what the NeXT finder did. Russ posted a bunch of GUI links to modern mac applications put out by apple and none of them do a three column layout left to right. All of the main content panes are large and take up the center point. In places where this represents a third level of navigation either the first pane is not shown or it is done where the panes are top left, bottom left, and center-right.

If any new direction in Clever Cactus should be taken perhaps it should be the TL-BL-CR format, with multi-line rows (like quicken or palm's versa mail) containing the second level navigation items. Three column just dosen't float my boat.

July 10, 2003

SWT: I Still Don't Get It

The lone programmer blogged about my old entry on SWT claims referring to it as a "short critique." I think he was being kind, it was a rant all the way. But his entry reminded me of the old saying "If all you have is a screwdriver everything looks like a screw."

I find it kind of funny that he almost admits that SWT sucks on GTK and Mac OS right now. And then he continues to defend the native widgets of SWT by saying it grants "consistency between the apps on a particular platform." News flash: SWT widgets are normalized across platforms just like swing widgets are. And swing provides the same native client look. Have you seen the new XP look and feel in JDK 1.4.2? It looks just like windows themes, and it even keeps up with arbitrary changes. Why? It gets it's UI painting resources from the native OS DLLs. That's one big reason you won't see it do XP on Win2K, the theme information Java needs isn't in Win2K. With SWT you do get native widgets, complete with slow table re-draws.

But this brings me back to my screwdriver argument. If you want native cool thingies like Mac OS dock integration, sliding accessory windows, windows notificaitons, balloon help, Linux GNOME panel integration, etc. etc. Use the right language! (or at the very least the right APIs). You want all those slick dock integration APIs? Use Objectve C and the Coca APIs. You want Gnome panel integration? Use the Gnome APIs in their particualr language (C, Python, Perl, or Java-GNOME) . You want neeto-skeeto integration with Longhorn? Use C# (but that may make you part of the problem). Just because it can be approximated in Java dosen't mean that you have to use Java! Use the right language for the task. If platform specific features are essential to the user experience use the tools designed to deliver that integration.

Jeez, it seems that Java is a religion. I just hope that they don't start refering to people at java conferences as "the faithful."

July 22, 2003

I is for Integrated

One of the principal features if an IDE is the Integrated part. What it takes to be integrated has gone up from the days of the first IDEs. The way it used to be was you had the compiler and the editor running from the same binary and that was what constituted integrated. Slowly the IDE became more and more integrated. Features like next compiler error and code context highlighting brought the editing and the compiling closer together. Now the bar for integrated is high, and if you know how to use the environment it can speed up your coding time. While it's true that if you don't know how to use the environment that it can slow you down there are some capabilites that could not exist without wich integration.

Lets take NetBeans for an example, and three rather un-related tasks: Source Control, Internationalization, and GUI design. The IDE intrgrates these three facets without making you switch to three differnt applicaitons or even three different panes in the IDE. First I open up the GUI designer and I add some components. However, I cannot just hard code some of the label names in since we plan on selling it outside the US (one of the few places you can get away with monolingualism, and that too is changing). So I click on the label I want to internationalize, and I bring up the property editor for the "text" property. I select a drop down box tha says I want to get the value to be internationalized. Now I am doing some rather common Java I18N tasks: I need to identify the resource bundle I will get the text values from and select the key. I can either create a new bundle or select an existing bundle in my code base. For the keys I can select from one of the existing keys or create a new one as well. The value of the key in the current language is also displayed to me so if I don't unerstand the key name I can select an appropriate key based on it's value. I can even add a new key and it will be added to the bundle for me. Resource selected, key selected, time to press OK. Here's where the source control comes in. If I've selected an existing resource bundle and I've either added or chagned a key NetBeans will save the changes. But if the resource bundle is in source control and is read only NetBeans will also ask me if I want to open it for edit in the source control. All this without me having to navigate pop-up menus and I am prompted only when I need it. When all this is solved and I am back in the GUI designer, the label I just internationalized has the value from the resource bundle shown right in the designer!

Source Control, Inernationalization, and GUI design, all dealt with in the same application in a logically connected fashion. And when you are done no visible warts are sticking out at you. Without these tools the work would have taken me mutliples of time longer because I would have to switch in and out of three seperate programs and mental contexts, where instead the IDE deals with the warts for me and only brings these issue to my attention when being dealt with.

A truly integrated experience is very seductive indeed.

November 15, 2003

The many lives of javax.swing.Action

Gregg Bolinger been using swing for a while mentioned in My Approach to Menu's in SWING about how he extends and uses the Swing action alot. After being buried deep in Swing for nearly two years now I have to concur: Actions are more importiant than you may initially think.

For the Swing code I've written at my job I use Actions to back the actions of menu items, toolbar buttons, popup menu items, some of the regular old buttons, and even handeling Drag and Drop actions too! (Since the drag and drop is another way to invoke a menu action I just wire in the call to the actions for a successful drop).

Like Gregg I've overloaded abstract action, but I've gone crazy with stuffing in the standard behavior. First I populate all of the action values from a resource bundle. This allows for easier I18n of the action and it also keeps a lot of the related actions visual looks in the same file. This is handy when someone decides they don't like the menu accelerators you've selected or that all of te Icons need to be re-done and stored in a differnt place Next I populate a large amount of standard information into the value cache of the action itself:

  • Name
  • Location in the Menu Bar (i.e. file/new/widget or help/about
  • Location in the Tool Bar
  • Location in standard Pop-up
  • Toggelable (creates checkbox menu item or toggle toolbar button)
  • Asynchronous (spins a thread for the action)
  • Icon (along with rollover and selected varients)
  • Tool Tip
  • Mnemonic
  • Accelerator

And that's just what I can remember early in the morning on a weekend. I also provide standard methods to get a menu item and toolbar button out of the action so I can handle things like the checkbox menu items and global options such as show/hide menu icons and tooltips. I also try and limit any code that does any user initiated actions to live in the action methods of these objects.

By doing this it keeps a lot of the non-gui code out of the gui and I can stress out about bizzare JTable behavior without tripping over a database call to delete a row.

November 18, 2003

IBM Move Fills in Eclipse Hole

Almost year ago I posted a review and comparison of NetBeans and Eclipse. The ultimate end for me was to stick with NetBeans because it had a visual gui designer and Eclipse didn't (an essentail job function of mine). Well, that looks to be changing. IBM will start it off by donating its Visual Editor from the WebSphere Studio line to the Eclipse project for JFC/Swing editing, and other companies will be extending it to support SWT. This perhaps may explain why SWT Designer sold itself to Instantiations earlier this week.

This basically leaves refactoring as the bigest distinguishing feature of Eclipse, and Code Folding for Netbeans once 3.6 ships.

November 19, 2003

Python one-ups Java in Consumer Land

So I spent most of the afternoon setting up and transferring data for my new HP computer (a250n for those who care). Boy you wouldn't believe the junk that comes pre-installed with a consumer model. But when I was uninstalling the junk that had unistallers I was astonished to see that one of the items that came pre-installed was Python 2.2.1 and the win32 extendsions. But Java wasn't. Python, yes Python was on my consumer PC. I don't know why, I can't find any *.py* files.

So Java, with sun behind it has to play second fiddle to Pyton being the pre-installed suprise. Who'de of thunk?

November 20, 2003

NetBeans Feels the Refactoring Heat

In addition to starting up an interim release 3.6 that NetBeans initially didn't consider doing they have also recently proposed major changes to the 4.0 plan. Originally a re-worked Projects system was to be the centerpiece of the 4.0 release, but that has for the most part been scrapped. The big reasons pusing this? It was consuming too much resources that they felt should go to requested features such as code folding and (no suprise) refactoring. Some projects stuff will come in but most of the projects bugs will be closed as WONTFIX.

A real IDE arms race is heating up now that it seems that NetBeans realized that this is a battle that is winnable and worth fighting. But honestly I don't see there being only one true IDE for java like Visual Studio is for Windows development. Combine this news with the recent additon of a Visual GUI Editor to Eclipse means that Netbeans 4.0 and Eclipse 3.0 should have very solid parity with no clear advantage to either. Things will get very interesting if the common IDE plugins JSR gets supported by both as well.

November 21, 2003

Thick Client : Thin Client :: Red Pill : Blue Pill ?

Now that the Web has finally invaded just about every corner of life and the magic of "thin client" has been applied to every conceivable application we can finally as ourselves the question "is this the right thing to do" rather than "can we" or "how do we." the answer to the second is "yes" and with some Googling the answer to the third is within easy grasp. But these two beg the first question, of "should we." At my company we started out our first pass on the GUI as a pure think client DHTML nirvana. At the time the think client kool-aid was quite strong and everybody bought into the vision of it. We didn't have any real serious discussions on any non-html solutions. We have since started going down the swing path for various reasons. It wasn't a bad thing we started out thin, because if we started out thick we would have certainly have been asked the question about why we don't just do it in HTML. Now people can see the difference and for waht is wanted it is a real value.

But thick isn't always the answer. Sometimes thin is the way it should be done. But when and which? Here is a bullet list based on some of my experiences, dating all the way back to when NetDynamics was sold by a company called Spider Technologies.

  • Scale - This is actually two questions, with different answers for each extreme based on the way you ask it.
    • Number of Users - How many users are going to be using this application? If it is large (hundreds to thousands per instillation) then a thin client avoids messy install issues. If it is small then either way.
    • Amount of Data - How much data is the user expected to handle. It's not about how much water is coming through the hose but how big the nozzle is. To much data coming through a thin client is like a fire hose. But on a thick client it can look like a meandering river. Lots of data at once means go thick
  • Interactivity - Is the interface meant to be highly interactive? We're not talking just mouse overs and hovers. Resizable and removable column headers have a hight cost associated with then in a thin client. Similarly a frequent need to update data on the server can place a heavy load on the server application if done poorly, even if done smartly. A thick client can more easily update a small piece of data without dragging back across the wire a large amount of strictly visual effects, such as adding a new node to your typical tree control.
  • Rich UI Controls - How much control do you need over the UI controls? Editable ComboBoxes/SelectBoxes are one example that are all but impossible to do well in HTML. A rich table control with sortable columns that can be dynamically resized and have columns removed showing thousands to possibly millions of rows can be done with HTML through various HTML and serving tricks, but the tend to work better when thick. Some controls can be emulated "good enough" in HTML with scripting, such as calendar selects and formatted fields, so that may work for thin. But plain old goofy controls will requires some meat on them bones.
  • Frequency of User Use - How often is the typical user going to use it? If it's once a month they won't endure a 10 minute install, like your typical online banking app. But if it is continually used they may want a client image, like an Instant Messenger client. Some frequently used apps can be done well with a thin client, but that's because the UI is simple

Thin clients are good, but I think they are being over-done. When I hear of people writing a UI that 10 people at each large client will be using all day with rich table controls and massive amounts of data pushed through it being written as a DHTML web app it makes me want to take the blinders off and introduce them to old friends like Applets and new friends like WebStart. After all, thick is the big trend.

December 1, 2003

Some Code Never Dies

I remember when I first really learned about Java. I had seen the HotJava browser on TuCows but passed it by. It was when I downloaded and used a beta version of Netscape Navigator 2.0 in late 1995 that I really got interested in it. I immediatly went and got the beta JDKs for Java 1.0 and started looking at it. I had told myself that I don't have time to learn another language because C++ was the future, and that I really needed to stop playing with it because I really really needed to study for finals. Since I was at the Colorado School of Mines finals wasn't something I could really blow off. I still got a C in Chemistry even though I actually did study for that class (it was the hard heavy math based chemistry, now warm and fuzzy environmental essays here, I probobly would have gotten a D in that class).

I didn't do too much with java over the Christmas Break, I spent most of it playing Dark Sun Shattered Lands. Durring the next semester was when I started playing more with java. One of the first things I wrote was an absolute positioning Layout Manager, since I hadn't quite groked the whole point of relative layout managers. Over the years I'de see some of my early stuff pop up on Google queries, a presentation I made at an early DJUG Meeting on ClassLoaders is still kicking around on someone elses site. My position layout was even shown on some companies JIT benchmark pages.

Well today I got an IM from someone looking for the source to that first real polished Java class I wrote over 7 years ago. Whouldn't you know it was still sitting on someone's web page? I found it complete with my old "semi-colins everywhere indent the braces" coding style. They had actually used it and the web page had never been taken down (unlike my page at Mines which is long gone). Considering that this is a Random Act of Software it's pretty impressive that it just refuses to die. I'm sure there's got to be better implementations of what I've done, but if you disagree you can grab PositionLaout.java for yourself, now under a Creative Commons Attribution License! (No warrenties of fitness, as is, no support, etc. etc. et. al.).

March 25, 2004

Optimizing with a narrow scope

When optimizing stuff you need to keep a rather large scope to make sure you aren't really making things worse. Consider this entry on Strings.

Based on what the entry is discussing at the best you are optimizing byte code alone. What needs to also be considered is the true cost of the virtual method being called, String.concat(String) vs. StringBuffer.append(String). Those 8 lines in bytecode you save will be more than made up in heap thrash and array copying. (But if it's a J2ME environment, it may be valuable enough, even caveats have caveats, time vs memory is a tradeoff not a rule).

For the case of two strings this is the same performance as common StringBuffer tricks, but once you go to three or more IMHO using a StringBuffer or merging all additions to one line is the best way to go. Concat creates a new char buffer big enough for itself and the item being concated, so for N strings N-1 extra buffers are created, whereas a string buffer only creates a new one on size violations, so N-1 is the worst case.

And this is a worst case, when dealing with multi KB or multi MB strings the hit is huge with lots of GC thrash for each new string in concats or simple "+" operations. If you can cram all of the strings into one <RVALUE> you will get StringBuffer/StringBuilder for free, otherwise make one and use it yourself, your heap will thank you.

April 2, 2004

Don't Laugh, I've Done the Commando Pattern

Sometimes April Fools isn't, and in the case of "Resign Patterns" I've actually used The Commando Pattern, in production. And to my knowledge it's still in production somewhere. While the article was tounge in cheek ther are some times wherer this is appropriate:

  • A Pattern of Last Resort
    When using the commando pattern it should be used only as a last resort. Diplomatic means (proper registration, coping with bugs) have failed, marginalization and containment (subclassing, replimplementation) are for whatever reason no other viable alternatives exist (plain old doing something else). But sometimes the net benifit is greater than the other costs, and it should also be considered in those cases as well.
  • Clean Execution
    When commandos operate in real life a good mission is one where not a single bullet is fired or any injury incurred except for what the mission dictated, and this is on either side of the conflict. Commandos are not equipped to handle a full military assult and they (usually) don't want to start major conflicts. If people know you are there then something has gone horribly wrong. Nothing is worse than cleaning up a botched special forces job (think American hostages in Iran and Jimmy Carter). Similarly when you use the commando pattern you want to do what is needed quickly, cleanly, and covertly. And if the president doesn't need to know neither does your manager. (But wouldn't it be great if this URL magically worked? Right away Mr. Architect.)
  • Take No Prisoners
    All you are interested in is is getting your job done, extracting High Value Targets or delivering specific items to well insulated places. If you need to track other event listeners or integrate yourself into the framework then probobly you should look at other options. Perhaps a "spy" or "co-opting" pattern should be used in such cases.

In my particular case the registration of URL handelers in the java.net.URL class had been taken hostage by the startup routines. Our program was much to dependant on forgein URLs and when transitive closure made putting all of our stuff in the boot class path untenable we had a problem. Registering a property wouldn't work because our classlaoder was not exposed to the system class path. So I went to the accessiblity of the hashtable storing the class objects for the URL protocols, opened it, insterted our protocol, locked the access back up again, and got out.

It's been many years since that mission, and now that it's been de-classified I can tell my story.

April 9, 2004

Make your MFC Apps look like Metal?!

Some people see beauty in the strangest things, like this abandoned project to provide MFC controls that look like Swing Components. It is four years abandoned, but even four years ago the author refused to make the fonts bold and use the horrible Lucida fonts.

That fonts are the biggest problem with the swing look and feel, even more than the "Owe my eyes it's purple" color scheme. So why did the ocean theme just fix the colors and never the fonts? That's going to make the ocean theme the least used new feature of JDK 1.5.

May 17, 2004

Groovy, Verbosity, and Swing

While I was on vacation in Hawaii Jonathan Simon lamented about how people still aren't getting it.. I think that the single biggest problem creating the misconception that swing is slow is that people don't understand or use threading on their GUIs. Two main problems exist. First any event you handle is inside the event dispatch thread which is also responsible for painting the GUI. Second, practically any manipulation of a JComponent must be done from within the event dispatch thread. Practically a paradox, but it can be dealt with.

Consider an action event that updates a label named jLabel with a string value from a long running method called takesTenSeconds. You may be tempted to do something like

public void actionPerformed(ActionEvent e) {
    jLabel.setText(takesTenSeconds());
}

but then you violate the first rule: no long running calls in the event thread. With anonymous methods it can be handled however...

public void actionPerformed(ActionEvent e) {
    (new Thread(new Runnable() {
        public void run() {
            jLabel.setText(takesTenSeconds());
        }
    }).start();
}

That's some progress. But we now violate the second rule: Don't use thread unsafe methods on JComponents or mess with models they use. In this case it will not be a problem, but when you start with JTrees, JTables, JLists, JComboBoxes, and the like you can create these lovely stack traces to system.out involving concurrent modification, null pointer, index out of bounds, and other stuff that looks bad to QA and clients. How do we fix this?

public void actionPerformed(ActionEvent e) {
    (new Thread(new Runnable() {
        public void run() {
            final String newText = takesTenSeconds();
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    jLabel.setText(newText);
                }
            });
        }
    }).start();
}

A code snippet that a random VB developer would assume is one line morphs to 3 times it size in characters and (depending on your codeing style) 10 lines in the code. Even with another utility method for the background call we have to make two runnable classes, whether anonymous, inner, or stand alone that's a lot of code bloat. What would be nice is a more concise syntax for a runnnable. Enter Groovy and closures. This can be made much smaller with the creation of a few simple utility closures...

invokeAndWait = { SwingUtilities.isEventDispatchThread() ? it() : SwingUtilitites.invokeAndWait(it); }
invokeLater = { SwingUtilities.invokeLater(it) }
invokeOutside = { SwingUtilities.isEventDispatchThread() ? Thread.start(it) : it() }

From this, the proper way becomes much shorter...

invokeOutside {
    text = takesTenSecondes()
    invokeLater { jLabel.text = text}
}

With some tweaking on the sample closures it could probably even be reduced to...

invokeLater { jLabel.text = invokeOutside { takesTenSeconds() } }

I think that the greatest problem with the swing APIs are not that they are too complex or too poorly explained. The biggest problem I see is that to do simple things the correct way, it can get quite verbose. Kind of like reliable file I/O, but you get far fewer urgent-1 bug in the GUI than in core I/O routines. Perhaps the best thing isn't to change the Swing APIs, but to add more syntactic sugar.

May 25, 2004

Extending Swing via Listeners

With a framework as nimble as Swing there are many ways to skin a cat. This is possibly one of the sources of many complains about Swing. For example Sam Dalton wrote a class that implements a dialog that closes when the escape key is pressed. Subclassing JDialog is certainly one way t do it, but I probably would have simply wrote a utility method...

static void makeDisposeOnEscapeKey(final RootPaneContainer rootPane) { Action action = new AbstractAction() { public void actionPerformed(ActionEvent arg0) { ((java.awt.Window)rootPane).dispose(); } }; KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); rootPane.getRootPane() .getActionMap() .put(action,action); rootPane.getRootPane() .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(stroke, action); }

A couple of changes reflect my swing codeing preferences. First, I call dispose() instead of hide(). My reasons are twofold: first until a window is disposed it takes up native graphics resources, and can essentially be a big memory leak until the object becomes inaccessible and is finalized. The second reason has to do with a clean JVM exit. While any AWT resources are realized (i.e. have native OS resources allocated) the AWT event thread will keep running and the JVM will not exit. If all of the windows are disposed() then the AWT event thread will enter a state that will allow the JVM to terminate. No more calls to System.exit(0).

The second thing I changed was which action map I put the escape key in. Sam used WHEN_FOCUSED which is fine if there are no focusable components in the dialog. But throw in a button or text field and the action may never get fired. There are actually two options here, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW. I chose the latter because this is also how the JMenuItems register their accelerator keys and the desired operation is essentially the same. Since we are adding the action to the JRootPane there are no differences between the two.

By using a utility method we can also add this behavior to any free standing component. One of the issues Swing has to deal with is that higher up in the AWT hierarchy dialogs and frames were separated. To deal with this they created an interface javax.swing.RootPaneContainer so that they can treat all root level components the same. Hence this behavior can be added to any JFrame, JDialog, JWindow, JApplet, or JInternalFrame.

And please, if you have obnoxious splash screens either have a user preference to turn it off or add this to the JWindow so the user can click it and press escape. Wouldn't that be nice.

June 3, 2004

JDIC criticism misses the big picture

One common problem you will see on news forum sites like SlashDot and their ilk is that sometimes the people who write comments to the posting don't read the article or only the first and last paragraph. But what happens when it's not an article but an open source project with big name sponsorship and instead of a comment it's a weblog post on the same sponsoring site? Less Comments.

When Jonathan ranted about how JDIC missed the point in reality Jonathan missed the point of JDIC. It appears that instead of reading what the project is actually about he skipped down to the screenshots and critiqued the sample application code itself and not the actual content of the JDIC project. But to make sure the causal reader who has 100 to 1000 aggregated weblog posts to read can get the point of my response I will use a larger font, write it in bold, underline it, and blockquote it. (I'd use the flash tag but no mainstream browsers support that anymore).

JDIC has nothing to do with Swing.

For those who are sill reading, I lied about the larger font, bold, and underlining. I just didn't have the heart to be that mean. But with enough whitespace around it a person who is scanning will see that the only realtion between JDIC and JFC/Swing is that they are written using Java.

To give Jonathan credit, showing the three different platforms for the same screen shots does lead one to believe that the demo apps are the real product. But in reality all the criticism levied in the article actually lands squarely on Swing because the demonstration of the features happen to be written in Swing . None of the classes from the project itself use Swing, and the only GUI component in the project is actually a subclass of an AWT class. I'd respond to the Swing criticism, but instead I'll direct interested readers to a previous blog entry I did on the same subject (executive summary: Microsoft Office XP and 2003 don't look like windows either). And there is a great projects on Java.net to address the GUI differences called winlaf. The dev builds of NetBeans v4.0 use this to great effect. But I'm going down a rat hole.

What does the JDIC provide anyway? According to the documentation link on the project page (the sarcastic commentary is my doing).

  • An AWT based web browser control.
    The reference implementation uses Mozilla, but why use HTML when you've gone tot he trouble to write a Java GUI? Oh yea... Ads.
  • APIs to open files for viewing, editing, or printing on the native system based on their file types.
    You can start an MP3 file with Windows Media Player, Real, iTunes, or whatever they have their OS configured to use. Better than Runtime.getRuntine().exec("c:\\my music\\stolen.mp3") because it's not owned by the opening process.
  • APIs to associate programs with said file types.
    Just what Java needs, more "JNN is not registered as the default News Reader, would you like to register it now?" dialogs.
  • APIs to open up the system mailer with a particular message.
    One step closer to the killbill.j2se.worm virus, or generating crash reports. Those are two different items right?
  • A program to wrap up your WebStart applications in to platform native installers.
    Clicking on a link in the platform native web browser must still be to hard, wizards are much easier. Especially since all of us use computers that are online all the time and we never install anything from a CD-ROM.
  • They are also looking at adding screen savers.
    Wasn't the SoBig worm sent through screen savers? Or is this for distributed.net?

A poorly written Swing application certainly could use these. And I am sure some of them will. And they will call the APIs in the event dispatch thread (despite all of the documentation instructions not to). Hence, people will think JDIC is slow, and not use it. So really this is a moot issue.

June 17, 2004

Java WebStart and Desktop Integration

JDIC or not I think some people at Sun are getting some issues related to desktop integration and building them in. Some of the chagnes in 1.5.0 are ho hum but some of them address JDIC type issues:

  • Ability to specify where in the Start menu to install the startup shortcut
  • Ability to add extra stuff to the menu, like ReadMe docs and support links
  • Ability to associate MIME types and file extensions in the desktop shell with your WebStart app
  • Ability to detect another running instance of your app and send startup info to that instance
  • An Import Mechanism, so you can install apps from CD from and have them update from the web

All of these are great, but today I saw the best surprise of all (better than GridBagLayout throwing array index exceptions). While re-installing FireFox I saw that my test WebStart program was actually in the Add/Remove Programs Dialog! No more hokey stuff about going to the WebStart panel to clear out an old version, now I can tell SEs over the phone "OK, click start, control panel, Add/Remove Programs. Now find..." "Look, I'm not that stupid I know how to remove applications" "Apparently you don't or you wouldn't have opened that ticket as Urgent."

June 24, 2004

JDNC and the SwingX Project

After a year from when it was announced finally we see something from the JDNC project. Let me say I think it has a brighter future than the JSF project. Web Clients have their role, but just like Television Actors sometimes they overextend themselves. On a quick pass it looks a whole lot like XAML will be for longhorn, except you don't have to wait until after the Star Wars Episode III Special Edition DVD is out to use it in production.

But I am straying from the point I want to make. XML is the topmost layer of the JDNC project. What I am more excited about is the standard swing component extensions, which comprises the lowest layer of the JDNC project. For the level of Swing that I have been coding at those provide the most tangible value today. Why? Couldn't I just write or fork a TreeTable or Form interface of my own? Yes I could, and it would forever live inside the walled garden that is proprietary apps. Don't get me wrong, I've already done it for a DataPicker widget. But what this offers is a common standard extension to the swing components from Sun, one where the components might one day make it into the JDK.

Back when JDIC was announce I nearly wrote an article calling for a STSC project: Standards Track Swing Components. Some collector project on java.net where common swing components could try and evolve in some sort of a standard environment and possibly be included in the standard J2SE one day. It's much to late late at night for me to recount the details of how it would have gone down, but it would have been a standard set of common widgets that have some brand of authority. For example: look at the number and quality of data picker widgets, wouldn't it be nice to have a standard one like MFC does? And look at the widgets that Java Look and Feel (and the advanced topics) describes that do not exist in the JDK: sorting tables (two ways none the less), tree tables, Wizards, badged icons, and even toobar drop downs. All this in a published "do this" standard and no common implementation. No wonder VBers run from swing, they see cool stuff like that and say "I'll stick with MS" when the article starts talking about TableModel, EventListeners, and when to call repaint().

The SwingX subproject in JDNC can fill this role in my opinion. In fact they have a good portion of the items I just listed as part of their standard package (althought the date picker needs serious help, I don't think it will be hard to get it). Two suggestions I would have would be first to formally make SwingX a subproject of JDNC. Next they need to either drop the LGPL for a variant of the MPL or require a dual license for all submitted patches so that contributions can be brought into the core Java Runtime in the Mustang or later release. A Joint Copyright Assignment is required to contribute code.

If those things are done then when a kewl component like the JSpinner is released, it can first be hashed out in SwingX and then placed in the JDK later. Telling people that they have to upgrade their client JDK just because I used a spin box for number entry got me some strange looks and a good bit of grief.

July 23, 2004

A Plethora of Versions

Versioning versioning, let me count the ways in Java...

  • /**@version 1*/ - In the beginning there was JavaDoc. All this version tag was put a pretty version number in the HTML documentation file. Lives in the code and documentation.
  • long serialVerUID = 1L; - Introduced in Java 1.1, used for object serialization. Lives in the code and class files.
  • <extension>-Implementation-Version: 1 - Introduced in Java 1.3, used for standard extensions (which were introduced in 1.2). Applies to the jar as a whole. Lives in the manifest.
  • Implementation-Version: 1 - When used in a package section of a manifest this applies to the whole package. Also introduced in Java 1.3.
  • x-java-jnlp-version-id: 1 - WebStart has it's own concept of versioning as well. This version is sent by a HTTP header field, and can apply to any resource referenced by a JNLP file.

Four different ways to specify versions, and each with different scope and semantics. For example, the extension and package versioning have notions of specification version and implementation version. All but JNLP consider the version identifier to be opaque and have no meaning beyond identity. JNLP dedicates an entire appendix in the specification to version ordering and matching. And don't forget the unofficial methods like strange manifest headers and Version classes.

At least there isn't a Version annotation introduced in Java 5.0. Not yet anyway.

October 13, 2004

An ocean, an ocean of blue

I had a dream the other night.

I was stranded in the middle of a vast ocean, an ocean of bright blue. I tried to swim to the edges, but at every edge I was met bu bright bright blue. The ocean wasn't all blue, sometimes it would fade into white, and then back into blue, but it was still a bright blue. And the ocean was a bold ocean, still a very bold ocean.

Then I realized it was a dream, but if I work up the ocean would fade and I would find myself on a vivid blue corrugated metal slab, and the blue was so vivid it looked purple. A bold purple.

I couldn't decide if I wanted wake up or stay in my dream. I desperately wanted another choice.

February 5, 2006

Flattening the JSplitPane Divider

You can do just about anything with Swing... Iff you know the magic internal classes to monkey with.

Today's example has to do with the JSplitPane. For a GUI I am working on I needed to allow a list box on the left to be resized by the user while keeping some content on the right, but it can't be to obtrusive or distracting. This is obviously what the JSplitPane was meant to solve, except for the part where the implementation always paints the whole freaking thing! What I want is what is on the bottom and what I get by default is on the top.
flatdivider.png flatdividerXP.png
So how do I fix this? I need to override the UI painters. Usually this isn't for the faint of heart, but in this case it is for the faint of heart! You see the basic plaf split panel divider painter only paints the associated border for the split pane divider, and maybe the expand buttons.

So all we need to insure is (a) we use some variant of the BasicSplitPaneDivider and (b) that it doesn't get any border set to it. I'll wave my hand over some access issues and complaints about global defaults, and show you what finally worked...

jSplitPane.setUI(new BasicSplitPaneUI() {
    public BasicSplitPaneDivider createDefaultDivider() {
        return new BasicSplitPaneDivider(this) {
            public void setBorder(Border b) {
            }
        };
    }
});
jSplitPane.setBorder(null);

The how without the why is that I create my own UI for the BasicSplitPane that uses a custom BasicSplitPaneDivider that is oblivious to any border set on it.

Here the complete demo that spits up the frames I took the screen shots from.

import java.awt.GridLayout; 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;

public class FlatSplitPaneDivider {
    
    public static void flattenSplitPane(JSplitPane jSplitPane) {
        jSplitPane.setUI(new BasicSplitPaneUI() {
            public BasicSplitPaneDivider createDefaultDivider() {
                return new BasicSplitPaneDivider(this) {
                    public void setBorder(Border b) {
                    }
                };
            }
        });
        jSplitPane.setBorder(null);
    }
    
    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        
        JFrame f  = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(200, 200);

        JPanel p = new JPanel();
        p.setLayout(new GridLayout(0, 1));
        f.getContentPane().add(p);
        
        JSplitPane sp = new JSplitPane();
        sp.setLeftComponent(new JLabel("<html>This is the Top Left Label"));
        sp.setRightComponent(new JLabel("<html>This is the Top Right Label"));
        sp.setDividerLocation(100);
        p.add(sp);
        
        sp = new JSplitPane();
        sp.setLeftComponent(new JLabel("<html>This is the Bottom Left Label"));
        sp.setRightComponent(new JLabel("<html>This is the Bottom Right Label"));
        sp.setDividerLocation(100);
        flattenSplitPane(sp);
        p.add(sp);
        
        f.setVisible(true);;
        
    }
}

June 5, 2006

If it isn't easy, people won't use it.

Talk about transparency in process, JSR-296 has hardly conviened and a good idea of what will actually be delivered has already been presented at JavaOne. (Ok, the pedantic folk will argue that this wasn't speced from scratch in public and thus is still closed process, but bringing a functional idea to a standards body is IMHO a better way to get working standards finished in a reasonable amount of time than design by committie. But I digress).

Everything to me looks good, except for one piece. The piece that really will improve the performance of swing applications more than the other items in the framework. Asynchronous actions (starting at slide 45) are too complex for the below average developer (or in other words, half of the developers). What is my arbitrary metric for why it is to complex? The sample code takes two slides in the slide deck. And almost all of it is boilerplate class text for the SwingWorker. SwingWorker is indeed a powerful tool, but too may developer will either (a) not get it or (b) be too lazy to do it when they need it.

So what would I do? First, I wouldn't pitch the "returns SwingWorker" idiom for actions; there are times that is absolutely needed. But what I would do is...
@Action(stage=SyncBefore) List<MyItem> saveItems() {
    return getMyItems();
}
@Action(stage=Async) String saveItems(List<MyItem>) {
    int nSaved = 0;
    for(MyItem myItem : myItems) {
      saveMyItem(myItem);
    }
    return "Items Saved";
}
@Action(stage=SyncAfter) void saveItems(String status) {
    jTextAreaStatus.setText(status);
}
And this is actually the "do everything" example for my pattern. The pattern this is indented to deal with is an action that (a) gets some state from the GUI widgets in the EDT (b) does something with that state and then (c) updates widgets afterwards in the EDT. Clearly not all of the GUI actions will be this simple, but it is the 80% solution. If you need multiple steps of (b) and (c), return a SwingWorker. If you are just refreshing date in a combo box from a database query, this is the one for you. A good portion of actions will do only two or even just one of those steps, so there may be even less overhead.

So how would this be parsed? There would need to be three identically named methods, one that returns type U and takes no params, one that returns type V and takes U as a param, and one that returns void and takes V as param. Each of those are (respectively) the EDT before, the async, and then EDT after portions of the action. If any of the methods are missing, U and or V will become Object, and the missing method will become a no-op.

June 17, 2006

JavaDB is not in the Mustang JRE, Stop freaking out!

For all of the moaning and groaning going in in the java blogosphere about JavaDB being integrated into the JDK, I feel a particular nuance needs to be pointed out...
For a great out-of-the-box development experience with database applications, the final Mustang development kit - though not the Java Runtime Environment (JRE) - will co-bundle the all-Java JDBC database, Java DB based on Apache Derby.

[What's New in Java SE 6 Beta 2 (Mustang) bullet point 3]
I will admint I missed that the first few times, and whined about how bad the bloat is becoming, but it is a tool that is going into the Developers Kit, not the Runtime Environment. It's like JConsole, the swing demos, and all of the ohter cool stuff we play with as developers. Joe user won't have to deal with it, unless you bundle it yourself. So take a deep breath, ease of the keyboard, and don't bile it just yet.

December 30, 2006

DRY Logs, there are better ways

Ruby is having a definate impact on Java, or at least the idioms implemented by Rails. Two of the most commonly mentioned are Coding by Convention, and Don't Repeat Yourself. The last one comes with a nifty acronym as well, DRY.

The problem is, not everything is good dry. Firewood and tinder work better dry, but a dry aquarium? And which of the standards is better, convention or DRYness? According to Dr. Heinz M. Kabutz DRY should win, at least if you extrapolate from the vendetta he has against a very common convention in Java today, the static final LOGGER, where the category of the logger is the full name of the Java class it is in.

His solution to me lacks some real world (i.e. production tested) sensibility. His final solution is to use a parameterless logger factory class. That doesn't sound so bad, until you look under the covers. To determine which class to make the category from, he creates an exception and takes the first element of the stack trace and unwraps the top element of the trace to get the calling class name.

He says that the approach feels like there is some law against it. I've heard it called a code smell; if it feels like you are doing something wrong that could be done a different way, you probably are. This approach won't entirely kill the server. The exception stack trace overhead will only occur during class initialization and will in effect only be felt on the first hit or application startup. If I were to write code like that is would be like giving my toddler the same milk in the morning he went to bed with the night before: likely not lethal but it smells (and kinda chunky too).

There are other ways to do this, one is to use annotations and write an annotation pre-processor. This turns it into a compile time injection field: @InjectLogger static final Logger LOGGER;. no messy initialization code either. Injection is quite trendy, and so are annotations. (Implementation is left as an exercise for the reader, academic speak for "I'm not doing it here").

But in the end, what is so wrong with having private static final LOGGER = new Logger(ClassName.class.getName()) at the top of every file? Has DRY become and end to itself? If you want to get pedantic about it even declarring a logger in each class is repeating yourself. Your language should be smart enough to just add the logger everywhere you are using it, you know, like a mix-in or something.

This is one of the few examples of Coding By Convention you are likely to find "in the wild," mostly because it just works. Yes, this allows for cut and past errors where you leave in some other class as the seed class, but you can write a PMD rule for that. And convention that can be verified by static analysis in my book is a convention that doesn't need to be dried out.

January 11, 2007

Null Handelers and Null References

Stephen Colebourne has published two interesting ideas that I would like to see make it into the next JDK, Null-Ignore Invocation and Null-Handlers.

The first one isn't new, Groovy has Null-Ignore Invocation but calls it Safe Navigation. The syntax Stephen proposes is to use the Sharp Hash as an operator. i.e. foo#bar() . But I much prefer the Groovy way to do it, foo?.bar() . The ? part of the operator implies to my English-centric mind that there is some question as to whether or not it will be called, and the the dot shows it is a feild or method reference.

The second idea I think is the most interesting, that of a Null handler. This is a similar Idea I came up with while daydreaming in my sophomore Data Structures classes nearly 10 years ago, but I never wrote it down or published it because I thought I'd be laughed out of academia. That was when I thought it wasn't going to take me 13 years to get a B.S., just 8 years.

The idea to me is also very elegant as well in it's implementation. I am sure there are comments that can be made about it obscuring real values of fields. And it will need to be used judiciously (as in likely not in the java.util collections framework). But it can speed up alot of standard error checking. The best part IMHO is that null handlers are they are only called when safe navigation is invoked. The programmer intended for strangeness to happen when the values are null.

This is one of the first real innovations in a while that Java can do that doesn't just steal from another language (not that it's bad, but all the time?) Too bad its coming from outside of the Ivory walls of Sun. Even with OpenJDK it's going to have to fight it's way through the JCP process to get canonized.

About Java

This page contains an archive of all entries posted to ... And They Shall Know Me By My Speling Errors in the Java category. They are listed from oldest to newest.

Inst.Ant is the previous category.

Meta is the next category.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33