« Previous month (Jul 2005) | Main | Next month (Sep 2005) »

20050829 Monday August 29, 2005

Copyright Folding

Most source files have copyrights on them. When opening a file you have to scroll past the copyright, and the import statements, before you get to the interesting part - the class javadoc comment. Most IDEs now have a way to have the import section automatically folded. But what about the copyright section? It's often quite large - in Apache source code for example the copyright is 50 lines long - that's more than a full editor page. Code folding to the rescue!

NetBeans has support for user-defined folds. In Creator, we use this to hide the bean getters and setters, since that segment of code is never interesting to a user, but nevertheless should be part of the source file and discoverable and editable by expert users.

You can use this facility yourself to create arbitrary folds around code. One obviously place to do this is around your copyright sections. These are ideally suited because a copyright is a piece of static text which is replicated in each and every source file. Just change your copyright template once, and from now on all new files will have folded copyrights. In the Creator source base we have marker tokens in the copyrights such that we can update the copyright sections in an automated yet safe way.

(Note: In NetBeans 4.2 you can set an option to have the first comment in the document automatically folded. This will also achieve copyright folding if it's the first comment in the document. Of course, you can apply folding to other logical portions in your document too - there's nothing comment-specific about user folds.)

Here's how user-defined folds work: Simply add two Java line comments (//), one to indicate the start of the fold, and one to indicate the end. The comment itself has an XML-like syntax:

  // <editor-fold defaultstate="collapsed" desc="Your Fold Comment">

You can leave out the defaultstate attribute if you don't want the fold to default to a folded state when the file is opened. Obviously the desc field is used to supply a description which is shown when the section is folded. Note that the comment isn't truly in XML format in the sense that you cannot reorder these attributes.

Let's see how this works in practice. Here's one of my source files, using the short copyright version. Most other file licenses I've seen have a much larger copyright than this, so the folding payoff is higher.

First I simply add the begin and end folding comments as described above around the code I want folded.

Now, when I open the file (or collapse the file by clicking on the - in the margin), the copyright takes up just a single line, and the fold description is displayed instead:

Finally, note that you don't have to expand a fold to see what's inside - simply hover the mouse over the folding box and the contents are displayed as shown here:

(2005-08-29 21:15:16.0) Permalink

20050827 Saturday August 27, 2005

Say Hi To Marco

Say hello to Marco "Deployment" Walther - another developer on the Creator team. He has just started blogging.

In addition to being in charge of all the deployment machinery in Creator, he's also the guy to go to if you have any Linux questions. Which should be obvious from his second post!

(2005-08-27 00:04:06.0) Permalink

20050826 Friday August 26, 2005

Fly your own airplanes!

I was just going through my buglist for the webform designer in Creator, and came across this request:

Synopsis: way to turn off GIF animation in designer
Description: Maybe this is simply an IDE option for Visual Editor. I'm inclined to think the default should be off. They can be pretty distracting...

In case you didn't realize it, if you insert animated gifs in your web page, the designer will preview the animation at designtime too. Here a user is asking for the ability to turn this off, since animated gifs are distracting.

My first thought was: You are about to inflict annoying animation on your users, so shouldn't you have to put up with this yourself? It's a bit like the reverse dog food test. Or, more recently at Sun we like to say we "fly our own airplanes" - e.g. use our own products. I'm not sure where the saying comes from, but clearly as a customer you have more confidence flying in a plane knowing that the people who built the plane also fly it. The reverse situation is that if you don't want to fly your own airplanes, you shouldn't force your customers to either. And that's what asking for distracting images to be hidden at designtime sounds like to me.

By that line of reasoning I guess I should implement designtime support for the <blink> tag as well! And it raises the question of what I would do if users requested a new JSF component which creates a pop up ad in user browsers, one smart enough to defeat most popup blockers.

Making it easy for people to create annoying web apps feels a bit like making weapons... on the other hand I'm probably getting way out of hand here. Simple banner ads are used to pay for web sites that are free for use, many of which I use. And of course, even Creator has been advertized using banner ads.

(2005-08-26 11:45:02.0) Permalink

20050822 Monday August 22, 2005

Portlet Demo

