The Java Tutorials' Weblog

pageicon Friday Jul 13, 2007

Reworking the IconDemo

During the JavaSE 6 update to the Swing Tutorial, a decision was taken to convert a number of the old applets to stand-alone applications. We also converted the majority of them to NetBeans projects.

I got to convert the IconDemoApplet. It used to look like this:

the original icon demo applet--you may find it in an archive somewhere
«IconDemoApplet»

I changed it into the IconDemo application, which now looks like this:

the new icon demo application
«IconDemoApp»

The IconDemo is now launched with Java™ Web Start—just click the “Launch” button below (you may need to download JDK 6). To compile and run the example yourself, consult the example index from the Swing Tutorial pages.

Launches the IconDemo example

The first step was to replace the acquisition of the image files. In the applet, this was handled by the <applet> tag in our HTML code:

<applet code="IconDemoApplet.class" ... >
    <param NAME="IMAGEDIR" VALUE="images">
    <param NAME="IMAGE0" VALUE="stickerface.gif">
    <param NAME="CAPTION0" VALUE="Sticker Face">
    <param NAME="WIDTH0" VALUE="230">
    <param NAME="HEIGHT0" VALUE="238">
    ...
</applet>

We replaced this with an embedded table pointing at the image files:

String myargs[] = {
    "sunw01.jpg", "Original SUNW Logo", "300", "200",
    "sunw02.jpg", "The Clocktower", "275", "220",
    "sunw03.jpg", "Clocktower from the West", "268", "195",
    "sunw04.jpg", "The Mansion", "315", "200",
    "sunw05.jpg", "Sun Auditorium", "330", "205"
};

and a pre-defined directory:

String imagedir = "images/";

The next step was to design the application. Rather than working with the old applet code, I used the NetBeans GUI Builder.

detail of NetBeans window
«NetBeans detail (click for 1020×746 full screen) »

With the GUI Builder, I was able to create a clean symmetrical layout. I could have even placed the picture count, captionLabel, between the two buttons, nextButton and previousButton.

The usual working method of NetBeans and its GUI Builder is to create a java file for your layout and a seperate java file for your logic. This is a clean way to split your logic from your display. If I was creating the IconDemo from scratch, I would have elected to do it this way.

However, my task was to convert an existing applet into an application. I therefore took the source code that GUI Builder generated and cut and paste it back into the original applet code. I had to change a number of the extended paths NetBeans created (it uses the full path to the class it's calling rather than depending on the import statements at the top of the file—probably a wise design decision) to simpler paths, for example:

nextButton.setBorder(javax.swing.BorderFactory.createEtchedBorder());

to:

nextButton.setBorder(BorderFactory.createEtchedBorder());

Not a huge change, but one that makes my source a little easier to read.

The original applet code had a hand-created layout. I tried to take the NetBeans code to copy and paste into the structure provided, but it was too confusing to match too completely different coding methods. Instead, I simplified its generated paths then pasted the entire code block into place:

// Lay out the GUI (taken from NetBeans code)
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
    layout.createParallelGroup(GroupLayout.Alignment.LEADING)
    .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
    .addContainerGap()
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
    .addComponent(numberLabel, GroupLayout.DEFAULT_SIZE, 438, Short.MAX_VALUE)
    .addComponent(photographLabel, GroupLayout.Alignment.LEADING,
        GroupLayout.DEFAULT_SIZE, 438, Short.MAX_VALUE)
    .addComponent(captionLabel, GroupLayout.Alignment.LEADING,
        GroupLayout.DEFAULT_SIZE, 438, Short.MAX_VALUE)
    .addGroup(layout.createSequentialGroup()
    .addComponent(previousButton, GroupLayout.PREFERRED_SIZE, 144,
        GroupLayout.PREFERRED_SIZE)
    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 150,
        Short.MAX_VALUE)
    .addComponent(nextButton, GroupLayout.PREFERRED_SIZE, 144,
        GroupLayout.PREFERRED_SIZE)))
    .addContainerGap())
);
layout.setVerticalGroup(
    layout.createParallelGroup(GroupLayout.Alignment.LEADING)
    .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
    .addContainerGap()
    .addComponent(captionLabel)
    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
    .addComponent(photographLabel, GroupLayout.DEFAULT_SIZE, 308,
        Short.MAX_VALUE)
    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
    .addComponent(numberLabel)
    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
    .addComponent(nextButton, GroupLayout.PREFERRED_SIZE,
        GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    .addComponent(previousButton, GroupLayout.PREFERRED_SIZE,
        GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
    .addContainerGap())
);
pack();

Testing and debugging took only a short while (and most of my issues were the pre-release Java SE 6 version that's available for Mac OSX).

My concluding recommendations: don't do it this way. Instead, use the full power of NetBeans to both give you a clean layout and an environment within which to build and test your project.


Note: The photographs used in the IconDemo application are copyright ©2006 spriggs.net and licenced under a Creative Commons Licence.


-- Grif Rosser

Comments:

Looks much better! Although I will miss my son's picture being in the demo. :-) One suggestion: turning on anti-aliased text will make it look even nicer.

Posted by Jeff Dinkins on July 16, 2007 at 03:56 PM PDT #

the window lost its title in the conversion. Is that expected?

Posted by fred on July 17, 2007 at 12:32 AM PDT #

Why must I have Java 6? I am on a Mac where Java 6 is still missing. I can't see anything you can't do with Java 5. Wouldn't it be possible to compile and deploy it for Java 5?

Posted by Christian Beer on July 17, 2007 at 01:27 AM PDT #

IMO the app looks like it hasn't gone through any kind of GUI design. And you have created GUI layout code that is 100% not readable by a human. Please make the code accessible to people not using NetBeans. How about making the arrows a bit smaller (like half). The buttons some 75 pixels wide and preferrably use anything but Ocean. OS X would be nice but any platform LAF would do. There also needs to be more white space around everything and the whitespace below the buttons are changing depending on picture height which isn't all that nice. If Java is ever going to make it on the desktop at least the tutorials needs to show something that doesn't look like it's been made by server guys. ;)

Posted by Mikael Grev on July 17, 2007 at 01:49 AM PDT #

Yeah, and how about changing the "HTML Syntax: Allowed" to "HTML Syntax: Required, or you will not get any white space at all". :)

