Friday November 30, 2007
NetBeans Visual Web - JSF, "Pretty" URLs and Multiple Instances of the Same Page
Since I introduced "Pretty URLs" in
the
NetBeans Plugin Portal, there have been some strange things
happening like issues
119249,
122600,
and
122340.
Once again I've been schooled on the JSF life cycle.
So here's what's happening.
Problem
When a button or link is clicked on a page and an action is associated
on the pages backing bean, a post back occurs. For the
purposes of this discussion, a post back basically means a request is
sent from the displayed web page to the server, the page backing bean
action method is executed, a null is returned from the method telling
the JSF framework not to navigate anywhere, and the page is redisplayed
using the JSF Standard Processing Lifecycle. If you look at
the how I used the JSF life cycle in my earlier blog titled,
"NetBeans
Visual Web Pack - Real World Apps Tip #4 - "Pretty" URLs", I
took advantage of the
Visual
Web application model "init" method. In the details
of implementing "Pretty" URLs, the key piece of information for
rebuilding the state of the page in the "init" would logically be put
on the SessionBean. For example, for the Plugin Detail page I
need the "currentPlugin". So when I navigate to the Plugin
Detail page I set the "currentPlugin" attribute on the SessionBean and
use that for all the details. So now what happens when
someone right-clicks on my "Pretty" URL and chooses to open a different
Plugin in another tab? The Plugin Portal stores the new
Plugin as the "currentPlugin" on the SessionBean. Now on the
first plugin, I do some action like click the download button.
Now to the important part! Remember that a PageBean
gets instantiated EVERY time a page is displayed. This means
the PageBean for the first Plugin is instantiated and gets the
"currentPlugin" from the SessionBean. Things are now bad
because the second Plugin in the other tab set "currentPlugin".
So you have results like described in the issues above.
Solution
The solution for this seemed easy at first, save each page instance
state per Plugin. This turned out to be quite difficult to
implement. Again I realized that the biggest difficulty when
using JSF is understanding the Standard Processing Lifecycle.
I somehow needed to save off state from a page with
uniqueness and pull that state back. For example, if a detail
page was showing for a particular Plugin and the user opens another
instance of the page with a different plugin, we need to have each page
somehow maintain which plugin is which for a post back.
Remember we can't use the SessionBean for "currentPlugin"
because each instance of the page will overwrite this attribute.
We can't use cookies because these are browser instance wide
and not page specific. The black magic is based on a nice
class in the JSF framework called "UIViewRoot". The
"UIViewRoot" is the root of the component tree for all the components
on the page. And here's the best part, "UIViewRoot" is saved
across post back calls. This means on a post back, you can
expect values set in components to be there when the page is
rerendered. This implementation does things like keeping form
values across post backs to keep users form committing suicide after
they've filled out a form for 3 hours only to hit the "submit" button
and find out they missed a required field and now all the fields are
blank. The Visual Web application model has the "init" method
that happens during the "Restore View" phase.
The problem is that the
UIViewRoot values don't get stuffed back into the components on the
backing bean until "Update Model Values". This means you
can't do something like this,
this.getTxtPluginID().getText();
and expect to get the value you stuffed in there before a button was
clicked. So the trick is to pull the value out of the
"UIViewRoot". Here's the code that shows how I did this on
the Plugin Detail page.
/**
* Process a GET type request.
*/
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
String [] pluginids = request.getParameterValues("pluginid");
if(null != pluginids && pluginids.length == 1) {
try {
Long pluginid = new Long(Long.parseLong(pluginids[0]));
currentPlugin = getApplicationBean1().getPluginSystem().getPlugin(pluginid);
if(null != currentPlugin) {
getSessionBean1().setCurrentPlugin(currentPlugin);
getRequestBean1().setCurrentPlugin(currentPlugin);
this.getTxtPluginID().setText(currentPlugin.getPluginid());
}
} catch(NumberFormatException nfe) {}
} else {
if(null == this.getCurrentPlugin()) {
/**
* Process a post back.
*/
FacesContext fc = FacesContext.getCurrentInstance();
UIViewRoot viewRoot = fc.getViewRoot();
if(null != viewRoot) {
StaticText pluginid_text =
(StaticText) viewRoot.findComponent("form1:center_container:page_border:fixed_contentarea:fixed_contextbox:topPanel:txtPluginID");
if(null != pluginid_text) {
Long pluginid = (Long)pluginid_text.getText();
if(null != pluginid) {
currentPlugin = getApplicationBean1().getPluginSystem().getPlugin(pluginid);
}
}
}
}
}
So you can see that for a "GET" style call with the "Pretty" URL we do
what did before except we stuff the part of the state we want for the
post back into a "Static Text" component. In the case of the
post back, we get a hidden field from the "UIViewRoot" and get its
value to use. So the one last piece is to create a "Static
Text" component somewhere on the page and make it invisible.
As you can see from the code you have to fully qualify the
name of the "Static Text" component. In my case it's
"txtPluginID".
Well I'm hoping another brick doesn't fall out the other side again.