Navaneeth Krishnan has created a portlet demo using Creator 2 EA, showing how the basic Creator WYSIWYG design of web apps applies to portlets as well. Check it out.

By the way.... Creator 2 EA Refresh, coming soon to a download center near you... (sorry, can't be more specific with dates)

(2005-08-22 08:38:59.0) Permalink

20050821 Sunday August 21, 2005

Submit Query? What Query?

You've just built a web form. Users type in a message in a text area, then click on a Submit button to send the message. You run the application, and .... what? The browser has changed your Submit button into "Submit Query"! What Query? There's no query here!

We've had some bugs filed against Creator on this. In some browsers (notably Mozilla and Firefox), submit buttons change their labels into "Submit Query".

Form built in Creator Form deployed and shown in Firefox

This is a symptom of a much deeper problem, which I'd like to discuss in this blog entry.

Let's say you drop a button. This will create a button, but no label has been set on the button - look at its text property in the property sheet. A button component with no label set will render to this HTML:

    <input type="submit" />

This will not display a blank button (which you can achieve by adding value="") - all browsers will pick a default label! Internet Explorer, Safari, and most other browsers use the label "Submit". Mozilla/Firefox on the other hand, uses "Submit Query" - which I think is an odd choice. Creator has to choose something - it cannot show the "right" thing since that will depend on which browser the application is viewed with - and there could be a different browser for each user accessing the same web page!

There is an easy fix to this - go and set the value of the button to a specific string, like "Submit" (or Send or Order or Lookup or whatever makes sense on the current page.) In recent dev-builds of Creator, we've made some changes such that you don't end up in the scenario of an unset button as easily.

But this raises the question of why we don't set the text to some default value automatically. For a button, we probably could (and have - see above). But for components like Static Text, we can't. The reason for that is that it would make it very hard to set the text value from code!

Let's say you've dropped a Static Text component on the page, and you've set its text attribute to "Hello World", so your JSP contains this:

    <ui:staticText text="Hello World" binding="#{Page1.staticText1}" />

Now you're trying to do something clever in your Java code, for example setting the text to include the name of the logged in user:

    // In Page1's constructor
    staticText1.setText("Hello " + getUserName());

This won't work! Note that there is a conflict of definitions here - the JSP says that the text should be "Hello World", and the page constructor says that the text should be "Hello Tor". And the JSF spec says:

The JSP attribute wins.

You might try to move the above code into the new init() method, or even the prerender() method, but that won't help - the JSP attribute setting will still win the first time the page is displayed.

The only way to get your Java code to be able to set the static text, is to remove the attribute setting from the JSP.

And this is precisely why, when you drop a Static Text component on a page, we don't automatically set it to some "default" value. We could (and in early devepment versions did), but most users are not aware of the JSP vs Java conflict, and did not understand why their Java code which set labels didn't work. Granted, in most cases you don't want to set the label from code - you'll use value binding expressions instead. But it's an important enough scenario that we don't want to get people too frustrated when they run into this.

So, the solution we've settled on is using what we call shadow text*. When a component is rendered at designtime, and it's missing a value that's vital (but one we don't want to set to avoid conflicts), we render the component text in bold italics instead, using a default label such as the type of the component. This shows you that there is a component here (since otherwise a static text with no actual text is rather hard to read...) and allows you manipulate it. But it's also obvious, or at least we hope so, that the component is not configured with normal text. As soon as you set a specific value for the property, it's rendered in the usual way.

Here's how this looks for buttons, static texts and hyperlinks - the first row shows components with shadow text:

*: I don't think this is "official" terminology - it was simply called that in a recent bug report, and once I realized what they were describing I figured it's as good a name as any. Before that I had called it "uninitialized/bold/italic text" which is a mouthful...

(2005-08-21 22:54:02.0) Permalink Comments [2]

20050817 Wednesday August 17, 2005

In Prague

I'm in Prague this week, visiting the NetBeans team. NetBeans of course is the foundation Creator is built on top of. We're working closely together to make sure that we get everything we need, and to align work and vision such that we're heading in the same direction.

