Software Development

I'm a software developer, or programmer, by trade. I primarily code web sites or web applications using the Java programming language. I like Java the best because it takes care of a lot of busy work that comes up when programming and it is entirely embraced by the Open Source (OS) community. I use a ton of OS projects to help build my applications, both professionally and personally. If you have any questions about any of my articles below, please feel free to contact me at dev@ebessette.com.

Articles


My Favorite OS Projects

Spring
The Spring Framework is an AMAZING project. If you developing Jave web applications, then you HAVE to check it out. The main benefit is the Inversion of Control and Dependency Injection capabilities it has. Check out the documentation for more on these topics, but they can solve a ton of problems that are typical for J2EE applications.

Hibernate
Hibernate is a Object Relational (OR) framework.  It takes a lot of the work out of converting data from a relational database to objects in your code.  For simple retrievals, you don't have to write any SQL.  It will also save the objects to the database and any sub objects.  This is very helpful, but it also boosts performance by caching search results and lazy loading.

Google Web Toolkit
Google does is again with the Google Web Toolkit (GWT). GWT allows you, the programmer, to write AJAX web applications in Java, then compile them into Javascript. This means that you'll have all the compile time checking, debugging, and other Java capabilities when creating a AJAX application. For any of you who have tried to create a complex AJAX application directly in Javascript, you know what a nightmare it is. GWT is the answer and is only getting better.

Android
Android is an open source mobile operating system (OS).  The API is in Java, making creating applications very easy.  The OS is broken up in to some very simple components.  Activities are the applications that can display something to the user.  Services are background processes.  Intents are messages to do something.  And Content Providers give a standard way to access any type of information.  You can override the standard Intents, for example, a common intent is to call a phone number and you can create a new appication that handles that type of intent, overriding the default application.

Dynamically Switch Locales in GWT

Like me, a lot of people want their GWT applications to be able to change locale on the fly. While mine still only has one locale, I wanted to make sure that it could expand to more if necessary. Here's how I implemented dynamic local switching.

First, I store my languages in an XML configuration file, along with some other stuff for the application. A language element looks like this:

<language default="true">
	<key>myapp.language.name.english</key>
	<abbreviation>en</abbreviation>
	<icon>us.gif</icon>
	<email>translation@email.com</email>
</language>

This allows me to dynamically display the available languages to users of my app using clickable graphics. I use country flags.

Then I store my localized strings in a Java XML properties file. Like this:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties version="1.0">
	<comment>This is the English translation for MyApp</comment>
	<entry key="myapp.language.name.english">English</entry>
</properties>

On load of my application, I read the configuration file and get the default language (or use the user's last language choice from a cookie value or the browser's locale, see Get Locale via Javascript for more info). Then, on demand, I get the messages_.xml file, like above, for that language, using an increasingly general locale. If none is found, then it'll use messages.xml, which is the English language for my app.

Now, to make this dynamically change, you have implement a listener to all of the classes in your application that display localized text for when the user changes the language. Then you have to add those listeners, usually the class itself, to the class that handles the changes in language.

Get Locale via Javascript

Since a lot of websites need to be available in multiple languages, or localized, developers need a way to figure out what language the user prefers. Most modern browsers have a setting in their preferences or options that the user can change. If the user doesn't, then the browser most likely uses the operating system's locale (language and country) setting.

There are many ways to get this information. Most server-side programming languages can get the requester's locale from the request header. However, now that many sites use AJAX or GWT, developers need to be able to get this information on the client-side, i.e. using JavaScript.

Here's an implementation that I use when it's necessary for me to get the locale on the client-side.

if ( navigator ) {
    if ( navigator.language ) {
        return navigator.language;
    }
    else if ( navigator.browserLanguage ) {
        return navigator.browserLanguage;
    }
    else if ( navigator.systemLanguage ) {
        return navigator.systemLanguage;
    }
    else if ( navigator.userLanguage ) {
        return navigator.userLanguage;
    }
}

This JavaScript should work on most modern browsers. I know that it works in Firefox 1+ and Internet Explorer 5.5+. I haven't done any more compatibility testing than that though.

Google Web Toolkit Tooltip Extension

