Monday Aug 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)

Sunday Aug 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...

Saturday Aug 13, 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.

Thursday Aug 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):

  • Code completion on properties and property values. For example, here the caret (right under the mouse pointer) is in the value are for a border-style property, so the completion popup is showing the possible values for that property (solid, double, etc.) along with a visualization of these values.
  • There's a live preview of the style declaration near the bottom right. Let's say you had a style declaration only defining the text color to be orange. In that case, you'd only see sample text, in orange. Here we have a more complex style declaration, setting borders, font weight and size, etc. These rules are all reflected immediately while you're tying in the style declaration.
  • There's also a customizer area on the bottom where you can easily choose fonts, background colors or images, margins, etc. etc. These automatically update the current style declaration with new properties or value updates. Also, as you're tying in the text area, the right values are selected in the customizer.
  • Notice the property sheet on the right - it's showing the properties set for the current style declaration. This is also kept in sync with the other views. (The customizer and preview area, which takes up a lot of space here, can be toggled on and off with a toolbar button, and when it's off the property sheet is pretty useful.)
  • You can navigate styleclasses with the combobox in the editor toolbar.
  • There is Syntax highlighting and Code Folding of style rules
  • There's a Reformat action which reformats the stylerules such that all property declarations are on their own lines; indentation is uniform, etc.
  • There's a style builder dialog which lets you construct new style declarations with more complicated selectors.
  • There's background error checking too.

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!

Monday Aug 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...

Wednesday Aug 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.

Tuesday Aug 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.

Friday Jul 29, 2005

Navigation Wildcards

Most problems in computer science can be solved by adding a level of indirection!

In JSF, navigation is done through an indirection table. Rather than having each button that navigates to another page know its destination, a level of indirection has been added such that the buttons only specify a navigation case name, and then there is a central navigation table which records the actual destination to navigate to for a given navigation case. (A navigation case is simply a short string that describes the navigation intent, like "failure", or "loggedin", or "next" and "previous" in a wizard scenario for example.)

This has some really important advantages. It makes it extremely easy to change the page flow later, since it is not spread out across all the web application pages. The indirection also makes it possible to add a some additional logic to the destination lookup. One such feature offered by JSF is wildcards.

For example, let's say you want to have a Help button. The navigation associated with the help button is "help" - in other words, its action property is set to "help".

  <ui:button text="View Help" action="help" binding="#{Page1.button1}" id="button1" />

Navigation Screenshot We can obviously link this particular button directly to the Help page. That will result in the following navigation rule being added to the navigation rule file:

    <navigation-rule>
        <from-view-id>/Page1.jsp</from-view-id>
        <navigation-case>
            <from-outcome>help</from-outcome>
            <to-view-id>/HelpPage.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>

But what if we had a help button on every page? Would we have to repeat this rule for each and every from-page?

No. This is where wildcards come in. You don't have to specify the source page in the above rule; you can use "\*" instead which means "any" page:

    <navigation-rule>
        <from-view-id>\*</from-view-id>
        <navigation-case>
            <from-outcome>help</from-outcome>
            <to-view-id>/HelpPage.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>

Now, ANY page specifying a navigation case of "help" will result in navigaton to the given Help page.

Wilcards play a very important role with page fragments. A page fragment is essentially a "static" include of a portion of a page: it literally gets copied into the referencing page at deployment time. Thus, if you have a Page fragment (such as a Footer page fragment listing copyrights as well as a Contact Info button), every single page including this page fragment will have the Contact Info button. If you bring up the page navigation editor and zoom a page, you'll see buttons and links from fragments that are included in the page too. However, note that there is only a single JSP for the fragment with the button, even if it's included in multiple pages. Thus, its action property can only be set to one thing. If you drag this button to a destination page, this both adds a navigation rule from this Page and sets the action property of the fragment. This action property will now be seen in all other pages including the fragment too. You cannot set the action property to different values for different including pages. (You can however have different navigation rules for the same action when used in different pages, as discussed shortly.)

Because of this, you usually want to use wildcards when you're using navigation components (like buttons and links) in fragments. This will ensure that regardless of which page the fragment button is clicked from, the same target page is chosen. This will for example ensure that your "Contact Info" button will bring up your page with Address, Phone, and E-mail information regardless of which page the user clicked the fragment button from.

Note however that you don't have to use wildcards with fragments - using normal navigation rules also gives you some really powerful possibilities. For example, if we go back to the Help example, your Footer fragment could have a Help button, but you can bind it to -different- destination pages for each different source page. Thus, you can have context sensitive help!

Unfortunately, the navigation editor doesn't help you with wildcard rules. You'll have to add these by switching to the XML view. Also, wildcard rules are shown as erroneous rules - the arrow flows into the destination pages and show the case names, but the page flows from an error icon. It should flow from a wildcard icon instead.