If anyone has a better way to pull this off, please, please
post a comment.
Posted by David Botterill
( Nov 30 2007, 12:53:36 AM MST )
Permalink

|

|
Tuesday August 07, 2007
NetBeans Visual Web Pack - Real World Apps Tip #4 - "Pretty" URLs
Problem
One issue that's been plaguing the NetBeans Plugin Portal from the
beginning is the lack of direct URLs to portions of the web
application. As many of you know, JSF page navigation creates
some pretty horrendous URLs. Besides being "Ugly", as one
user put it, you can't use the URLs to reference pages in the web
application. Without going into the design considerations for
JSF, I will mention that one of the main issues is state. Yes
I know. In any web application development managing state is
always an issue. If you read my
JavaOne
2007 BOF slides, you will see that I had somewhat of a
solution on slides 54-55 by providing a "Permanent Link" then
dispatching through my main page. This worked but when you
ended up on the page, the URL was still ugly. I've Googled
many times on the subject but always seem to wind up in the same place
with the solution. Winston Prakash in the NetBeans visual web
engineering group did a blog entry on another
real
world application built on Visual Web Pack. A few
weeks ago I was looking at what
Joshua van Aalst
had done with his web site. Joshua had a goal of making much
of the web site Search Engine Optimized (SEO) so he needed to replace
the ugly URLs. His technique included using a servlet filter
and converters. In looking at his solution and doing some
testing, I realized that my original solution was very close with one
critical mistake. I was sending everything through the main
page then doing a redirect to the PluginDetailPage after setting up
state.
Solution
The solution - change all the links in the web app to point to the real
pages and set up the state in each page "init()" method. The
solution involves still using "GET" style URLs. So the first
step is to design the URL for each page that you will provide direct
linking to. The URL will need to contain adequate information
for the given page to build the web application state on the fly.
For example, to provide direct linking to the category list
page, I designed the following URL.
http://plugins.netbeans.org/PluginPortal/faces/CategoryPage.jsp?categoryname=Tools
As you can see, the URL has a parameter named "categoryname"
and a value of "Tools". In the "init" method of the
CategoryPage class, I use the following code.
/**
* Process a GET type request.
*/
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
String [] categories = request.getParameterValues("categoryname");
if(null != categories && categories.length == 1) {
getSessionBean1().setCurrentCategoryName(categories[0]);
}
The above code is what the Plugin Portal needs to set up state for the
category list page. That's all that's really needed.
The major refactoring I had to do was to change all the
hyperlinks to be in this "Pretty" format.
Posted by David Botterill
( Aug 07 2007, 02:27:57 PM MDT )
Permalink

|

|
Friday June 22, 2007
NetBeans Visual Web Pack - Real World Apps Tip #3 - Tag Clouds
Finally I've found the time to show you how to do tag clouds in
NetBeans 5.5 with Visual Web Pack. In my last blog, I showed
you how to create dynamic Hyperlinks. In the blog before
that, I discussed how to do dynamic content. Both of those
topics provide necessary background information for creating a tag
cloud.
First, let me provide a little background on how I tackled creating a
tag cloud. Since I really didn't know what a tag cloud was, I
started with the
Wikipedia's
definition. Next, since my task was not to be an
expert on tag clouds but to implement one on the web site, I simply
needed an algorithm to get me started. I found an excellent
white paper by Kevin Hoffman called, "
In
Search Of...The Perfect Tag Cloud". Based on the
Plugin Portal needs and Kevin's explanation, I decided to use the "
Linear Distribution Algorithm".
Plugin Portal Details
The goal is to basically have a set of words that are
displayed in different font sizes based on how many "things" there are
for that word. With the Plugin Portal, the words represent
categories. The bolder, bigger font category names are the
ones with more entries in the category. The sample project
I'll include will include hard coded data but I thought I would take a
moment to talk about the query behind the Plugin Portal that gave me
the results I needed. In the case of the Plugin Portal, I
needed to define a type that contained a category name and a category
count. I created a class called "
CategoryCount".
Here's the code including the query that creates the "
CategoryCount"
instances.
String select = "select distinct o.categoryname, cc.cat_count from othercategoryimpl o," +
" (select distinct categoryname,count(categoryname) as cat_count from othercategoryimpl cc group by categoryname) as cc" +
" where o.categoryname=cc.categoryname order by o.categoryname";
Query query = em.createNativeQuery(select);
List resultList = query.getResultList();
Iterator resultIterator = resultList.iterator();
Vector currentResult = null;
while(resultIterator.hasNext()) {
currentResult = (Vector)resultIterator.next();
String categoryName = (String)currentResult.get(0); //category name.
Integer categoryCount = (Integer)currentResult.get(1); //count
CategoryCount currentRecord = new CategoryCount(categoryName, categoryCount.intValue());
newCache.add(currentRecord);
}
You can see from this SQL query that I really have to do two passes of
the data. The "from" target:
(select distinct categoryname,count(categoryname) as cat_count from othercategoryimpl cc group by categoryname) as cc
gets the actual count for each category. Believe me this
query took a while to get right.