Using the Google Web Kit Google Group post, contrib: tooltip listener, as a guide, I came up with a little more general tooltip panel. You can specify a delay before showing the tooltip and/or a delay to automatically hide it after it opens. I've also included the CSS that I use.

CSS

/* Display's tooltips like in Eclipse */
.tooltip .gwt-HTML {
        border: 1px solid black;
        padding: 2px 3px 3px 3px;
        font-size: smaller;
        background-color: #ffffcc; /*Pale Weak Yellow*/
 
}

Java Code

public class TooltipPopup extends PopupPanel {
 
        /**
         * The default css class name for the tool tip
         */
        private static final String     DEFAULT_TOOLTIP_STYLE   = &quot;tooltip&quot;;
 
        /**
         * The default delay, in milliseconds,
         */
        private static final int        DEFAULT_SHOW_DELAY              = 500;
 
        /**
         * The delay, in milliseconds, to display the tooltip
         */
        private int                                     showDelay;
 
        /**
         * The delay, in milliseconds, to hide the tooltip, after it is displayed
         */
        private int                                     hideDelay;
 
        /**
         * The timer to show the tool tip
         */
        private Timer                           showTimer;
 
        /**
         * The timer to hide the tool tip
         */
        private Timer                           hideTimer;
 
        /**
         * Creates a new Tool Tip with the default show delay and no auto hiding
         * @param sender The widget to create the tool tip for
         * @param relLeft The left offset from the &lt;code&gt;sender&lt;/code&gt;
         * @param relTop The top offset from the &lt;code&gt;sender&lt;/code&gt;
         * @param text The tool tip text to display
         * @param useRelTop If true, then use the relative top offset. If not, then
         *        just use the sender's offset height.
         */
        public TooltipPopup( Widget sender, int relLeft, int relTop, final String text, boolean useRelTop ) {
 
                super( true );
 
                this.showTimer = null;
                this.hideTimer = null;
 
                this.showDelay = DEFAULT_SHOW_DELAY;
                this.hideDelay = -1;
 
                HTML contents = new HTML( text );
                add( contents );
 
                int left = getPageScrollLeft() + sender.getAbsoluteLeft() + relLeft;
                int top = getPageScrollTop() + sender.getAbsoluteTop();
 
                if ( useRelTop ) {
                        top += relTop;
                }
                else {
                        top += sender.getOffsetHeight() + 1;
                }
 
                setPopupPosition( left, top );
                addStyleName( DEFAULT_TOOLTIP_STYLE );
        }
 
        /**
         * Creates a new Tool Tip
         * @param sender The widget to create the tool tip for
         * @param relLeft The left offset from the &lt;code&gt;sender&lt;/code&gt;
         * @param relTop The top offset from the &lt;code&gt;sender&lt;/code&gt;
         * @param text The tool tip text to display
         * @param useRelTop If true, then use the relative top offset. If not, then
         *        just use the senders offset height.
         * @param showDelay The delay, in milliseconds, before the popup is
         *        displayed
         * @param hideDelay The delay, in milliseconds, before the popup is hidden
         * @param styleName The style name to apply to the popup
         */
        public TooltipPopup( Widget sender, int relLeft, int relTop, final String text, boolean useRelTop,
                final int showDelay, final int hideDelay, final String styleName ) {
 
                this( sender, relLeft, relTop, text, useRelTop );
 
                this.showDelay = showDelay;
                this.hideDelay = hideDelay;
                removeStyleName( DEFAULT_TOOLTIP_STYLE );
                addStyleName( styleName );
        }
 
        /*
         * (non-Javadoc)
         * @see com.google.gwt.user.client.ui.PopupPanel#show()
         */
        public void show() {
 
                // Set delay to show if specified
                if ( this.showDelay &gt; 0 ) {
                        this.showTimer = new Timer() {
 
                                /*
                                 * (non-Javadoc)
                                 * @see com.google.gwt.user.client.Timer#run()
                                 */
                                public void run() {
 
                                        TooltipPopup.this.showTooltip();
                                }
                        };
                        this.showTimer.schedule( this.showDelay );
                }
                // Otherwise, show the dialog now
                else {
                        showTooltip();
                }
 
                // Set delay to hide if specified
                if ( this.hideDelay &gt; 0 ) {
                        this.hideTimer = new Timer() {
 
                                /*
                                 * (non-Javadoc)
                                 * @see com.google.gwt.user.client.Timer#run()
                                 */
                                public void run() {
 
                                        TooltipPopup.this.hide();
                                }
                        };
                        this.hideTimer.schedule( this.showDelay + this.hideDelay );
                }
        }
 