P.S. If you're wondering why there's a blue border around the left page in the screenshot, that's because my coworker Winston implemented full keybord support for the navigation editor recently, and the blue border signifies that the page is current. Tabbing switches pages, z/u zooms and zooms a page, b adds a button, s selects start page, tab to switch, then e ends and creates link, Ctrl-A adds a new page, etc.

Friday Jul 22, 2005

R.I.P. Red Boxes

One of the really nice things about Creator and JSF is that we're able to provide WYSIWYG editing of components. We do this by actually running the components' renderers at designtime. This does however have one problem: What if the component renderers aren't happy?

Lots of things can go wrong. For example, let's say you have a databound JSF table. If you kill the database connection, the component renderer will abort with a SQLException. Incorrect expression language bindings, missing converters and a whole host of other potential problems have similar issues.

How do we handle this in the IDE? In Creator 1.0, we had the "Red Boxes" scheme, as shown in the first screenshot on the right. In the designer, components which aborted during rendering would be shown partially (as much as possible depending on how far along the renderer got before dying), but all the markup would be changed to have a red background. That way you could sort of see the component if it had rendered enough before giving up. This is better than not showing the component at all, since (1) it makes it really obvious that there is a problem, and (2) it makes the troubled component easy to select so you can inspect the property sheet and try to fix the problem. We also opened the Output window with an error message trying to explain what had happened, and what to do about it.