I don't claim to be a SQL
expert so if someone knows of an easier method, please let me know.
Creating the "Comparator"
Part of the goal also is to have the words sorted alphabetically so I
chose to use "Arrays.sort". To use this method, we need to
create a specialized "Comparator" that knows how to compare our "Count"
type. For my simplified example, I will be creating
"CategoryCount" as the "Count" type. Here's the code.
public class CategoryCount {
/** Creates a new instance of CategoryCount */
public CategoryCount() {
}
public CategoryCount(String inName, int inCount) {
setName(inName);
setCount(inCount);
}
/**
* Holds value of property name.
*/
private String name;
/**
* Getter for property name.
* @return Value of property name.
*/
public String getName() {
return this.name;
}
/**
* Setter for property name.
* @param name New value of property name.
*/
public void setName(String name) {
this.name = name;
}
/**
* Holds value of property count.
*/
private int count;
/**
* Getter for property count.
* @return Value of property count.
*/
public int getCount() {
return this.count;
}
/**
* Setter for property count.
* @param count New value of property count.
*/
public void setCount(int count) {
this.count = count;
}
}
Also we need a Comparator to sort this type. Here's the
"CountComparator".
import java.util.Comparator;
public class CountComparator implements Comparator {
/** Creates a new instance of CountComparator */
public CountComparator() {
}
/**
* This method is used to compare o1 and o2.
* @param o1 The first object to compare to o2
* @param o2 The second object to compare to o1
* @return a negative integer, zero, or a positive integer if o1
* is less than, equal to, or greater than o2
*/
public int compare(Object o1, Object o2) {
String o1categoryname = ((CategoryCount)o1).getName();
String o2categoryname = ((CategoryCount)o2).getName();
return o1categoryname.compareToIgnoreCase(o2categoryname);
}
}
The Linear Distribution Algorithm Details
The idea behind this algorithm is to figure out a range for a set of
"Buckets" then distribute your items in the buckets according to where
they fit into the range. The first step is to decide on the
number of buckets to use. In a tag cloud you'll be deciding
how many font size ranges you want. For the Plugin Portal, we
chose six buckets. So to figure out the range, you need to
take the max count of the items - the min count of the items and divide
by the number of buckets. This gives you the range to use for
each bucket. Here's the code I'll use in my sample to figure
out the range.
private long getCloudRange(int min, int max) {
/**
* For this tag cloud we will use the linear distribution algorithm with six different "buckets".
* The algorithm is:
* category weight = max number/category - min number/category
* range = category weight/number of buckets (6).
*
*/
long weight = 0;
long range = 0;
weight = max - min;
if(weight < 6) {
/**
* We don't have a very big range of numbers in categories so we need to increase the
* weight so the range will be bigger.
*/
range = 1;
} else {
range = weight/6;
}
return range;
}
The other key piece of the implementation is to assign a font based on
which bucket the item fits into. Here's my sample method to
do that.
private String getFont(CategoryCount inCount,long bucketRange) {
String fontsize1="font-size: 10px; font-weight: normal;";
String fontsize2="font-size: 11px; font-weight: normal;";
String fontsize3="font-size: 12px; font-weight: normal;";
String fontsize4="font-size: 13px; font-weight: normal;";
String fontsize5="font-size: 14px; font-weight: normal;";
String fontsize6="font-size: 15px; font-weight: normal;";
/**
* Determine which of the buckets the count falls into.
*/
if(inCount.getCount() >= 0 && inCount.getCount() <= bucketRange) {
return fontsize1;
} else if(inCount.getCount() >= (bucketRange*1) +1 && inCount.getCount() <= (bucketRange*1)+bucketRange) {
return fontsize2;
} else if(inCount.getCount() >= (bucketRange*2) +1 && inCount.getCount() <= (bucketRange*2)+bucketRange) {
return fontsize3;
} else if(inCount.getCount() >= (bucketRange*3) +1 && inCount.getCount() <= (bucketRange*3)+bucketRange) {
return fontsize4;
} else if(inCount.getCount() >= (bucketRange*4) +1 && inCount.getCount() <= (bucketRange*4)+bucketRange) {
return fontsize5;
} else {
return fontsize6;
}
}
Leveraging our dynamic Hyperlink experience, we will need a block of
code like this create the actual Tag Cloud.
/**
* Sort the CategoryCounts
*/
Arrays.sort(counts,new CountComparator());
/**
* Get the range to use for the tag cloud.
*/
long range = getCloudRange(minCategory,maxCategory);
/**
* Create all the hyperlinks and add them to the dynamic panel.
*/
ArrayList<Hyperlink> hyperlinks = new ArrayList();
Hyperlink dynamicHyperlink = null;
for(int ii=0; null != counts && ii < counts.length; ii++) {
dynamicHyperlink = new Hyperlink();
dynamicHyperlink.setText(counts[ii].getName());
dynamicHyperlink.setActionListenerExpression(listenerMethod);
dynamicHyperlink.setActionExpression(actionMethod);
/**
* Get the font for this link which will be calculated based on the
* count and where it falls into a range for each bucket.
*/
String font = getFont(counts[ii],range);
dynamicHyperlink.setStyle(font);
dynamicPanel.getChildren().add(dynamicHyperlink);
}
The Finished Product
Running my sample project, you can see that we get a small cloud.
You can use
my
sample project for a good starting point. I really
wish I new how to create components. This would make a great
component wouldn't it!
( Jun 22 2007, 03:46:56 PM MDT )
Permalink