I've seen some of the new stuff coming in the next release of NetBeans - 4.2. It's documented in the this document, which is similar to the "New and Noteworthy" documents Eclipse publishes for their milestones. If you're wondering what "Q-Build" refers to in that document, a "Q-Build" is a "quality-build". It's a promoted build (roughly weekly) from the nightly builds, that has had some QA analysis applied to it and showstoppers fixed. There's a separate document for new and noteworthy features in the mobility pack.

...and of course, I saw some cool new stuff that hasn't been integrated (and therefore listed) yet!

Prague is a beautiful city. I have been here many times before (I think this is my eighth trip) but it never ceases to impress. I haven't done any sightseeing on the last trips so I think I'll go back and visit the castle if I get some time Friday morning. The best way to get around is to use the underground. The metro runs deep below the ground, so to get down to the tracks they have these really really long escalataors -- see the picture on the right (and note that it continues up above the lighting fixture). On my first trips here I was amazed at how fast the escalators were running! They don't seem as fast anymore and I was just told yesterday they have deliberately tuned back the speed...


(2005-08-17 06:27:21.0) Permalink Comments [9]

20050814 Sunday August 14, 2005

Dynamic Titles

Craig has resumed blogging. In his first new blog entry he's talking about the new Data Provider APIs in Creator 2 - which allow you to drag & drop not only database tables, but EJB methods, and web services to automatically data bind to visual components.

The Data Providers also allow you to map the components to your own data structures - or connect the components to other persistence technologies or frameworks. One of my earlier blog entries talked about how to do this with the standard JSF data table in Creator 1.0. With the new data providers it should be a lot easier. However, we have some EA bugs which makes it a bit tricky at the moment. Perhaps Craig's next blog will show how to do it specifically - if not, I'll take a stab at it.

It's been a really great week in Creator engineering. We've been doing memory profiling and have found some major culprits. We're not done with the performance work though.

I'll finish this entry with a tip: How to generate dynamic titles for your pages. Page titles of course are typically shown by browsers in their window titlebars - and they usually also become the default bookmark label.

This used to be tricky (in Creator 1.0). In Creator 2, all you need to do is locate the Head component in the Outline. Notice that it has a Title property. All you need to do is set this property to a value binding expression, for example #{Page1.title}, and then add this method to Page1's java file:

    public String getTitle() {
        return "Dynamic Title " + new java.util.Date().toString();
    }

Title bar screenshot

For those of you who are using Creator 1.0, the way you need to do it is to add the same method to the page bean, but then switch to the JSP file, and locate the <title> tag. Remove the text which is in there, and add this:

   <h:outputText value="#{Page1.title}"/>

Note that this output text doesn't have an id, and doesn't have a binding attribute. That's important, because this means that the output text will emit the text returned by the value binding expression as a simple text string, rather than wrapping it in a <span> inside the title element as it would otherwise do.

(2005-08-14 00:22:30.0) Permalink

20050811 Thursday August 11, 2005

"To Die For" Style Editing

When we shipped "Reef" - a big update to Creator 1.0 last December, one of the new features was a CSS property editor. In the "What's New In Reef" feature overview posted on the web site, the CSS support was described as a "To Die For" Style Editor.

That was jumping the gun a little. We had in development really good CSS support, but only one minor part of that was actually added into Reef. Of course, it's now available in Creator 2 EA. I was just asked by a user how to edit full stylesheets, not just the style attributes of components. And this is precisely what the new CSS editing support is for: full fledged CSS file editing.

So without further ado, let me introduce a screenshot of what happens when you open a CSS file in Creator today (click for full image):

CSS Editing Screenshot

There are many things to notice here (not all are shown):

Something fun to try is to use this facility to explore the stylesheet that's built into the theme you see applied to the new Creator components -- gradients on buttons, etc.

Go into the Project Navigator, look under Libraries, locate the Default Theme item, expand it, then expand the css package, and open the css_master.css stylesheet. As you can see it's not a trivial stylesheet, clocking in at over a thousand lines!

(2005-08-11 23:24:10.0) Permalink

20050808 Monday August 08, 2005

Creator 2 Review

eWEEK Labs has reviewed Creator 2 Early Access. My favorite quote has to be this:

What will lose that audience in moments, though, after 14 years of conditioning by Microsoft Corp.'s Visual Basic and its many imitators, is anything less than full drag-and-drop convenience. Having reviewed a decade's worth of Java tools that have tried to do this with varying success, we feel as if JSC2 is finally there. Not only is it easy to do things correctly in JSC2, but it's also - and this is at least as important - difficult to mess things up. We're used to finding ways to break the multilateral links among visual and code-focused tools, but JSC2 proved immune to our deliberate attempts to confuse it.

We do know about the bugs and performance issues in the EA bits though. Believe me, we know intimately: we're in a bug fix phase now so every day each developer starts by looking over the personal bug list and attacking it in priority order!

I don't have the bugids memorized - but at one point I actually did! Early on in Creator development, when we were just a small skunkworks project named Rave, we were using Scarab for bug tracking. One of the nice things about Scarab is that the bug ids were easy to remember; they had the subsystem name plus a 3 digit number after it. Thus, you'd have bugs like WEBFORM152, or WINSYS250. These bugs, particularly the notorious ones, were easy enough to remember by id.

Every week towards the end before our first public demo, we'd do a team run-through with that mornings bits, testing the scenario we were planning to show. On several occasions we'd hit a glitch that I recognized as a duplicate of one particularly nasty window system bug, so I'd call out "That's just good old WINSYS106!".

I don't have the bug ids memorized anymore. Not only because we're using Sun's enterprise bug database where bug ids are seven digits long, but I'm only looking at my own bugs these days, and I don't want to get familiar with them, I want to squish them before we get acquainted...

In other news, I saw this article on news.com: Sun funding Derby database development. So hopefully the database 5Mb limit days are not here to stay...

(2005-08-08 17:40:59.0) Permalink Comments [1]

20050805 Friday August 05, 2005

NetBeans versus Eclipse!!

There's no better way to get attention than with a subject like that! There's a new JavaCast podcast out. This is a new "weekly radio program" on Java and what's happening in the Java world. If you have iTunes, or other podcasting software, it's trivial to subscribe to the weekly feek - just follow the links from the JavaCast page. Of course, you can just listen to the MP3 file directly.

So why did I use such a controversial subject for this blog entry?

In this week's JavaCast, I'm the interview subject. One of the things I talk about is the "IDE war" - addressing why I don't think NetBeans should give up just because Eclipse have signed up so many partner companies. Other things I address is Class Library Development versus Component Based Development, I talk about my observation that many server-side framework pundits seem to have tools phobia, and of course I talk a bit about AJAX and about Creator.


(2005-08-05 13:04:29.0) Permalink Comments [1]

20050803 Wednesday August 03, 2005

Authorization servlet filter for JavaServer Faces

Alexis has written a blog entry on how to add an authorization servlet filter for JSF. This will allow you to prevent users from accessing your web app pages directly via URLs, bypassing your navigation logic. Check it out! Alexis works at Sun France and was our host during the trip to Paris last fall. He's been a really great tools evangelist!

In other news, some of you have asked when Creator 2, now in Early Access, will ship. David Folk from marketing responded.

(2005-08-03 22:17:49.0) Permalink Comments [1]

20050802 Tuesday August 02, 2005

Centering - Finally Finally

I finally implemented support for the HTML <center> tag last night. I had resisted doing that since none of the components are using it, and besides, <center> is a deprecated tag. However, some users have been asking for it - and I discovered that the new Alert component -does- rely on <center>'s evil twin: the align="center" attribute on <table> tags. So I decided to implement it. But don't take this as encouragement to ask for support for the <blink> tag!

If you've read this blog for a while you might remember that I made a quick attempt at implementing center before. The "correct" way to center in CSS is to set the horizontal margin properties to auto. However, simply aliasing <center> to auto margins has other side effects, so I backed that change out.

The solution I settled on is what Mozilla seems to be using: a new internal-only value for the text-align property. In Mozilla's case it's "-moz-center", and you can see it if you use their DOM inspector to look at elements inside a <center> tag. Now, the <center> tag, as well as the align="center" attribute, will set text-align to -rave-layout, and the box dimension code looks for this property and handles centering as you'd expect.

It seems to work - here's my Google test page finally properly centered (click for full size):

You can see how it used to look in this old blog entry. Quite a bit already centers simply through use of text-align: center, but notice how the menu above the textfield is wrong.

