<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>JavaWords</title>
	
	<link>http://javawords.com</link>
	<description>A blog about Java Programming Language. Tips and solutions for common problems, tools and resources, tutorials and guides. A window to share my Java experience with others.</description>
	<lastBuildDate>Tue, 22 Dec 2009 14:43:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Javawords" /><feedburner:info uri="javawords" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.0/</creativeCommons:license><item>
		<title>Using JSF 1.2 with Facelets on Google App Engine for Java</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/CnSFNvu2LQw/</link>
		<comments>http://javawords.com/2009/06/05/using-jsf-12-with-facelets-on-google-app-engine-for-java/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 16:19:40 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[JavaServer Faces]]></category>
		<category><![CDATA[Web Applications]]></category>

		<guid isPermaLink="false">http://javawords.com/2009/06/05/using-jsf-12-with-facelets-on-google-app-engine-for-java/</guid>
		<description><![CDATA[On April Google announced the support for Java on Google App Engine. I became aware of this last week and rushed to create an account and check it out. Since this is an &#8216;early look&#8217; release, I had to wait until the guys at Google grant me the rights to use the service. Meanwhile I [...]]]></description>
			<content:encoded><![CDATA[<p>On April Google announced the support for <strong>Java on Google App Engine</strong>. I became aware of this last week and rushed to create an account and check it out. Since this is an &#8216;early look&#8217; release, I had to wait until the guys at Google grant me the rights to use the service. Meanwhile I downloaded the SDK and started building a test application to check if the frameworks I mostly use are supported. My minimum requirements are <strong>JSF 1.2</strong> with <strong>Facelets</strong> for templating (I also use ICEfaces but I can live without them). The results where positive while using the SDK on my computer but when I&#8217;ve uploaded the application on App Engine (my account was activated two days ago) I received a nasty error thrown during the initialization phase of JSF.<span id="more-27"></span></p>
<p>After hours of searching and debugging I finally managed to get it up and running. Now I&#8217;m going to list the steps involved. The most interesting and insightful resource I found is <a href="http://ctpjava.blogspot.com/2009/04/jboss-seam-on-google-app-engine-first.html">this post</a>, which describes how to setup JSF on App Engine as a step in configuring JBoss Seam.<br />
As the post author states, you&#8217;ll have to enable sessions in <em>appengine-web.xml</em>, then configure JSF as usually, then set it up to use JBoss&#8217;s EL implementation and finally use those <a href="http://code.google.com/p/ctpjava/source/browse/#svn/trunk/projects/google-appengine/patches">patched classes</a> in order to avoid API calls that are restricted by the security policy of App Engine. I only used the patched classes under &#8216;jboss-el&#8217; and &#8216;jsf_mojarra&#8217; since I don&#8217;t use Seam.</p>
<p>After this I added Facelets and gone through the necessary configuration steps, built the application and tried to run it on App Engine.<br />
<br />
Problems Occurred (yes, of course, <a href="http://en.wikipedia.org/wiki/Murphy%27s_law">Murphy&#8217;s Law</a> dictates it):<br />
<br />
<strong>1)</strong> <em>FacesServlet</em> was not properly initialized. This is probably because App Engine does not initialize servlets at startup, instead initialization is postponed until the first request. As a result an <em>IllegalStateException</em> was thrown. To resolve the issue I had to add the following to <em>web.xml</em>:<br />
<code>&lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;listener-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;com.sun.faces.config.ConfigureListener<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/listener-class&gt;<br />
&lt;/listener&gt;</code><br />
Error Message:<br />
<strong><small><em>javax.servlet.ServletException: java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory</em></small></strong><br />
<br />
<strong>2)</strong> An error was thrown during <em>FacesServlet</em> initialization due to the use of a restricted class. After examining the stack trace I realized that JSF was trying to perform some XML validation and failed throwing a <em>NoClassDefFoundError</em>. I had no other option but to deactivate XML validation by setting the following at <em>web.xml</em>:<br />
<code>&lt;context-param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;com.sun.faces.validateXml&lt;/param-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;false&lt;/param-value&gt;<br />
&lt;/context-param&gt;</code><br />
Error Message:<br />
<strong><small><em>java.lang.NoClassDefFoundError: com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary is a restricted class. Please see the Google App Engine developer&#8217;s guide for more details.</em></small></strong><br />
<br />
<strong>3)</strong> EL API classes were missing, had to include the <a href="https://uel.dev.java.net/download.html">EL API</a> class library to the project.<br />
<br />
Error Message:<br />
<strong><small><em>java.lang.ClassNotFoundException: javax.el.CompositeELResolver</em></small></strong><br />
&nbsp;  </p>
<p>One last upload of the application after all the above tweaks and voilà! The homepage loaded without any errors! The fact is that I didn&#8217;t have time to perform any further tests and for sure I cannot tell if all the features of JSF and Facelets will work normally. I&#8217;m waiting for your feedback on this. Good Luck!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=CnSFNvu2LQw:Ve8FLOsWJFE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/CnSFNvu2LQw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2009/06/05/using-jsf-12-with-facelets-on-google-app-engine-for-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://javawords.com/2009/06/05/using-jsf-12-with-facelets-on-google-app-engine-for-java/</feedburner:origLink></item>
		<item>
		<title>Start a native application from your Java code</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/0s_8j5JBN7U/</link>
		<comments>http://javawords.com/2008/04/04/start-a-native-application-from-your-java-code/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 02:17:10 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://javawords.com/2008/04/04/start-a-native-application-from-your-java-code/</guid>
		<description><![CDATA[Starting a native application from your Java code is as simple as the following command:
Runtime.getRuntime().exec(&#34;notepad.exe&#34;);
Of course, this adds platform dependency to your code, and if you want your application to be portable it&#8217;s a good practice to avoid using the exec() method. But if it is necessary to initiate a native application for any reason, [...]]]></description>
			<content:encoded><![CDATA[<p>Starting a native application from your Java code is as simple as the following command:<br />
<code>Runtime.getRuntime().exec(&quot;notepad.exe&quot;);</code></p>
<p>Of course, this adds platform dependency to your code, and if you want your application to be portable it&#8217;s a good practice to avoid using the <em><strong>exec()</strong></em> method. But if it is necessary to initiate a native application for any reason, the way is easy and pretty straight-forward. The fact is that there&#8217;s always a case where executing a command of the operating system is the only way to achieve specific functionality. </p>
<p>In this case, independence can be approached if the command to be executed exist(with common or different syntax) in various operating systems. The first step is to find out the syntax of the command for every OS. Then within the code, you can use <em><strong>System.getProperty(&#8221;os.name&#8221;)</strong></em> to determine the OS that is being to host your Java application and finally use this information to execute the command using the corresponding syntax.</p>
<p>There is one more useful feature of the <em><strong>exec()</strong></em> method: it&#8217;s return value is an instance of the <strong><em>Process</em></strong> class, which can be used to get access to the actual process of the application initiated.  Check out the javadoc of the  <strong><em>Process</em></strong> class to find out more.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=0s_8j5JBN7U:o6EsBEl7JBw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/0s_8j5JBN7U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2008/04/04/start-a-native-application-from-your-java-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://javawords.com/2008/04/04/start-a-native-application-from-your-java-code/</feedburner:origLink></item>
		<item>
		<title>How to use log4j logging API</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/Eu9Cu1CcS0g/</link>
		<comments>http://javawords.com/2008/01/08/how-to-use-log4j-logging-api/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 22:25:45 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://javawords.com/2008/01/08/how-to-use-log4j-logging-api/</guid>
		<description><![CDATA[Logging is an important and pretty useful mechanism for every application. It can help developers to debug and improve their code or test it&#8217;s functionality. Apache has made a great work in this field with it&#8217;s tool named log4j. You can find more information about it here.
In this post I will provide a quick guide [...]]]></description>
			<content:encoded><![CDATA[<p>Logging is an important and pretty useful mechanism for every application. It can help developers to debug and improve their code or test it&#8217;s functionality. Apache has made a great work in this field with it&#8217;s tool named log4j. You can find more information about it <strong><a href="http://logging.apache.org/log4j/1.2/index.html">here</a></strong>.</p>
<p>In this post I will provide a quick guide to help you get up and started with log4j. But fist of all you&#8217;ll have to download the <strong><a href="http://logging.apache.org/log4j/1.2/download.html">latest version</a></strong>. Once you do, follow the instructions below:</p>
<p><strong>1.</strong> Add log4j&#8217;s jar(log4j-x.x.xx.jar where x.x.xx is the version of the release you&#8217;ve downloaded) file to your application&#8217;s classpath.</p>
<p><strong>2.</strong> Create a file named &#8220;log4j.properties&#8221; and place it in the default package of your source code(the root folder where all your code resides). Copy the following lines in it:<br />
<code># Log levels<br />
# Uncomment the following line to enable full loggin for every class<br />
#log4j.rootLogger=trace, stdout, R<br />
log4j.logger.gr.xfrag=trace, stdout, R<br />
<br />
# Console appender configuration<br />
log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
# Pattern to output the caller&#039;s file name and line number.<br />
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n<br />
<br />
# Rolling File Appender<br />
log4j.appender.R=org.apache.log4j.RollingFileAppender<br />
# Path and file name to store the log file.<br />
log4j.appender.R.File=./logs/applog.log<br />
log4j.appender.R.MaxFileSize=500KB<br />
# Keep one backup file<br />
log4j.appender.R.MaxBackupIndex=1<br />
# Rolling File Appender layout<br />
log4j.appender.R.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.R.layout.ConversionPattern=%d - %c - %p - %m%n</code><span id="more-20"></span><br />
Here is a quick explanation of what the above properties do:<br />
&#8220;log4j.logger.xxx&#8221; controls the loggers, where xxx is the package for witch you want to set log levels.<br />
The line<br />
<em>log4j.logger.foo.bar=trace, stdout, R</em><br />
means that you want every class under the <em>foo.bar</em> package to <strong>have a logging level</strong> of <em>trace</em>, and <strong>output the log</strong> to the standard output(the console) using a Console Appender named <em>stdout</em> and to a file using a Rolling File Appender named <em>R</em>.<br />
<br />
After that you define the appenders I mentioned earlier and set their properties.<br />
The lines<br />
<em>log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) &#8211; %m%n</em><br />
define the ConsoleAppender named stdout, set it&#8217;s layout to PatternLayout and then assign a pattern for the output.</p>
<p>Following the same procedure the RollingFileAppender is defined, setting some additional properties: the file name of the log, the size of the log and the number of backup files to keep.</p>
<p><strong>3.</strong> The third and final step is about the code you&#8217;ll have to use. There&#8217;s not much to be said, this is the easiest part. Take a look of the class below:<br />
<code>import org.apache.log4j.Level;<br />
import org.apache.log4j.Logger;<br />
<br />
public class Main {<br />
&nbsp;&nbsp;&nbsp;&nbsp;private static Logger logger = Logger.getLogger(Main.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long time = System.currentTimeMillis();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(&quot;main method called..&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.info(&quot;another informative message&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.warn(&quot;This one is a warning!&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(Level.TRACE, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;And a trace message using log() method.&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long logTime = System.currentTimeMillis() - time;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.debug(&quot;Time taken to log the previous messages: &quot; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+ logTime + &quot; msecs&quot;);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Exception logging example:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String subs = &quot;hello&quot;.substring(6);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch (Exception e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.error(&quot;Error in main() method:&quot;, e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</code><br />
First you have to import <em>org.apache.log4j.Logger</em> and <em>org.apache.log4j.Level</em>(if you want to use the log() method). </p>
<p>Then instantiate a static <em>Logger</em> object using the static method <em>getLogger()</em> and provide your class as an argument.</p>
<p>To log messages through your class, you use the logging methods of the created Logger object. There are two ways to log messages:<br />
<strong>Directly</strong>, using the methods <em>trace()</em>, <em>debug()</em>, <em>info()</em>, <em>warn()</em>, <em>error()</em> and <em>fatal()</em>, providing the message as an argument.<br />
<strong>Using the <em>log()</em> method</strong>, providing the level of the message from the <em>Level</em> class and the message to log as arguments.</p>
<p>According to the configuration you provide in the properties file, a message will be logged &#8211; or not. For example, if you set the level to WARN, all messages of level WARN, ERROR and FATAL will be logged and everything else will be omitted. In other words, the hierarchy is:<br />
TRACE &lt; DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL.</p>
<p>Now, check out how the appenders output the messages according to their pattern. Here&#8217;s what you get at the console when you run the Main class:<br />
<code> INFO [main] (Main.java:12) - main method called..<br />
 INFO [main] (Main.java:13) - another informative message<br />
 WARN [main] (Main.java:14) - This one is a warning!<br />
TRACE [main] (Main.java:15) - And a trace message using log() method.<br />
DEBUG [main] (Main.java:19) - Time taken to log the previous messages: 0 msecs<br />
ERROR [main] (Main.java:26) - Error in main() method:<br />
java.lang.StringIndexOutOfBoundsException: String index out of range: -1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at java.lang.String.substring(String.java:1938)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at java.lang.String.substring(String.java:1905)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at gr.xfrag.loggingexample.Main.main(Main.java:24)</code></p>
<p>And the same in the log file:<br />
<code>2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - INFO - main method called..<br />
2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - INFO - another informative message<br />
2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - WARN - This one is a warning!<br />
2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - TRACE - And a trace message using log() method.<br />
2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - DEBUG - Time taken to log the previous messages: 0 msecs<br />
2008-01-10 15:39:46,724 - gr.xfrag.loggingexample.Main - ERROR - Error in main() method:<br />
java.lang.StringIndexOutOfBoundsException: String index out of range: -1<br />
&nbsp;&nbsp;at java.lang.String.substring(String.java:1938)<br />
&nbsp;&nbsp;at java.lang.String.substring(String.java:1905)<br />
&nbsp;&nbsp;at gr.xfrag.loggingexample.Main.main(Main.java:24)</code><br />
Besides the deferences of the formating, notice how long it takes to log those messages &#8211; zero milliseconds on my machine. If you ask me, I&#8217;ll say that speed is the most impressive feature of log4j..</p>
<p>I hope the above information will help you get started with log4j and logging in general. You can learn more by reading the manual located at log4j&#8217;s home page: <strong><a href="http://logging.apache.org/log4j/1.2/manual.html">Log4j Manual</a></strong></p>
<p>I also uploaded the example code as a NetBeans 6.0 project. Use the following link to download the zip archive:<br />
<strong><a href='http://javawords.com/wp-content/uploads/2008/01/logging-example.zip' title='Log4j Example NetBeans Project'>Log4j Example NetBeans Project</a></strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=Eu9Cu1CcS0g:7xRXd18V4Mo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/Eu9Cu1CcS0g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2008/01/08/how-to-use-log4j-logging-api/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://javawords.com/2008/01/08/how-to-use-log4j-logging-api/</feedburner:origLink></item>
		<item>
		<title>Mapping FacesServlet to URLs without extensions</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/uaSaB19LG4E/</link>
		<comments>http://javawords.com/2007/10/02/mapping-facesservlet-to-urls-without-extensions/#comments</comments>
		<pubDate>Tue, 02 Oct 2007 21:18:36 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[JavaServer Faces]]></category>

		<guid isPermaLink="false">http://javawords.com/2007/10/02/mapping-facesservlet-to-urls-without-extensions/</guid>
		<description><![CDATA[Over the past few months, I&#8217;ve been working on JavaServer Faces, making an effort to learn the framework and ultimately use it to create a web application. Currently I&#8217;m still in the learning process and the more I&#8217;m involved with JSF, the more I&#8217;m becoming a fan of it. The last challenge I&#8217;ve faced is [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few months, I&#8217;ve been working on JavaServer Faces, making an effort to learn the framework and ultimately use it to create a web application. Currently I&#8217;m still in the learning process and the more I&#8217;m involved with JSF, the more I&#8217;m becoming a fan of it. The last challenge I&#8217;ve faced is not directly related with JSF, but has to do with Servlets in general.</p>
<p>When you declare a Servlet in your web application&#8217;s configuration file (that&#8217;s web.xml), you also have to declare a mapping for the Servlet to make the web container forward the requests to the Servlet. There&#8217;s two types of mappings you can choose from: extension mapping and prefix mapping. Extension mapping will be of the form <em>&#8220;*.extension&#8221;</em> and path prefix mapping will be <em>&#8220;/path/*&#8221;</em>. Here&#8217;s an example:</p>
<p><code>&lt;servlet&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />
&lt;/servlet&gt;<br />
&lt;servlet-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;</code></p>
<p>I prefer extension mapping for JSF, because this way I&#8217;m not restricted to have a certain path for my JSF-enabled pages. The challenge I was talking about previously, has to do with my requirement to go beyond the default mapping mechanism. I want to be able to invoke JSF pages from any path, <strong>without using an extension</strong>. For example, say there is a JSF page displaying user account information, that has to be invoked using the URL <em>&#8220;/account/view.faces&#8221;</em>.  Wouldn&#8217;t it be nicer to have &#8220;/account/view&#8221; instead?</p>
<p>After a small research, I&#8217;ve found out that a Filter can do the job. All that have to be done is a check of the requested URL pattern and if it match the mapping criteria, forward the request to the FacesServlet. Here is how I&#8217;ve done it:<span id="more-17"></span></p>
<p><code>public class MappingFilter extends HttpServlet implements Filter {<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void doFilter(ServletRequest request, ServletResponse response,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterChain chain) throws IOException, ServletException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest httpReq = (HttpServletRequest) request;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Get the requested URI<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String uri = httpReq.getRequestURI();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Check if the URI matches mapping creteria.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean matches = uri.matches(&quot;.*/[\\w]+&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(matches){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServletContext context = filterConfig.getServletContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Strip context path from the requested URI<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String path = context.getContextPath();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (uri.startsWith(path)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uri = uri.substring(path.length());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Check if there is actually a file to handle the forward.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL url = context.getResource(uri+&quot;.jsp&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(url != null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Generate the forward URI<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String forwardURI = uri + facesExtension;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Get the request dispatcher<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RequestDispatcher rd =<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.getRequestDispatcher(forwardURI);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(rd != null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Forward the request to FacesServlet<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rd.forward(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// We are not interested for this request, pass it to the FilterChain.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request, response);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (ServletException sx) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filterConfig.getServletContext().log(sx.getMessage());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (IOException iox) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filterConfig.getServletContext().log(iox.getMessage());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
}</code></p>
<p>This filter works just fine and can be used to map extension-less requests to any Servlet. In other words, you can use it to <em>map requests for plain JSP pages also</em>. But when it comes to JSF, there&#8217;s a problem: JSF will write action URLs to the forms according to the <em>servlet-mapping</em> parameter that you have set in your <em>web.xml</em> configuration file. So, even if you request using the extension-less URL, after submitting the form your web browser&#8217;s bar will have the original location (the one with the extension) -and that&#8217;s not nice. After making a huge research this time, struggling for hours to find something in javadocs and in search engines, I&#8217;ve managed to find the class responsible for the creation of the action URL. It&#8217;s name is <strong><em>ViewHandler</em></strong> and the method is <em>getActionURL()</em>. I&#8217;ve also found that you can easily make a custom <em>ViewHandler</em> that sits on top of the one the framework is using and change only part of it&#8217;s functionality.</p>
<p>All you have to do is to create a class that extends <strong><em>javax.faces.application.ViewHandler</em></strong> and specify a constructor that takes a parameter of the same type as an argument. Then you declare it in <em>faces-config.xml</em> like this:</p>
<p><code>&lt;application&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;view-handler&gt;gr.xfrag.faces.mapping.MappingViewHandler&lt;/view-handler&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&lt;/application&gt;</code></p>
<p>The JSF framework will find your declaration, and will call your implementation&#8217;s constructor, passing it the default <em>ViewHandler</em> used by the implementation you&#8217;re using(if you use JSF-RI it will pass <em>com.sun.faces.application.ViewHandlerImpl</em>). You can use this class to delegate every method you don&#8217;t want to customize from your custom ViewHandler to the default one. Using this technique, I&#8217;ve been able to strip the extension from the action URLs like this:</p>
<p><code>public class MappingViewHandler extends ViewHandler{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * The original handler we are customizing.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp;private ViewHandler prevHandler = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;/** Creates a new instance of MappingViewHandler. By including<br />
&nbsp;&nbsp;&nbsp;&nbsp; * a parameter of the same type, we encourage the JSF framework<br />
&nbsp;&nbsp;&nbsp;&nbsp; * to pass a reference of the previously used ViewHandler. This way<br />
&nbsp;&nbsp;&nbsp;&nbsp; * we can use all the previous functionallity and override only the<br />
&nbsp;&nbsp;&nbsp;&nbsp; * method we are interested in (in this case, the getActionURL() method).<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp;public MappingViewHandler(ViewHandler prevHandler) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.prevHandler = prevHandler;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Delegate control to the original ViewHandler<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp;public Locale calculateLocale(FacesContext context) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return prevHandler.calculateLocale(context);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * This is the only method needed to be extended. First, we get the<br />
&nbsp;&nbsp;&nbsp;&nbsp; * normal URL form the original ViewHandler. Then we simply return<br />
&nbsp;&nbsp;&nbsp;&nbsp; * the same URL with the extension stripped of.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp;&nbsp;public String getActionURL(FacesContext context, String viewId) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String origURL = prevHandler.getActionURL(context, viewId);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int dotIdx = origURL.lastIndexOf(&quot;.&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (dotIdx &gt; 0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return origURL.substring(0,dotIdx);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else return origURL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
}</code></p>
<p>This way you can have flawless extension-less mapping for JavaServer Faces. If you want to disable requests for URLs having an extension completely (they will still work even if you use my classes), you can add a few more lines of code to the <em>MappingFilter</em>.</p>
<p>To get the complete source code, use the following links:</p>
<ul>
<li><a href='http://javawords.com/wp-content/uploads/2007/10/mappingfilter.java' title='MappingFilter'>MappingFilter</a></li>
<li><a href='http://javawords.com/wp-content/uploads/2007/10/mappingviewhandler.java' title='MappingViewHandler'>MappingViewHandler</a></li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=uaSaB19LG4E:I8HJFFxiGNU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/uaSaB19LG4E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2007/10/02/mapping-facesservlet-to-urls-without-extensions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://javawords.com/2007/10/02/mapping-facesservlet-to-urls-without-extensions/</feedburner:origLink></item>
		<item>
		<title>Theme Updated</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/P4g-1HfC25g/</link>
		<comments>http://javawords.com/2007/09/06/theme-updated/#comments</comments>
		<pubDate>Thu, 06 Sep 2007 17:18:34 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[Blog Update]]></category>

		<guid isPermaLink="false">http://javawords.com/2007/09/06/theme-updated/</guid>
		<description><![CDATA[After spending hours and hours playing with HTML, CSS and image editors, I&#8217;ve managed to give JavaWords a unique, nice and clear layout. The process was not easy at all for me, as my knowledge on the field is limited. Well, at least it was before making the decision to create my own theme.
The good [...]]]></description>
			<content:encoded><![CDATA[<p>After spending hours and hours playing with HTML, CSS and image editors, I&#8217;ve managed to give JavaWords a unique, nice and clear layout. The process was not easy at all for me, as my knowledge on the field is limited. Well, at least it was before making the decision to create my own theme.</p>
<p>The good thing is that now I can say I have a clear image of what it takes to consider yourself a web-designer. The whole site is <a href="http://validator.w3.org/check?uri=referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> valid and cross-browser compatible. I assume the later relying on my tests on Firefox, Internet Explorer 6.0 and Opera 9.0. If you notice any odd behavior on your browser, please notify me and I&#8217;ll try to fix it. I really want everyone to be able to read the blog without problems.</p>
<p>The bad side is that I didn&#8217;t had any time to spend writing anything about Java&#8230; Well I&#8217;m pretty stressed up lately studying for the exams at the University, but I&#8217;ll try to steal some time and write a few posts.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=P4g-1HfC25g:8stx0y4kFSI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/P4g-1HfC25g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2007/09/06/theme-updated/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://javawords.com/2007/09/06/theme-updated/</feedburner:origLink></item>
		<item>
		<title>Fade on change Label</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/MoUomsNOKW0/</link>
		<comments>http://javawords.com/2007/08/13/fade-on-change-label/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 14:14:26 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[Swing]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://javawords.com/2007/08/13/fade-on-change-label/</guid>
		<description><![CDATA[Here is the concept: We want to extend the JLabel swing component and make it perform a simple fade effect each time it&#8217;s value changes. Using this kind of label can be helpful to build a user interface for an application having the need to notify the user for important state changes.
The following applet demonstrates [...]]]></description>
			<content:encoded><![CDATA[<p>Here is the concept: We want to extend the <strong>JLabel swing component</strong> and make it perform a simple <strong>fade effect</strong> each time it&#8217;s value changes. Using this kind of label can be helpful to build a user interface for an application having the need to notify the user for important state changes.<br />
The following applet demonstrates the component:</p>
<div align="center"><applet code="gr.xfrag.swing.FadeOnChangeLabelApplet.class" archive="/wp-content/uploads/applets/FadeOnChangeLabel/fadeonchange.jar" width="250" height="80"></applet></div>
<p>A good example is an application which  continuously tracks a number of important data and represents values on the screen, each one on a separate label. It will be easier for the user to notice a change if the labels perform some kind of animation in response to an update of their value.</p>
<p>It is obvious that to make the above happen, we must &#8220;inject&#8221; animation code inside JLabel. The task is to figure out a way to start an animation thread whenever the text value of the label is updated. Well you can say this one is easy, because there&#8217;s the <strong><em>setText()</em></strong> method which we can override like this:</p>
<p><code>public void setText(String text){<br />
&nbsp;&nbsp;super.setText(text);<br />
&nbsp;&nbsp;if (!text.equals(lastValue)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;lastValue = text;<br />
&nbsp;&nbsp;&nbsp;&nbsp;animate();<br />
&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Alright, now that we have set up a mechanism to start the animation, we have to implement the animation procedure itself. The question is: What do we have to put inside <em>animate()</em> method?<br />
When I was trying to find an answer to the above question, I was sure for one thing only: There must be a thread to carry on the animation, witch I had to initiate during the call of <em>animate()</em> method. So I decided to make the class implement the <em>Runnable</em> Interface, and put my core animation code inside the <em>run()</em> method. I ended up with the following body for <em>animate()</em>:</p>
<p><code>private void animate() {<br />
// Only animate if there&#039;s not another animation in progress<br />
// and this Label is actually added to a parent Container, i.e.<br />
// if it is visible.<br />
&nbsp;&nbsp;if(!animating &amp;&amp; this.getParent()!=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;Thread t = new Thread(this);<br />
&nbsp;&nbsp;&nbsp;&nbsp;t.start();<br />
&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Now we have to deal with the animation procedure, which involves the manipulation of the <strong>paintComponent()</strong> method. But this is the most tricky part: Simply having a loop repeating a call to <em>paintComponent()</em> is not a solution, because it requires a <em>Graphics</em> object reference to the screen area where the label resides. This object is normally passed to the method by the Event Model and you actually don&#8217;t have control over the last. The right way to make <em>paintComponent()</em> get called with an appropriate <em>Graphics</em> object is to call the <em>repaint()</em> method of the <em>Component</em>. This will add a request to the event queue and eventually will lead to a call of <em>paintComponent()</em>.<span id="more-10"></span></p>
<p>Ok, so we can have an animation loop inside <em>run()</em> which calls <em>repaint()</em> at the end of every animation frame. Unfortunately, this approach will not work. Subsequent calls to <em>repaint()</em> with sort intervals between them will get stacked in the event queue, but will be treated as one request. Let&#8217;s say we make 10 calls of repaint() with an interval of 200 milliseconds. The most probable result is to get only one call of <em>paintComponent()</em> because it&#8217;s up to the Event Model to decide <strong>when</strong> to dispatch the event.</p>
<p>Here is the workaround I figured out:<br />
First, override <em>paintComponent()</em> and add the necessary code to perform the drawing for every frame of the fade effect. Also add a <em>paintCalled</em> flag to be informed about the method call. </p>
<p><code>public void paintComponent(Graphics g){<br />
&nbsp;&nbsp;// Let the Label perform its normal painting.<br />
&nbsp;&nbsp;super.paintComponent(g);<br />
&nbsp;&nbsp;// Now make the fade effect.<br />
&nbsp;&nbsp;if(fade != 0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;Insets i = this.getInsets();<br />
&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(fadeColor);<br />
&nbsp;&nbsp;&nbsp;&nbsp;g.fillRect(i.left, i.top, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getWidth() - i.left - i.right, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getHeight() - i.top - i.bottom);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;// paintComponent() called, we can continue to the next<br />
&nbsp;&nbsp;// animation frame.<br />
&nbsp;&nbsp;paintCalled = true;<br />
}<br />
</code></p>
<p>Second, inside the animation loop, wait for <em>paintComponent()</em> to be called before proceeding to the next animation frame by checking the value of <em>paintCalled</em> flag. A sleep interval of 100 milliseconds proved to be satisfying.</p>
<p><code>public void run() {<br />
&nbsp;&nbsp;animating = true;<br />
&nbsp;&nbsp;fade = initFade;<br />
&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;while (fade!=0) { //The animation stops when fade reaches 0.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... // Animation control code.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repaint(); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Now wait until paintComponent() gets called.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(!paintCalled &amp;&amp; fade!=0){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(100);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;animating = false;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;...<br />
&nbsp;&nbsp;}<br />
}</code></p>
<p>And that&#8217;s all. It works like a charm!<br />
You can find the full source code of FadeOnChangeLabel here: <strong><a href='http://javawords.com/wp-content/uploads/2007/08/fadeonchangelabel.java' title='FadeOnChangeLabel source code.'>FadeOnChangeLabel source code</a></strong>. The full class has a method to set fade options(<strong>setParams()</strong>) and there&#8217;s also an additional method named <strong>setRepaintContainer()</strong> that can be used in circumstances where the JLabel doesn&#8217;t control it&#8217;s painting, like when you make custom Renderers for list or tree items. Call <strong>setRepaintContainer()</strong> on the label and pass the Container object that controls it&#8217;s painting.<br />
I&#8217;ve fully documented the file using comments and hope it would be easy for everyone to understand how it works.</p>
<p>A couple of links to broaden your knowledge on the field:</p>
<ol>
<li><a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html" target="_blank" title="Painting in AWT and Swing">Painting in AWT and Swing</a></li>
<li><a href="http://java.sun.com/docs/books/tutorial/uiswing/components/" target="_blank" title="Using Swing Components">Using Swing Components</a></li>
</ol>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=MoUomsNOKW0:PD1VbRMu-vA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/MoUomsNOKW0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2007/08/13/fade-on-change-label/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://javawords.com/2007/08/13/fade-on-change-label/</feedburner:origLink></item>
		<item>
		<title>JavaWords is up and running!</title>
		<link>http://feedproxy.google.com/~r/Javawords/~3/h6uO2tm9_24/</link>
		<comments>http://javawords.com/2007/07/25/javawords-is-up-and-running/#comments</comments>
		<pubDate>Wed, 25 Jul 2007 15:20:21 +0000</pubDate>
		<dc:creator>xfrag</dc:creator>
				<category><![CDATA[Blog Update]]></category>

		<guid isPermaLink="false">http://javawords.com/2007/07/25/javawords-is-up-and-running/</guid>
		<description><![CDATA[Ok, after spending a lot of time while designing and tweaking the blog&#8217;s theme, I think I&#8217;ve come up to an acceptable result.
Finally I can enable search engine bots to crawl the site and make JavaWords available to everyone. Unfortunately(for the readers), I will be on vacation the next days and obviously there will not [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, after spending a lot of time while designing and tweaking the blog&#8217;s theme, I think I&#8217;ve come up to an acceptable result.</p>
<p>Finally I can enable search engine bots to crawl the site and make JavaWords available to everyone. Unfortunately(for the readers), I will be on vacation the next days and obviously there will not be anything of great interest to read here until my return&#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Javawords?a=h6uO2tm9_24:hNj-NSZOBPA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Javawords?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Javawords/~4/h6uO2tm9_24" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://javawords.com/2007/07/25/javawords-is-up-and-running/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://javawords.com/2007/07/25/javawords-is-up-and-running/</feedburner:origLink></item>
	</channel>
</rss>