Posted by Mikael Grev on July 17, 2007 at 01:51 AM PDT #

I think this looks very complicated for a simple demo.

Can I request you to avoid this over reliance on netbeans please ??

When i started java, i took tutorial because it was simple, and to the point. If somebody showed me this code, then i wouldn't have switched.

Posted by Viswanath on July 17, 2007 at 02:29 AM PDT #

Your code is un-readable, and un-changeable. I would recommend avoiding Netbeans for examples. Isn't this 3-line Border layout?

Posted by guest on July 17, 2007 at 04:56 AM PDT #

1) If you move from one image to another the buttons move up and down, making it difficult to repeatedly hit Next Picture 2) I agree with others that while Netbeans' GUI editor is amazing it might be inappropriate for example code. Your first priority when writing an example for beginners should be to make the thing as short and readable as possible.

Posted by Gili on July 17, 2007 at 06:16 AM PDT #

While I appreciate the effort to update the tutorials. The reliance on group layout seems inappropriate in this demo. The ~30 lines of code for the group layout implementation can be done in ~10 with BoxLayout.
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(captionLabel);
add(photographLabel);
add(numberLabel);
JPanel buttonBar = new JPanel();
buttonBar.setLayout(new BoxLayout(buttonBar, BoxLayout.X_AXIS));

buttonBar.add(previousButton);
buttonBar.add(Box.createHorizontalGlue());
buttonBar.add(nextButton);

add(buttonBar);
The only other code is to call
setAlignmentX(Component.CENTER_ALIGNMENT);
on the first three comments to center them. Netbeans supports BoxLayout. Why is this using GroupLayout?

Posted by aberrant on July 17, 2007 at 07:01 AM PDT #

[Trackback] Blogs doom high-value online media. Or not. Also:
Weblogs: HK2 modules, Mac upgrade disaster, and I18N ResourceBundles
Featured Podcast: Loopt the Social Networking Application
Java Today: IDE Shootout reca...

Posted by Chris Adamson's Blog on July 17, 2007 at 08:03 AM PDT #

Sad to see that Sun continues an old tutorial tradition. Instead of using the tutorial examples to also demonstrate best practice, they demonstrate very bad practice.

Among them:

* Very ugly GUI, violating Sun's own style guide, e.g. regarding the distance between components, usage of borders, etc.

* Hard-coded sizes in the layout. Bad, bad, bad, bad, bad.

* Requiring a special tool like NetBeans. I don't know if this is a fanboy or a political thing. Whatever it is, it is bad. Don't you have any professional educators at Sun who can tell you a little bit about pedagogic principles?