In Creator 2 this behavior has changed. Instead of the red boxes, you first get an error screen (similar to the one you get if you introduce parsing errors in the JSP, or syntax errors in the Java file). This error screen includes portions of the stacktrace, which in many cases might reveal what the problem is (don't forget to look for a cascaded exception1)

You can also click through to the design view, and now you'll see the component. However, rather than an ugly red box you'll see a small error icon in the component's place along with an error message associated with the render problem. It should also be much better about not repeating the error screen until you've resolved the problem and encounter a new problem (although there was a bug in this area fixed shortly after EA).







Wednesday Jul 13, 2005

com.sun.\* classes in Creator applications

One of the nice people I met at JavaOne was Dave Johnson, the guy behind Roller, which is the open source blog server software we're using at Sun. In this blog entry he describes his recent experiments with learning JSF and using Creator 2:

I was hoping to build a simple JSF front-end for Roller, just for fun. Creator looks great and the form designer works well, but when I noticed how many com.sun.\* classes end up in the generated code I backed off. According to the release notes the whole JSF implementation and com-sun-web-ui-appbase jars are redistributable (...), but the idea of IDE specific code makes me uncomfortable -- especially in an open source context.

The same issue came up last year when we released Creator 1.0 beta. So in this blog entry I'd like to explain why you'll notice a number of com.sun classes in your Java files maintained by Creator, what they're for, and what you can do about it.

Creator 1.0 provided only the standard JSF components (javax.faces). If you drop a command button, you get a <h:commandButton value="Submit"/> entry in your JSP - just like your JSF books tell you.

The big problem is that the standard components are extremely limited. When you build applications using the standard components, you've created a web page that would look right at home in 1995.

In addition, the component set shipping with JSF is limited in functionality. We've gotten tons of requests for additional components: file upload, tree, tabs, calendar, etc. Therefore, in Creator 2 we're no longer focusing on making web applications that look identical to what you'd find in an off-the-shelf JSF book. Instead, we've provided a new component library, consisting of pure JSF components obviously, which have additional value add. Buttons can be configured to be primary or secondary (affects visual appearance), they can be configured to disable themselves when clicked (so you don't get double submits on forms), they follow theme styling, etc. And of course, we have new components like trees and calendars to address those needs. Obviously, if you use these components, your page beans will include references to additional com.sun.\* classes.

Don't despair however - if you want to use the standard JSF components, you can do that - just look in the palette for the component categeory named "Standard". This is where the standard JSF components live - drop these and you'll get your familiar JSF commandButton, outputText, panelGrid, etc. components. To make it easier to spot these in the palette, so you don't grab the "wrong" button for example, all the icons for these components are now tinted blue as shown in the screenshot on the right.

There are a couple of more areas where you wind up with com.sun classes. First, your page and session beans themselves. If you look at your Java files corresponding to your pages, you'll notice that they're very small and simple; you basically have several empty stub methods where you can add code that is run during different parts of the page's life cycle: initialization, render, and cleanup. JSF doesn't make it that easy. That's why we've created an abstract class you can extend (and our page beans automatically do this) where the super class has all the convenience methods you want. For example, your page beans code can simply call getFacesContext() to get the FacesContext object, or it can call getValue to perform value binding expression evaluation. Just look at the code in the ancestor classes to see the PhaseListener magic that is necessary on the programmer's part to make these simple callbacks possible.

So this was a deliberate choice in order to make it really trivial and easy to write "event handlers" for your web component's events, like button presses and text field validations. There is nothing special about this code - its source is fully included and in Creator 1.0 you can simply press Alt-G over the parent class name in the java file to open it. Unfortunately this doesn't seem to work in Creator 2 EA. But the source code is all there; go extract rave2.0/docs/jsfcl-src.zip and you'll see it. (It's in the wrong place which is why the normal IDE facilities for warping to it doesn't work. This will be fixed before ship date.)

There's one final area where you can end up with com.sun classes: data providers. Standard JSF lets you hook its Data Table up to arbitrary data structures (and I've described how before). However, it's pretty inconvenient and not done in a general fashion. In Creator 2 we have a new abstraction layer in the middle, which all components know how to talk to. We then implement these interfaces for a wide variety of data sources. The net result is that you can drop not only a JDBC table, but a web service method or even an EJB method on GUI components, and all the binding is handled correctly. These data provider wrappers can also end up in your code.

So in short, yes, if you choose to use the new components and databinding facilities, you end up with additional com.sun.\* classes in your code. You also get this in the page beans from the app model. Our focus in Creator has been to make web apps easy and feature rich, which resulted in adding some convenience classes around the standard primitives provided by JSF, and of course a new set of JSF components.

As JSF matures there will hopefully be fewer and fewer areas where this is needed.

Thursday Jul 07, 2005

Code Completion in JSPs

Somebody asked how to find out more about the new "ui" tags in Creator 2. This seems like a good opportunity to point out that we have code completion, and popup javadoc, for JSP tags as well. In particular, if you switch to the JSP view of your source files, put the caret over a tag like <ui:button>, and hit Ctrl-Space or Ctrl-\\, you get a completion popup listing possible alternatives. As you walk around in the list with the arrow keys, the TLD doc for the tag is listed in the popup (which for java files show javadoc documentation for the methods). There's quite a bit of documentation for all the new components - look at the size of the scrollbar to get a sense of the size of the button help. Or better yet, go try this yourself!

Of course, you don't have to go to the JSP view and read tag documentation to learn about the components. In the Early Access version we don't have all the help for the new components written, but if you for example select the Button in the JSF Standard palette, you'll see that the dynamic help window begins with a help topic for the Button component. Double click on it and you can read component-oriented documentation on the button component. We'll be filling this out as we finish Creator 2.

(As always in this blog, click on the thumbnail to see the full picture.)


Saturday Jun 25, 2005

It's Out!!


Creator 2 Early Access is now available. I'll be showing it at NetBeans Day tomorrow and several times during JavaOne this week, so if you're coming to the conference you'll have plenty of chances to see it and find out what we've been up to. The rest of you should download the bits and start reporting bugs, feature requests and anything else we should know about.

I'm taking off in a few minutes to head in to San Francisco and will spend the whole week there for JavaOne. I hope to meet many of you after some of the talks or by the Creator booth in the pavillion -- I don't have booth duty but will stop by several times and observe the action and hopefully strike up interesting conversations as in previous years.

I'm bringing a digital camera so hopefully I can get network access and blog occasionally from the conference!

Friday Jun 24, 2005

Positive Creator Review

Check out this review of Creator in InfoWorld.

The review is covering Creator 1.0. I'll be demoing Creator 2 on Sunday at NetBeans Day - be the first to see it! Sign up here. And of course see all the new cool things coming in NetBeans. I personally cannot wait for the new GUI builder!

The Rave Room

Part of the Rave room, taken on Marco's cell phone yesterday.
Picture of the Rave room
Roumen, one of the NetBeans engineers in Prague, blogged about his trip to the U.S. For JavaOne, and mentioned that he's heard about the infamous Rave room here in Menlo Park:
I've heard that there is some special huge office with 12 Creator developers on one place and it's interesting to see how they work together (I cannot imagine how this works, I need relative silence to be able to work efficiently).
Rave was the project name for the tool that eventually was named Sun Java Studio Creator. When we started out, we had an extremely aggressive schedule. (Some things never change...) The project was unlike any I had worked in, or even heard about, at Sun before. We had a small, very focused team that worked like a small startup company. The team has since grown, but we still hold on to some of the core aspects started two and a half years ago.

The team is too large to fit in the Rave room now. But I still spend all my office time there. In fact, I'm one of those Sun engineers who have given up their regular offices. I figured it was time to do that when I hadn't been in it for over a year! I come in to the office twice a week, and on the other two (actually, four :) I work at home.

My corner. Back off! Hey, who took my good chair?
Picture of my corner
When I'm in the office, I sit in my Corner Office. This is a spot I've had since the very beginning, so nobody dares to challenge me for it... In the picture, you can see a Viking guarding my corner, and the Dukie award I got two years ago for my demo trouble .

You may wonder how one can get any work done surrounded by so many people. The key to that is that most of us only work there twice a week. Those are days when you schedule meetings, or work out technical issues on one of the boards, or just get the pulse of the product and find out what's going on by talking to people or overhearing conversations. Of course there have been times when I need to get some coding done at the last minute for a milestone build. That's when I wear my noise cancelling head phones and crank up some suitable coding music to drown out the background conversations. Those who want peace and quiet tend to disappear, probably to their offices, or for those like me without one, to one of the flexible offices.

Having a shared space like this makes it easier to have a team culture. For example, we have various artifacts spread throughout the room - such as early marketing posters, or award trophies and diplomas. There's even a picture on the wall from the JavaOne 2003 keynote demo when the product was launched. And, when we get near a code freeze, we write the number of days left until code freeze on the door.

Speaking of that, let me go see how many days we have left...
<voice type="panic" pitch="high" volume="high" >AAAAAAARGH!<voice>

Sunday Jun 19, 2005

How to Write a JSF Component

As JSF is gaining popularity, more JSF components are being written. In fact TopCoder is running a competition on writing components. (Sun is a sponsor.)

However, some of the components written work, but do not work well in tools like Creator, or do not work well when used in conjunction with CSS. In this blog entry I will provide some hints that will make sure your components do not fall in that category.

How to actually write a JSF component is covered in many places; it's not hard. You need to write 3-4 classes, plus write a .tld file and a faces-config file with some information about your component.

Here's a document which takes you through this process.

However, there are some additional Rules You Should Follow when you write your component.

These rules serve two purposes:

  • They ensure that your component will work right when it is sized and positioned using CSS properties.
  • They ensure that your component will work well at designtime in a tool like Creator.

Here they are:

  1. First and foremost, you MUST use the ResponseWriter's startElement, endElement and writeAttribute methods. Do NOT write out markup by simply streaming out HTML bytes linearly using the write method. There is one minor exception to this rule: some components need to emit HTML provided by the user, such as the HtmlOutputText component when its Escape property is set to false. In this limited scenario you should use write.
  2. Always pass in a component reference to the startElement method on the ResponseWriter. E.g. if your UIComponent is a PanelGrid, and you want to emit <table><tr><td>... you would use
       writer.startElement("table", gridpanel);
       writer.startElement("tr", gridpanel);
       writer.startElement("td", gridpanel);
    
  3. Every component should have a style property, which will render to a style attribute on the rendered HTML markup. This will allow tools like Creator to position and size the component (using CSS). It is vital that you remember to replicate this style attribute on your top level rendered HTML tag. However, there are some complications...
    1. In the normal case, you render a single top level HTML element (possibly with children) from the JSP tag. In this case, simply duplicate the value of the JSP tag's style attribute to the top level HTML tag attribute. For example, if you have <h:commandButton style="width: 100px"/> in the JSP, you would render <input type="submit" style="width: 100px"/>
    2. If you need to render multiple top level HTML tags, but only one of them is visual, duplicate the style attribute on the one visual tag. For example, your component may want to render a <script> tag before it renders its one visual element, <table>, and then perhaps another non visual element, an <input> of type hidden. In this case, simply emit the <script>, then emit the <table> with the style property value from the JSF component, and finally emit the hidden <input>.
    3. If you need to render more than one visual element as siblings at the top level, you need to wrap these in a single container component, such as a <span> or a <div>. (Use span only if all the children being rendered are inline elements.) The style property should be placed only on this outer, wrapping <span> or <div>.
  4. Don't throw exceptions from your renderer! Even if for example value is a required property, don't throw a configuration exception just because it's null when you're rendering! If you really want your component to alert the user to the problem, I suppose it's okay to throw an exception when the component is used at runtime, but at designtime, it's quite normal for a component not to be correctly configured yet - after all, the user may just have dropped the component and is about to configure it. If necessary, you can have code in your renderer which checks if the component renderer is being used at designtime:
      if (java.beans.Beans.isDesignTime()) {
          // Designtime - better render error handling here
          ...
      } else {
          // Runtime - throw your exceptions if you must
          ...
      }
    
    One thing you might consider doing is having the component render exactly the problem message to the user. As an example, in Creator, if you drop the Message component, it will tell you if it is not bound to anything (since the for property is null, so the component is not yet configured.)

Once you have written your component you should package it up such that it can easily be imported into Creator and used out of the box by your users. That is also covered in the component library article I linked to earlier.

Please let me know if you develop components that work well with Creator!

About

Tor Norbye

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today