|

|
Thursday June 07, 2007
NetBeans Visual Web Pack - Real World Apps Tip #2 - Dynamic Hyperlinks
In
my
last blog I covered creating Dynamic Content in NetBeans VWP
(Visual Web Pack). In this blog, I'll show you how to create "
Hyperlink"
components dynamically in VWP.
Creating the Hyperlink component and adding it is really not difficult.
But, hooking the Hyperlink component up to a Java backing
beans is a different story. This took me a while to figure
out.
Creating the Hyperlink
Actually creating the "
Hyperlink"
component is easy. Here's the code.
Hyperlink link = new Hyperlink();
Using the Hyperlink to Pass Data
As with most cases developing on the JavaServer Faces framework, you
can't ignore the standard processing lifecycle. Remember VWP
uses a modified "
Application
Model" based off the one used by Java Studio Creator 2.
Why is this important? In the case of a Hyperlink
on a page, if you want something about the Hyperlink to be passed as
data to the actual page bean method that will process the hyperlink
click, you either need to use the SessionBean or the Hyperlink
component itself. The technique I'm about to show you uses
the Hyperlink component. Remember you can't use state on the
page bean because a new instance of the page bean will be created on a
postback.
To explain this, I'll use the example of the
Plugin
Portal when the categories are in list form rather than tag
form. Here's a snapshot of that area of the screen.
You can see that the
Hyperlink has the category name and the number of items in that
category. In the Plugin Portal code, I needed the category
name so I could show a category list of that category. To
pass that name to the method that would deal with the selection, I used
the "Hyperlink.type" property. The "type" property is used to
set the MIME type of the hyperlink. Since we are handling the
link, we don't care about the MIME type so we can use this property to
pass values.
So here is some code that creates the Hyperlinks using the type
property.
/**
* Now create the hyperlinks to add
*/
Hyperlink dynamicHyperlink1 = new Hyperlink();
dynamicHyperlink1.setText("list1(" + list1.size() + ")");
dynamicHyperlink1.setType("list1");
Hyperlink dynamicHyperlink2 = new Hyperlink();
dynamicHyperlink2.setText("list2(" + list2.size() + ")");
dynamicHyperlink2.setType("list2");
Hyperlink dynamicHyperlink3 = new Hyperlink();
dynamicHyperlink3.setText("list3(" + list3.size() + ")");
dynamicHyperlink3.setType("list3");
/**
* Create a grid panel so we have one column.
*/
HtmlPanelGrid listPanel = new HtmlPanelGrid();
listPanel.getChildren().add(dynamicHyperlink1);
listPanel.getChildren().add(dynamicHyperlink2);
listPanel.getChildren().add(dynamicHyperlink3);
/**
* Add the list grid panel to the layout panel.
*/
dynamicPanel.getChildren().add(listPanel);
Mapping the Hyperlink to Backing Beans Methods
Now to the difficult part, at least before knowing what I'm about to
show you.