* Mishandling of text updates in an event handler. From http://java.sun.com/docs/books/tutorial/uiswing/examples/components/IconDemoProject/src/components/IconDemoApp.java

    //User clicked either the next or previous button
    public void actionPerformed(ActionEvent e) {
        //Show loading message
        photographLabel.setIcon(null);
        photographLabel.setText("Loading image...");

That text will not be shown right when set here! The comment is misleading. You are still in the EDT. updatePhotograph(Photo photo) later cancels the setting out, in case the program flow for already loaded images is used.

In case the loadImage() branch is used instead, the text will be rendered since the event handler returns. However, it should be the loadImage() method setting the text, and not preactively the actionPerformed() method. For symmetric reasons it should also be the done() method in loadImage() later canceling the message, instead of relying on the flow of execution in the invoked updatePhotograph()

This label display logic is very bad style at best. Such junk code should not be done in a tutorial. Yes, I consider it junk code, particularly for a tutorial. I would not even accept it in rushed production code.

* Unexplained optimization claims like

     // When running  using Java Plug-in, getResourceAsStream
    // is more efficient than getResource

and then incredibly complicating the code of createAppImageIcon() is also not beneficial in teaching people.

createAppImageIcon() could be a few easy to understand lines instead of the current mess:

ImageIcon i = null;
URL url = new ... getResource(...);
if(url != null) {
  i = new ImageIcon(url);
} else {
...
 

Oh, by the way, what is the point in making the method static?

Oh, oh, by the way, the usage of a fixed-size buffer which must match be large enough to hold the largest image is also extremely bad style.

* Nesting the Photo class inside class IconDemoApp also doesn't buy you anything.

* The writing style for the // comments is bad. This is typical for IDE-only users. In an IDE one can still read comments interspersed without visible separation into the code due to syntax highlighting. But they look very bad when one (a scholar ...) studies the code as-is. You really hate your scholars, do you? Instead of

sdfjsdlkjfsdklfl
sdfsdjfsldjfkl
// sdkljfklsdj
sdkljfklsdjflk
lkfhjsdfshf 
Please write
sdfjsdlkjfsdklfl
sdfsdjfsldjfkl
//
// sdkljfklsdj
//
sdkljfklsdjflk
lkfhjsdfshf 
* Further, for $DEITY's sake use JavaDoc comments for commenting classes and fields. Please! Please demonstrate best practice, not sloppy 1337 5crip7 h4cking sty1e.

I could go on for some time. But Sun hasn't cared for six major releases. Please let the examples be done by professionals, not by the intern. Please follow Sun's own rules (JavaDoc, GUI style guide, etc.). Please don't add optimizations if this isn't the point of the demo. Please get the code properly reviewed.

If not, then at least don't be surprised that there are so many badly done GUI applications out there and that so few people get Java GUI programming.

Demo code like this perverts the goal of the whole tutorial. Assuming of course the goal is to teach people proper Java GUI programming. The goal should not be to squeeze as many effects in as few lines of code as possible, or to get away with the most simple constructs that just happen to work accidentally.

Posted by Kauer on July 17, 2007 at 10:25 AM PDT #

Amen to all that! This example is awful, for all the reasons listed above.

Posted by Adam on July 17, 2007 at 12:12 PM PDT #

If this is to serve as an example, please make it at least into something another programmer can study and learn from. What can I learn from this example? How to make a crappy Java GUI app using a UI Builder in ten minutes?

Posted by Jerry on July 18, 2007 at 07:29 AM PDT #

Ah, more good reviews for GroupLayout. When can we remove it from the JDK being that it is useless?

Posted by alskiontheweb on July 18, 2007 at 07:40 AM PDT #

Bad examples made worse. Please remove GroupLayout, which is astoundingly unsuitable for an example. Altho I'm an enthusiastic NetBeans user, making examples dependent on it (at least in it's current form) is bad. Ditto on other issues. Sad, sad, sad.

Posted by Fred on July 18, 2007 at 03:23 PM PDT #

Bah, Well I posted the link, but to explain I decided to rewrite the demo myself. Hopefully it's an improvement.

Posted by aberrant on July 19, 2007 at 12:33 PM PDT #

I am hoping that the tutorial team heeds to all the advice above
Buahahaha! You are new to Java and "The Sun Way" of doing GUI things, aren't you? The Sun Swing team gives a ....... .... about feedback. They are a bunch of primadonnas thinking they are god's gift to programming. For years they had a lead clown who was bussy writing fancy demos and books to demonstrate his greatness but couldn't come around to fix the bad Swing demos that come as part of the JDK. Or while we are at it, the tutorial examples.

Hey, they were even willing to ship a completely broken widget in Java 6, one that is in Swing since Java 1.2, because they were to lazy to cut through the red tape to get a fix for something they broke into the code.

Or look at this "discussion". Do you see any reaction from Grif Rosser? Do you see a discussion? I don't. Six days and Mr. Rosser doesn't consider us worthy. This is so typical for them. They don't talk to mortals. All they do is to issue patronizing statements. Or look at the rejoicing in the first comment. One Sun Swing guy congratulating another Sun Swing guy for a job badly done. Boy are they full of it.

They don't care. They never did, they never will.

Posted by Kauer on July 19, 2007 at 12:33 PM PDT #

I am hoping that the tutorial team heeds to all the advice above and removes netbeans dependency in the tutorial

Posted by Viswanath on July 19, 2007 at 12:33 PM PDT #

I do apologize for the silence on my end. This blog posting went up the day before I departed on vacation -- a blissful week of no internet access. Thank you all for your comments, especially aberrant for fixing my hack of a hack. I wish we had the resources to provide better examples. I hope the community will support us in trying to improve the tutorial

Posted by Grif Rosser on July 23, 2007 at 01:47 PM PDT #

update to the Swing Tutorial, a decision was taken to convert a number

Posted by runescape money on November 10, 2007 at 06:39 PM PST #

It’s very good article. Great site with very good look and perfect information. I like it too.

Posted by gold price on June 03, 2008 at 07:56 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed

« November 2009
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
12
14
15
16
18
19
20
21
22
23
26
27
28
29
30
     
       
Today

Feeds

Search this blog

Links

Weblog menu

Today's referrers

Today's Page Hits: 304