        /*
         * (non-Javadoc)
         * @see com.google.gwt.user.client.ui.PopupPanel#hide()
         */
        public void hide() {
 
                super.hide();
 
                // Cancel the show timer if necessary
                if ( this.showTimer != null ) {
                        this.showTimer.cancel();
                }
 
                // Cancel the hide timer if necessary
                if ( this.hideTimer != null ) {
                        this.hideTimer.cancel();
                }
        }
 
        /**
         * Show the tool tip now
         */
        private void showTooltip() {
 
                super.show();
        }
 
        /**
         * Get the offset for the horizontal scroll
         * @return The offset
         */
        private int getPageScrollLeft() {
 
                return DOM.getAbsoluteLeft( DOM.getParent( RootPanel.getBodyElement() ) );
        }
 
        /**
         * Get the offset for the vertical scroll
         * @return The offset
         */
        private int getPageScrollTop() {
 
                return DOM.getAbsoluteTop( DOM.getParent( RootPanel.getBodyElement() ) );
        }
}

 

Hiding/showing embedded flash in Firefox

Recently, I created an AJAX web site that had to hide and show a container that had a flash object element inside of it based on the user's actions.

I first created an html block like this:

<div id="flashContainer"><br />	<object></object></div>

Then I created the following two css classes.  As you can see, by default, my flash object is shown and the flash player runs.

/* Hide by default */
div#flashContainer {
	display: block;
	visibility: visible;
}
 
div#flashContainer.hide {
	display: none;
	visibility: hidden;
}

 Now, if I programmatically add the "hide" css class to the "flashContainer" element, then the flash player will disappear.  This works correctly in all the modern browsers I tested: Firefox, Internet Explorer, Safari 3, and Opera.

The problem arises when you try to hide the "flashContainer" element again.  In Internet Explorer, if you programmatically remove the "hide" css class, then the flash player shows the *.swf file at end of it's timeline (or if it's still playing, the correct spot in the timeline).  The same JavaScript run in Firefox (or any Gecko-based browser) to remove the "hide" css class will trigger the flash player to restart the flash file.  This may be what some people want, but for this project, it was very bad.

I finally figured out how to get around this issue by just using a simple CSS work-around.  Using the example above, if I change the CSS to the following, then all browsers will hide and show the "flashContainer" element without replaying the embedded flash file.

/* Hide by default */
div#flashContainer {
	height: auto;
	overflow: hidden;
}
 
div#flashContainer.hide {
	height: 0px;
}

 

Scrolling to an Element

Note: This is not my code, but a friend of mine's.

When writing AJAX websites, developers sometimes need to scroll to a particular element within the DOM on the page. The most common approach, using javascript, is:

/**
 * Scroll to an element (by id attribute or name attribute of the anchor tag )
 */
function scrollToElement( elementName ) {
	if ( elementName ) {
		window.location = &quot;#&quot; + elementName;
	}
}

However, this approach is not cross-browser compatible because some browsers will refresh the page. Since this is mostly necessary in an AJAX application, refreshing is most likely NOT desired.

So, my friend came up with the following JavaScript that I have found to work in most modern browsers.

/**
 * Scroll to an element (only works by id attribute)
 */
function scrollToElement(elementID)
{
	var theElement = document.getElementByID( elementID );
	if(theElement != null) {
		var selectedPosX = 0;
		var selectedPosY = 0;
 
		while( theElement != null ){
			selectedPosX += theElement.offsetLeft;
			selectedPosY += theElement.offsetTop;
			theElement = theElement.offsetParent;
		}
 
		window.scrollTo( selectedPosX, selectedPosY );
	}
 
}

If you use the prototype.js JavaScript, which I recommend, then you could rewrite the function above to use the CSS Class finder function, which would allow you to scroll to an element without needing the id attribute set.