Many times you want Hyperlinks to invoke some
action on your Java backing bean. To accomplish this, you'll
need to know how to create a "
MethodExpression".
A
Hyperlink
component has two properties for dealing with an action:
The ActionExpression is the method JavaServer Faces uses to determine
page navigation. The ActionListenerExpression will wrap the
Hyperlink in the event and let us use the "Type" field as a way to pass
data. When a user clicks on the Hyperlink, the methods will
be called in this order.
- ActionListener method
- Action method
To create a
MethodExpression,
you need the "
ELContext".
You can get the "ELContext" from the "
FacesContext".
You use the "
ExpressionFactory"
from the "
Application"
to create the
MethodExpression.
So here's the code to create the ActionListenerExpression.
/**
* Create the MethodExpressions for the Hyperlinks
*/
/**
* First get the ExpressionFactory from the Application
*/
ExpressionFactory expressionFactory = this.getApplication().getExpressionFactory();
/**
* Next get the ELContext
*/
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
/**
* Now create the MethodExpressions
*/
MethodExpression listenerMethod = expressionFactory.createMethodExpression(elContext,
"#{Page1.category_action}",
null,
new Class[] {ActionEvent.class});
MethodExpression actionMethod = expressionFactory.createMethodExpression(elContext,
"#{Page1.category_action}",
String.class,
new Class[] {});
dynamicHyperlink1.setActionListenerExpression(listenerMethod);
dynamicHyperlink1.setActionExpression(actionMethod);
dynamicHyperlink2.setActionListenerExpression(listenerMethod);
dynamicHyperlink2.setActionExpression(actionMethod);
dynamicHyperlink3.setActionListenerExpression(listenerMethod);
dynamicHyperlink3.setActionExpression(actionMethod);
Lastly, you need to create the methods that will be invoked by clicking
the link. These methods will go on the page bean.
Let me talk about the "createMethodExpression" method signature for a
moment because that's important for understanding the methods.
The
first parameter
is the ELContext. We've already discussed that.
The
second parameter
is the binding expression. If you look at the code above,
you'll see that the page is hard coded in the binding expression.
#{Page1.category_action}
You will also notice the method name "category_action".
The
third parameter
is the method return type. You'll notice in the code above
for the ActionListener, we don't define a return type. For
the Action we do define a "String". This method signature,
"String action_method()" called by an action will cause JavaServer
Faces navigation to check the outcome to see if a navigate is needed.
The
fourth parameter
of the "createMethodExpression" call is the list of arguments that will
be passed to the method. Again notice for the ActionListener
the "ActionEvent" is passed. Remember this is how we will
pass data.
Here are the methods you need to define on the page.
public String category_action() {
return "page2";
}
public void category_action(ActionEvent ae) {
String selectedListName = ((Hyperlink)ae.getComponent()).getType();
getRequestBean1().setSelectedList(selectedListName);
return;
}
You can see the "return "page2"" in the Action method. This
corresponds to this navigation file which will cause a page navigation
to "Page2".
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns
si="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<navigation-rule>
<from-view-id>/Page1.jsp</from-view-id>
<navigation-case>
<from-outcome>page2</from-outcome>
<to-view-id>/Page2.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/Page2.jsp</from-view-id>
<navigation-case>
<from-outcome>case1</from-outcome>
<to-view-id>/Page1.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
Conclusion
So here's what the page will look like.
Posted by David Botterill
( Jun 07 2007, 12:26:01 PM MDT )
Permalink

|