(2005-08-02 08:44:45.0) Permalink

20050801 Monday August 01, 2005

Remove duplicate and unused entries from your property files

Three years ago or so I realized the code I was working on had lots of "stale" Bundle.properties entries. These are bad because not only do they create more work for localizers who translate these files to other languages, but unused keys also incur more runtime overhead.

It's easy to end up with unused key entries. Perhaps you first comment out some code which is referencing a bundle key - but you don't comment out the bundle key. Later the commented out code is removed, but the key in the property file is still there.

To find these I wrote a really hairy Unix command; something like this:

 find . -name Bundle.properties -exec cat {} \; | /bin/grep "=" | sed
'/^#/d' | sed '/^OpenIDE-Module-/d' | nawk 'BEGIN { FS="=" } {print $1}'
| sort | uniq | nawk '{system("/bin/fgrep " $0 " `find . -name
\"*.class\" -o -name \"*.xml\"` \| nawk \"BEGIN \{i=0\} \{ i++ \} END \{
if \(i==0\) print key \}\" key=" $0)}' | /bin/xargs -n 1 -I @ grep @
`find . -name Bundle.properties` 

I recently figured it was time to check my Bundle files in my current code - so I used a tool I had seen Tim Boudreau commit into NetBeans CVS. It's a standalone tool, not integrated as part of the IDE. But it's quite useful.

The tool is called "Bundlizer", and is found in NetBeans CVS under contrib/bundlizer. Just load it as a project in NetBeans and run it and you'll get the GUI (see screenshot below). Or, use the executable jar I just uploaded here. Use at your own risk.

The program does a couple of useful things:

When you're done it saves the resulting file.

You'll definitely want to check its results. Discovering if a key is unused is not something which can be done accurately. Obviously, if your code is doing something fancy, like computing keys rather than looking them up directly, the program will not figure that out and will think the keys are unused. One common case of that in my own code had to do with keys that are referenced from XML files. For example, NetBeans plugin code declares menu items in an XML file, and these pull keys out from a bundle. There are other ways the program can be tricked too.

Consider yourself warned. However, the program is extremely useful at identifying candidates for removal. You'll probably see some keys in your own files and go "oooooh yeah.... that's still there? Guess I forgot to remove it!".

Here's a screenshot of the utility in action (click on it for full size):

I suspect the reason the utility has not been "finished" and moved into the IDE as part of the Resource Bundle support, is precisely because discovering unused keys is such an inaccurate science. If anyone would like to take a closer look at the code and try to make it smarter, please do! I made a couple of tweaks for my own purposes before running the tool. Here's the patch I applied - the first diff makes it look in XML files for key references; the second makes the tool less unhappy when it encounters non-comment lines that don't contain and = sign:

Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java
===================================================================
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java,v
retrieving revision 1.3
diff -u -r1.3 BundlizerPanel.java
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java   7 May 2004 23:48:40 -0000        1.3
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/BundlizerPanel.java   2 Aug 2005 05:45:46 -0000
@@ -449,7 +449,7 @@
      
     private class JavaFilenameFilter implements java.io.FilenameFilter {
         public boolean accept(java.io.File file, String str) {
-            return str.endsWith ("java");
+            return str.endsWith ("java") || str.endsWith("xml");
         }
     }
      
Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java
===================================================================
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java,v
retrieving revision 1.2
diff -u -r1.2 Properties.java
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java       1 May 2004 13:52:24 -0000        1.2
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/Properties.java       2 Aug 2005 05:45:46 -0000
@@ -115,6 +115,10 @@
                 }
                 String keyValuePair = line;
                 int equals = keyValuePair.indexOf ("=");
+                if (equals == -1) {
+                    continue;
+                }
                 assert equals != -1;
                  
                 String key = keyValuePair.substring (0, equals).trim();
@@ -203,6 +207,9 @@
      
     private boolean isKeyValuePair (String line) {
         int equals = line.indexOf("=");
+        if (equals == -1) {
+            return false;
+        }
         int cmt = line.indexOf ("#");
         return (cmt > 0 && equals < cmt) || (cmt < 0 && equals >= 0);
     }

(2005-08-01 22:27:21.0) Permalink Comments [1]