XSLT for GWT

Here's a little lesson that I learned regarding client side XML and processing it. If your app requires any XML processing over about 50 nodes, use a native DOM implementation.

My app stores some Google Map locations in xml. Each location has the lat/long and an info node that I process in my app with XSLT to create the html for the marker window. Well, one file has 700+ of these location nodes, and when I wrapped AJAX-XSLT using the GWT, it took 2 full minutes to download the file, parse it, and process each location.

I switched to Sarissa, which is a JavaScript wrapper of the native DOM and XSLT support that most modern browsers have, and that same file now takes 4 seconds to do everything from download to processing. When I first got it working, I thought it was ignoring the xml file or something because it was so fast, but the Sarissa wrapper is doing it all, even remote DTD validation!

So, for those who need moderate to heavy use of XML, XSLT, and XPath for you apps, go with a native implementation like Sarissa. Don't have to redo all your work like I did.

My Implementation

If you would like to use my implementation, first go to http://sourceforge.net/projects/sarissa and download the latest release. You'll need to add these 3 files to your app:

  • sarissa.js
  • sarissa_dhtml.js
  • sarissa_ieemu_xpath.js

NOTE: Not all of these files may be included in future releases of Sarissa.

Then download the GWT wrapper at gwt.sarissa.zip. Note, this has no affiliation with the gwt.components guys, I just used their package path because it was convenient. Also, my apps only needs to read xml, so I didn't port any of the write xml methods.

Using the Code

After downloading the zip file, just extract it into your source directory for your GWT project and the compiler should pick it up without any problems.

I've gotten a lot of reports that this code isn't working. It might be that Sarissa has upgraded and the new version is not backwards compatible. Also, if you're creating the XML file, it will probably be faster to build your data in JSON as JavaScript can read it natively through its code syntax. However, I know some people are getting XML from a third-party source and it would be less efficient to transform it into JSON and then to parse the XML using the browser's native XML and XSLT functions. Plus there isn't, as far as I know, a transformation language for JSON like XSLT.

In any case, here's an example for using the API I provided:

/*
 * Notes
 * - I wrote this free hand, so I may have made syntax errors
 * - Normally you wouldn't want to put all the parsing and processing code in the RequestCallback
 */
RequestBuilder rb = new RequestBuilder( RequestBuilder.POST, &quot;path/to/ xml/file/xmlfile.xml&quot; );
rb.setHeader( &quot;Content-Type&quot;, &quot;text/xml; charset=utf-8&quot; );
 
try {
	rb.sendRequest( &quot;&quot;, new RequestCallback() {
 
		/*
		 * (non-Javadoc)
		 * @see com.google.gwt.http.client.RequestCallback#onResponseReceived(com.google.gwt.http.client.Request,
 		 * 	com.google.gwt.http.client.Response)
		 */
		public void onResponseReceived( Request request, Response response ) {
 
			if ( response.getStatusCode() != STATUS_CODE_OK ) {
				 // Capture error
				 return;
			}
 
			try {
				// Example of parsing the xml content into native DOM
				Node xmlDoc = XML.parse( response.getText() );
 
				// Example of finding a list of nodes
				List nodes = xmlDoc.getNodes( &quot;/xpath/to/nodes&quot; );
				for ( Iterator ni = nodes.iterator(); ni.hasNext(); ) {
					 Node n = (Node) ni.next();
					 System.out.println( n.getNodeName() + &quot; = &quot; + n.getStringValue() );
				}
 
				// Example of finding one node or the first noe
				Node node = xmlDoc.getNode( &quot;/xpath/to/nodes&quot; );
 
				// Example of applying a XSL file (assuming it was downloaded before hand)
				String transformedText = XSLT.process( xmlDoc, xsltDoc );
				System.out.println( transformedText );
			 }
			 catch ( XMLParseException xmlpe ) {
				// Handle exception
			 }
			 catch ( XSLTParseException xsltpe ) {
				// Handle exception
			 }
		 }
	 } );
}
catch ( RequestException re ) {
	 // Handle exception
}

 

AttachmentSize
gwt.sarissa.zip4.82 KB