|
Monday June 04, 2007
NetBeans Visual Web Pack - Real World Apps Tip #1 - Dynamic Content
I promised I would start blogging about my experiences developing the
NetBeans
Plugin Portal when I gave my BOF at JavaOne this year.
So this blog is the start of that series. To get
some background on the project, you really should look through
my
slides for the BOF.
There seemed to be the most interest around building a "Tag Cloud"
using NetBeans VWP (Visual Web Pack). So I thought I would
start with that topic. In order to do tag clouds in VWP, you
need to understand how to create two things first, dynamic content and
dynamic hyperlinks. This blog will cover the details of
creating dynamic content with NetBeans VWP. I'll then follow
up with blogs for dynamic hyperlinks and finally tag clouds.
I do plan to put the source code for the Plugin Portal out on
netbeans.org soon but I have to get through another phase and do some
cleanup first. In order to demonstrate these topics, I'll be
building simplified projects to be downloaded.
First, what is "
Dynamic
Content"? My use of this term focuses on the
distinction between the design time UI design and the run time UI.
Content that can not be visually created during design time
is content that I refer to as "
Dynamic
Content" or content that is created during run time.
Representing the Content in the Design Time
One of the greatest features of using VWP is the visual designer.
The designer gives you a pretty good idea what the page will
look like at runtime. So obviously you'd like to use the
designer to even help with the dynamic content. To do this,
use a "Layout Panel" as a placeholder for the dynamic content.
Here's a screenshot of the project we will build.
You can see the outline of the "Layout Panel" which I named
"dynamicPanel".
Creating the Content at Run Time
Now that you have a placeholder for the dynamic content,
"dynamicPanel", you can create the content at run time. We'll
target the "preprocess" method of the page backing bean. For
more information on the VWP application model, please see the article, "
The
Java Studio Creator 2 Application Model". As you
may already know, VWP incorporates most of the Java Studio Creator 2
functionality. The application model in VWP is the same as Java Studio
Creator 2.
For this first example, let's simply add a button as dynamic content.
Here's the code to do that.
public void prerender() {
/**
* First clear out the layout panel
*/
if(null != dynamicPanel.getChildren()) {
dynamicPanel.getChildren().clear();
}
/**
* Now create the button to add.
*/
Button dynamicButton = new Button();
dynamicButton.setText("My Button");
/**
* Add the button to the layout panel.
*/
dynamicPanel.getChildren().add(dynamicButton);
}
Note 1 - If you don't know the type for the component you want to add,
visually add the component to the designer and look at the Java source
to find the type.
Note 2 - The content you add MUST be a subtype of "UIComponent".
Conclusion
Here's what our page will look like.
Now that I have covered the basics of creating dynamic content, in my
next blog I'll cover creating dynamic hyperlinks.
You can download the
sample
"DynamicContent" project I used to get started. I
used NetBeans 5.5 with Visual Web Pack installed to create the project.
Posted by David Botterill
( Jun 04 2007, 01:19:48 PM MDT )
Permalink

|

|
Sunday May 20, 2007
NetBeans Day Mexico City 2007
I'm on the plane returning from NetBeans Day Mexico City. The
turnout was great! We had 455 people attend. This
was my first time to Mexico City and Mexico as well. The
people were very friendly. I'd like to go back some time and
see some sites. I really
wasn't supposed to be on this trip. Gregg Sporar was supposed
to go but got sick with the flu. He called me on a Tuesday, I
flew out on Wednesday, looked at the slides and demos for the first
time on Thursday, and gave the sessions on Friday. Overall
everything went pretty well. I did have some editor problems
with NetBeans 6.0 M9. Of course I had gone through the demos
many times the day and moments before with no problems. My
Google Tool Bar demo didn't work for some mysterious reason.
I was really frustrated by this so I opened my laptop at the
airport about one hour later, ran the demo and it worked.
Here's the proof.
The
only explanation I can think of is that I was running in a lower
resolution which might have caused the edit tool bar to truncate
somehow. I tried to reproduce the problem by changing the
resolution but I could not reproduce this. Oh well!
The crowd was wonderful. They asked many good questions and
were very much in tune with development issues. Here's some
shots of the actual conference
Entrance to NetBeans
Sessions - picking up translation devices

The crowd. Do you see yourself?

The venue - Centro Banamex
Posted by David Botterill
( May 20 2007, 12:03:56 AM MDT )
Permalink

|

|
Wednesday May 09, 2007
JavaOne 2007 BOF 9055 Slides
Thanks to everyone who attended my BOF Tuesday night. I'm not
sure how many people showed up. I would guess somewhere
around 30. As promised,
here
are the slides from my BOF. As soon as I get
settled from JavaOne, I'll start blogging all the details.
Posted by David Botterill
( May 09 2007, 04:44:54 PM MDT )
Permalink

|

|
Friday May 04, 2007
NetBeans Day On The Brain!
Got
NetBeans
Day on the Brain? You should. Don't
forget it's happening Monday, May 7, 2007 at the Moscone Center in San
Francisco. This will be a great opportunity to see what's up
and coming for NetBeans. The NetBeans 6.0 Preview
will be showcased heavily. One of the great aspects of this
years NetBeans Day is getting a free day at JavaOne. That's
right! You get one day, Tuesday, access to JavaOne.
Here's the paragraph from the
flier.
"CommunityOne attendees who are, or become, Sun Developer Network
members are also invited to experience the 2007 JavaOne Conference on
Tuesday, May 8. Enjoy the complimentary one-day access to the general
sessions, the JavaOne Pavilion and Welcome Reception, and two (2)
technical and/or BOF sessions. RSVP early to reserve your place. Please
Use
Priority Code C71AWM. "
The JavaOne Pavilion is where you get all the good
Swag.
Remember when you're going for Swag, try not to have the
glazed look in your eyes while you eye the Swag. This is a
dead giveaway that you really don't care about things like, "Clustering
in the New Time Space Continuum".
Also, there will be some great prizes given out at NetBeans Day.
Check out
Roman's
blog for more info.
It's not too late! Get registered now.
Posted by David Botterill
( May 04 2007, 11:42:56 AM MDT )
Permalink

|

|
Friday April 27, 2007
Check Out The New NetBeans Plugin Portal!
I can finally tell you what I've been working on for the past 5 months!
We reworked the netbeans.org "Plugins" tab from the ground up
into the
New
NetBeans Plugin Portal.
Here are some highlights of
the things you can now do with the NetBeans Plugin Portal.
- Add your own plugins with a netbeans.org userid.
- Comment on plugins
- Rate plugins
- Add the Plugin Portal as an Update Center to your NetBeans
IDE.
Stay tuned! I'll be blogging about my experience frequently
giving lots of information. I'll be giving out some of this
information at my BOF (session id 9055) at
JavaOne.
I'm looking forward to sharing the details!
-David
Posted by David Botterill
( Apr 27 2007, 12:52:15 AM MDT )
Permalink

|

|
Friday December 15, 2006
Creating Use Cases with the NetBeans 5.5 UML Tools
I'm currently working on a project that has given me the opportunity to
use the NetBeans tools I evangelize. I'm in the beginning
part of a software project when modeling is critical. The
obvious tool choice was the NetBeans 5.5 UML feature. This
blog entry will give you some "tips and tricks" on how to effectively
create Use Cases using the NetBeans 5.5 UML feature. Here's a
Use Case that might apply to a blogger tool just to get you in the mood.
Getting
the UML Modeling Feature
Before you can use the UML functionality in
NetBeans 5.5, you have to add it to the IDE. The UML
functionality used to be bundled in the Enterprise 5.5 Pack but now
it's available as a standalone feature via the NetBeans Beta Update
Center. I think this was a great move for the feature which
will hopefully allow it to grow and mature more rapidly.
First, go to the Update Center, from the menus choose
"Tools->Update Center". You'll see something like this.
Notice the "NetBeans Update Center Beta" is selected.
Press the "Next >" button and you'll see this.
Select "UML Modeling" and "Add >" it. Continue through
the process until the UML Modeling feature is installed.
Creating
the Project
Now that you have the UML Modeling feature installed, create the
project. In the new project dialog, choose "UML" for the
category and "Platform-independent Model" for the Project.
Here's what the new Project dialog will look like.
When you "Finish", you'll be presented with a diagram dialog asking
what type of diagram you want to create. Choose "Use Case"
and give it a name. Here's what that dialog will look like.
Use Case Refresher
If you're like me, you
don't spend enough time modeling so you tend to forget some of the
basic tenants of UML. First, I believe all documentation
should be useful. I know many developers are afraid of
"paralysis analysis" but too many swing the other way to "hacking
before thinking". I recently read some of the Agile stuff and
was generally impressed. I especially like
Scott
W. Ambler's discussion on documentation. UML when
done correctly is more than "just pretty pictures".
Remember there are really two artifacts around Use Cases; the textual
Use Case and the Use Case Diagram (UML). Here's a good
resource to get you started with Use Cases
http://www.agilemodeling.com/artifacts/systemUseCase.htm.
The textual Use Case describes expected and exceptional
courses of interaction between actors and the system. The Use
Case Diagram graphically represents the interaction. The real
meat and potatoes is really behind the textual representation.
Ideally, the Diagram and the textual description could be
kept together. I'll show you how to do that with NetBeans 5.5
UML.
Creating
the Use Case Diagram
Before we can fill in the textual use case information, we need to
create the diagram. From the steps above you should be
staring at a blank Use Case diagram in NetBeans 5.5. First,
let's add an "Actor".
Important!
There is a feature of the UML feature that might take some getting used
to. When you drag and drop a component on the drawing
service, the pointer is in what I call "semi-automatic" mode like a
semi-automatic pistol. All you have to do to fire is pull the
trigger again without cocking. In this mode, every time you
click the mouse on the drawing surface you'll get another instance of
the component you chose from the palette. To get back to
"manual" or "pointing" mode, simply hit the "ESC" key. You
can also select the pointer on the toolbar at the top. |
Name the "Actor" "Bank
Customer" by double-clicking on the "unnamed" label and typing in the
new name.
Next, add a "Use Case" and name it "Login to Bank Account".
As you can see we're going to model a bank customer
interacting with an online banking system. Add another "Use
Case" and name it "Transfer Funds".
Now let's add some dependencies showing the actor - system interaction.
Choose a "Usage" dependency and drag it from the "Bank
Customer" to the "Login to Bank Account" Use Case. Also drag
a "Usage" from "Bank Customer" to "Transfer Funds". Lastly,
drag a "Permission" dependency from "Login to Bank Account" use case to
"Bank Customer" actor. At this point, your diagram should
look something like this.
Adding
the Real Meat
As I said, the real meat of a Use Case is the textual description of
the interactions.
We will use the "Documentation" property of Use Case element to
document the interactions. The "UML Documentation"
window looks tempting but I currently recommend against using
it for a couple of reasons. First, as
issue
80014 describes, you can type a lot of text in the "UML
Documentation" window then loose it if you don't click on the right
part of the IDE. Also, I filed
issue
91102 for this behavior. If you put blank lines in
the "UML Documentation" window between your text, the IDE adds a line
each time you leave the window. Because of these two issues,
I recommend you use the "Documentation" property to enter the textual
use case. The "Documentation" property expects HTML to be
entered. You don't need a proper HTML page with
"<html></html>" tags. You only
need to focus on using HTML for formatting purposes. To open
the "Documentation" property editor, click the "..." next to the
property.
Important Notes About Property
Editor!
The property editor
deals strangely with line ends. In particular, when you have
a <li> for a list, make sure the text for the
<li> is right next to the tag and not split onto the next
line.
For example:
This HTML-
<li>
Bank
Customer enters userid/password.
</li>
Yields this display-
1.
Bank Customer enters userid/password.
Notice how the text is below the number for the list item.
Similarly, if you enter this:
<li>
Bank
Customer enters
userid/password.
</li>
You will see this-
1.
Bank Customer enters
userid/password.
To get the desired results, enter the HTML like this.
<li>Bank
Customer enters userid/password.
</li>
Also, the property
editor does NOT have an undo feature. So if you accidentally
wipe out a bunch of text, too bad. Hit the "OK" button
frequently to save the contents.
|
Here's a template to use for the Use Case Text.
<u><b>Main Flow of events:</b></u>
<ol>
<li>
</li>
</ol>
<u><b>Exceptional Flow of events:</b></u>
<ol>
<li>
</li>
</ol>
Filling the details for the "Login to Bank Account" would look
something like this displayed in a browser.
Sharing
With Others
The make or break for any UML tool is its ability to output its model
in a usable format. The NetBeans 5.5 UML Modeling feature
does a great job of producing a HTML UML report. To run the
report, right-click on the project node and choose "Generate Model
Report". This will cause the IDE to create a HTML report and
open it in the web browser.
Bummer!
The report feature doesn't seem to work correctly on Mac OSX.
According to issue
82394, there are also problems on Linux and Solaris. |
Thanks to
Parallels,
I was able to run NetBeans 5.5 on Windows XP Pro on my Mac to produce
the report correctly. Here's what our little Use Case example
looks like.
Future blog entries will
include more of my modeling experiences with NetBeans 5.5 UML Modeling.
Until then, remember modeling is worth the time. Do
just enough documentation to
fulfill the needs of the project team and the future system
maintenance.
Posted by David Botterill
( Dec 15 2006, 01:32:22 PM MST )
Permalink

|

|
Wednesday December 06, 2006
NetBeans 5.5 Visual Web Pack Released
NetBeans 5.5 Visual Web Pack is here! Check out the news at
http://www.netbeans.org/community/news/.
There are lots of enhancements and fixes from the TP (technical preview) version. Check it out!
Posted by David Botterill
( Dec 06 2006, 12:11:38 PM MST )
Permalink

|

|
Sunday October 29, 2006
NetBeans 5.5 and Visual Web Pack Technical Preview Are Out!
NetBeans 5.5 is out! If you haven't checked out NetBeans in a while you really really must. Also out today is the long awaited
Visual Web Pack.
Now you can use all the power of the NetBeans IDE with many of the great visual web application development features from
Java Studio Creator.
To get started developing a Visual Web Application, create a new
project then choose "Web->Visual Web Application" like this.
You can even open a Java Studio Creator
2 Update 1 project. Just be aware that once the project
conversion is done to Visual Web Project, you can't open the project
again in Java Studio Creator. When you try to open a Java Studio
Creator project, you'll get the following dialog.
Enjoy!
-David
Posted by David Botterill
( Oct 29 2006, 05:33:39 PM MST )
Permalink

|

|