tag:blogger.com,1999:blog-69294227995235744582024-03-05T10:58:44.007+01:00Albert AttardJava // GWT // Information SecurityAnonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-6929422799523574458.post-16401837968134142212012-06-28T17:58:00.000+02:002012-07-02T18:22:53.075+02:00Eclipse GWT Plugin Update SitesThis article lists all <a href=" https://developers.google.com/eclipse/docs/download" target="_blank">GWT Plugin</a>s available for various versions of the <a href=" http://www.eclipse.org/" target="_blank">Eclipse</a> IDE (or any development tool built on Eclipse such as <a href=" http://www.springsource.com/developer/sts" target="_blank">SpringSource Tool Suite</a>). The official GWT Plugin page (<a href=" https://developers.google.com/eclipse/docs/download " target="_blank">https://developers.google.com/eclipse/docs/download</a>) now (2012-07-02) includes the latest version of the plugin together with all previous versions.<br />
<p>The following table lists the updates links for various versions of Eclipse. <br />
<p><table cellpadding="2"><tr> <th align="left">Eclipse 4.2 (Juno)</th> <td>http://dl.google.com/eclipse/plugin/4.2</td> </tr>
<tr> <th align="left">Eclipse 3.7 (Indigo)</th> <td>http://dl.google.com/eclipse/plugin/3.7</td> </tr>
<tr> <th align="left">Eclipse 3.6 (Helios) </th> <td>http://dl.google.com/eclipse/plugin/3.6</td> </tr>
<tr> <th align="left">Eclipse 3.5 (Galileo) </th> <td>http://dl.google.com/eclipse/plugin/3.5</td> </tr>
</table><p>Please refer to the GWT Plugin (<a href="https://developers.google.com/eclipse/docs/download" target="_blank">https://developers.google.com/eclipse/docs/download</a>) for further information about how you can install it.<br />Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com1tag:blogger.com,1999:blog-6929422799523574458.post-88362857623969192192012-06-23T18:32:00.002+02:002012-12-29T18:28:21.249+01:00Practical Example of GSON (Part 2)<strong>Please note that this page has moved to: <a href="http://www.javacreed.com/gson-deserialiser-example/">http://www.javacreed.com/gson-deserialiser-example/</a>.</strong><br />
<p>The first article I wrote about GSON (<a href="http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html" target="_blank">part 1</a>) is (at the time of writing) the most popular article in my small blog. Thus, I decided to write a second article and add more practical and advance examples which anyone can use. As also noted in my previous article, the official GSON site is: <a href="http://sites.google.com/site/gson/">http://sites.google.com/site/gson/</a>. <br />
<p>In this article we will see how to parse complex JSON objects into existing Java objects that do not necessary have the same structure as the JSON object. We will see how the use of the GSON deserialiser (<a href="http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonDeserializer.html" target="_blank"><code>JsonDeserializer</code></a>) in order to control how the JSON object maps to the Java object.<br />
<p>The code shown here is all available at: <a href=" http://code.google.com/p/gson-practical-examples/source/checkout" target="_blank"> http://code.google.com/p/gson-practical-examples/source/checkout</a>.<br />
<p>The readers are encouraged to first read <a href="http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html" target="_blank">part 1</a> before proceeding, unless they are already familiar with GSON.<br />
<br />
<h2>A Simple Example</h2>Let's say we have the following JSON object, where it contains four Java books titles written by various, well known, authors.<br />
<pre><code>
{
'1': 'Effective Java (2nd Edition)',
'2': 'JavaTM Puzzlers: Traps, Pitfalls, and Corner Cases',
'3': 'Java Concurrency in Practice',
'4': 'Java: The Good Parts'
}
</code>
</pre><p>Note that each name/value pair has a number as its name and the book title as its value. Using the methods discussed in <a href="http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html">part 1</a> would create a problem. In that article, Gson is expecting to find variable names in Java with the same name as that found in JSON. But names in Java cannot start with a number. They can contain a number, but cannot start with one (as described in <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html" target="_blank">chapter 6</a> of the Java Language Specification).<br />
<p><strong>So how can we parse this JSON object and use it in Java?</strong><br />
We can use the <code>JsonDeserializer</code> to parse the JSON object into our Java object the way we want it. Using the <code>JsonDeserializer</code>, we have full control over how JSON is parsed as we will see in the following example.<br />
<p>Consider the following simple Java object.<br />
<pre><code>
package com.albertattard.examples.gson.part2_1;
import java.util.ArrayList;
import java.util.List;
public class Books {
private List<string> booksTitles = new ArrayList<>();
public void addBookTitle(String title) {
booksTitles.add(title);
}
@Override
public String toString() {
return booksTitles.toString();
}
}
</code>
</pre><p>This Java object will be used to hold the books listed in the JSON object shown earlier. Note that JSON object has four fields, one for each book, while the Java object has a list in which these books are saved. The structure of these two objects (Java and JSON) is different. <br />
<p>In order to be able to parse JSON to Java we need to create our own instance of the <code>JsonDeserializer</code> interface as shown next.<br />
<pre><code>
package com.albertattard.examples.gson.part2_1;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
public class BooksDeserializer implements JsonDeserializer<Books> {
@Override
public Books deserialize(final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context)
throws JsonParseException {
Books books = new Books();
<em style="color:green">// Parsing will be done here.</em>
return books;
}
}
</code>
</pre><p>The above example is not complete and we still need to add the most important thing, which is the parsing. But let's understand this class before we make it more complex by adding more code to it. The interface <code>JsonDeserializer</code> requires a type, which is the type of object that we will be parsing. In this case, we are parsing JSON into the Java object of type <code>Books</code>. The return type of the <code>deserialize()</code> method must be of the same type as the interface parameter, <code>Books</code>. <br />
<p><strong>How does this work?</strong><br />
Gson will parse the JSON object into a Java object of type <a href=" http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonElement.html" target="_blank"><code>JsonElement</code></a>. The <code>JsonElement</code> can be thought of a tree of name/value pairs containing all elements found in the JSON object. Each child within the <code>JsonElement</code> is yet another <code>JsonElement</code>. In other words we have a tree of <code>JsonElement</code>s. Through this object we can retrieve each JSON element by its name and set the Java object accordingly. The following example shows how we can retrieve the first book listed in the JSON object and add it to the Java object.<br />
<pre><code>
package com.albertattard.examples.gson.part2_1;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class BooksDeserializer implements JsonDeserializer<Books> {
@Override
public Books deserialize(final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context)
throws JsonParseException {
Books books = new Books();
<strong style="color:red">JsonObject jsonObject = json.getAsJsonObject();</strong>
<strong style="color:red">books.addBookTitle(jsonObject.get("1").getAsString());</strong>
return books;
}
}
</code>
</pre>In the above example, we are retrieving the JSON element with name <code>"1"</code> using the following code fragment:<br />
<pre><code>
jsonObject.get("1")
</code>
</pre>This returns the <code>JsonElement</code> with the name: <code>"1"</code>. In this case it is a simple <code>String</code>. Note that in order to retrieve the actual value we need to invoke another method on the <code>JsonElement</code> instance, which returns the value we need, <code>String</code> in this case.<br />
<pre><code>
jsonObject.get("1")<strong style="color:red">.getAsString()</strong>
</code>
</pre><p>The rest of the books titles can be retrieved in the same manner.<br />
<p>Before we can utilise our new deserializer, we must instruct GSON to use our deserializer when parsing objects of type <code>Books</code>, as shown in the next code example.<br />
<pre><code>
package com.albertattard.examples.gson.part2_1;
import java.io.InputStreamReader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Main {
public static void main(String[] args) throws Exception {
// Configure GSON
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Books.class,
new BooksDeserializer());
Gson gson = gsonBuilder.create();
// The JSON data
Reader data = new InputStreamReader(
Main.class.getResourceAsStream("books.json"), "UTF-8");
// Parse JSON to Java
Books books = gson.fromJson(data, Books.class);
System.out.println(books);
}
}
</code>
</pre>In the above example, we are creating an instance of <code>Gson</code> through the <code>GsonBuilder</code>. Using the <code>registerTypeAdapter()</code> method, we are registering our deserializer and instructing GSON to use our deserializer when deserializing objects of type <code>Books</code>. When we request GSON to deserialize an object to the <code>Books</code> class, GSON will use our deserializer . The following list describes what happens when we invoke: <code> gson.fromJson(data, Books.class)</code>.<br />
<ol><li>Parse the input as <code>JsonElement</code>. At this stage, the string JSON object is changed into a generic Java object of type <code>JsonElement</code>. This step also ensures that the given JSON data is valid.</li>
<li>Find the deserializer for the given object, in this case the <code>BooksDeserializer</code> instance.</li>
<li>Invokes the method <code>deserialize()</code> and provides the necessary parameters. In his example, our <code>deserialize()</code> will be invoked. Here an object of type <code>Books</code> is created from the given <code>JsonElement</code> object. This is from Java to Java conversion.</li>
<li>Returns the object returned by the <code>deserialize()</code> method to the caller of the <code>fromJson()</code> method. This is like a chain, where GSON receives an object from out deserializer and returns it to its caller.</li>
</ol>Running the above example would print the following:<br />
<pre><code>
[Effective Java (2nd Edition), JavaTM Puzzlers: Traps, Pitfalls, and Corner Cases, Java Concurrency in Practice, Java: The Good Parts]
</code>
</pre><p>This concludes our simple example. This example acts as a primer for other complex parsing. For example, parsing JSON objects that include nested objects, arrays and the like. In the next example we will discuss an enhanced version of the objects discussed here.<br />
<h2>Nested Objects</h2>In this example we will describe how to parse nested objects, that is, objects within other objects. Here we will introduce a new entity, the author. A book, together with the title and ISBN can have a list of authors. On the other hand every author can have many books. The JSON object that will be using in this example differs from the previous one to cater for the new entity as shown next:<br />
<pre><code>
{
'1': {
'title': 'Effective Java (2nd Edition)',
'isbn': '978-0321356680',
'authors': ['Joshua Bloch']
},
'2': {
'title': 'JavaTM Puzzlers: Traps, Pitfalls, and Corner Cases',
'isbn': '978-0321336781',
'authors': ['Joshua Bloch', 'Neal Gafter']
},
'3': {
'title': 'Java Concurrency in Practice',
'isbn': '978-0321349606',
'authors': ['Brian Goetz', 'Tim Peierls', 'Joshua Bloch',
'Joseph Bowbeer', 'David Holmes', 'Doug Lea']
},
'4': {
'title': 'Java: The Good Parts',
'isbn': '978-0596803735',
'authors': ['Jim Waldo']
}
}
</code>
</pre>We still have our four books, only this time we have a more complex and detailed JSON object. Instead of a simple book title, we also have an ISBN and an array of authors.<br />
<p>The new example provides new challenges. One of the authors, <a href=" http://research.google.com/pubs/author32.html" target="_blank"><em>Joshua Bloch</em></a>, has three books. This immediately leads to the following question. <br />
<p><strong>How many instance of this author should we have?</strong><br />
There are two possible answers for this question: <em>just one</em> or <em>three</em> (one for every book). There is no one correct answer, and both cases can be valid. In our examples we are going to have one instance of the author even when he or she has more than one book. We are taking this approach as this approach resembles the reality and helps highlighting the goal of this article (GSON examples). Therefore we will have one author object representing the author <em>Joshua Bloch</em>. <br />
<p>For this example we will be using three domain objects:<br />
<ul><li>Author </li>
<li>Book</li>
<li>Books</li>
</ul>All three objects have references to the other objects. For example, the <code>Author</code> class has a list of <code>Book</code>s and the <code>Book</code> has a list of <code>Author</code>s. The <code>Books</code> class contains all parsed objects. The <code>Books</code> class also provides the functionality required to maintain one instance for each author as we will see later on in this example.<br />
<p><strong>Author</strong><br />
<pre><code>
package com.albertattard.examples.gson.part2_2;
import java.util.HashSet;
import java.util.Set;
public class Author {
private Set<Book> books = new HashSet<>();
private String name;
public Author(final String name) {
this.name = name;
}
public void addBook(Book book) {
books.add(book);
}
public Set<Book> getBooks() {
return books;
}
public String getName() {
return name;
}
@Override
public String toString() {
return String.format("%s has %d book(s)", name, books.size());
}
}
</code>
</pre><p><strong>Book</strong><br />
<pre><code>
package com.albertattard.examples.gson.part2_2;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Book {
private Set<Author> authors;
private String isbn;
private String title;
public Book(String title, String isbn, Author... authors) {
this.title = title;
this.isbn = isbn;
this.authors = new HashSet<>(Arrays.asList(authors));
}
public Set<Author> getAuthors() {
return authors;
}
@Override
public String toString() {
StringBuilder fomrattedString = new StringBuilder();
fomrattedString.append(title).append(" (").append(isbn)
.append(")");
fomrattedString.append(" by: ");
for (Author author : authors) {
fomrattedString.append(author.getName()).append(", ");
}
<em style="color:green">// To remove the last comma followed by a space</em>
return fomrattedString.
substring(0, fomrattedString.length() - 2);
}
}
</code>
</pre><p><strong>Books</strong><br />
<pre><code>
package com.albertattard.examples.gson.part2_2;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Books {
<em style="color:green">// A map of authors index by their name.</em>
private Map<String, Author> authors = new HashMap<>();
private Set<Book> books = new HashSet<>();
public void addAuthor(Author author) {
authors.put(author.getName(), author);
}
public void addBook(Book book) {
books.add(book);
}
public Author getAuthorWithName(String name) {
return authors.get(name);
}
@Override
public String toString() {
StringBuilder formattedString = new StringBuilder();
for (Author author : authors.values()) {
formattedString.append(author).append("\n");
for (Book book : author.getBooks()) {
formattedString.append(" ").append(book).append("\n");
}
formattedString.append("\n");
}
return formattedString.toString();
}
}
</code>
</pre><br />
<br />
<br />
<br />
<em>Coming soon.</em><br />
This article is not complete and more information will follow shortly.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com1tag:blogger.com,1999:blog-6929422799523574458.post-75707743991522678042011-06-17T14:04:00.000+02:002013-01-27T09:32:49.832+01:00Why should we use dependency injection?<strong>Please note that this page has moved to: <a href="http://www.javacreed.com/why-should-we-use-dependency-injection/">http://www.javacreed.com/why-should-we-use-dependency-injection/</a>.</strong><br />
<p>In this article we will explore some of the benefits of dependency injection and how this can be used in all types of programming, including small and simple programs. Some of the example shown below make use of <a href="http://code.google.com/p/google-guice/" target="_blank">Guice</a>, a dependency injection framework by Google. The same concept applies for any other dependency injection framework.</p><p><strong>This article does not provide detailed description of Guice but it only focus on the benefits of dependency injection and design methods that improve modularity, extendibility and testing</strong>. </p><h2>What is dependency injection?</h2><p>Let say we want to make some tea. How would we do it and what do we need? We need to boil some water, a clean mug, tea bags, sugar and milk (at least that's what I put into mine). In order to make tea we need to provide all these ingredients and we need to manage all these ourselves. We have to fill the kettle with water and heat it up, get the milk from the refrigerator and get the rest. </p><p>Now assume that we can make tea, by simply asking someone else to do it for us. Someone that knows how to do the tea just the way we want it. Would that be better than making the tea ourselves? If yes, then welcome to dependency injection. </p><p>Dependency injection is a framework that takes care of creating objects for us without we having to worry about providing the right <em>ingredients</em> so to say.</p><h2>A Simple Example</h2><p>Let say we have a class, <code>Person</code>, and this class needs to send a message. The <code>Person</code> class requires the aid of some other class, <code>Email</code>, in order to send a message. Following is a simple way of doing this. </p><pre>public class Email {
public void sendEmail(String subject, String message){
}
}
public class Person {
private Email email = new Email();
public void greetFriend(){
email.sendEmail(<em>parameters...</em>);
}
}
</pre><p>Some code is omitted from the above classes for brevity</p><p>We all agree that this is a very simple and straight forward example that involves two simple Java classes. Nevertheless, the above has some limitations as listed below.</p><ul><li>The <code>Persons</code> class is dependent (has a strong/tight dependency) on the <code>Email</code> class. There is a hard connection between these two classes. Let say we have a new better version of email class, <code>FastEmail</code>, in order for us to use it, we need to go in each and every class that depends on the <code>Email</code> class, such as the <code>Person</code> class, replace it with the new version.</li>
<li>Let say we parametrise the <code>Email</code>'s constructor. Again we have to go in each and every class that is initialising the <code>Email</code> class, such as the <code>Person</code> class, and change it.</li>
<li>A design decision is taken to make the <code>Email</code> class singleton. Similar to above we need to modify all instances where it is used.</li>
<li>In order to improve the notifications/messages system, we decide to add different message delivery systems such as SMS or tweets. The <code>Person</code> class and other like it, need to all be modified in order for it to use the new classes.</li>
<li>Another developer needs to use the <code>Person</code> class, but would like to use a different notification/message system. This cannot be achieved with the current version of the <code>Person</code> class as it is hardwired to the <code>Email</code> class. What generally happens is that the other developer duplicates the <code>Person</code> class and modifies it as he/she needs. The projects ends up with two versions of the <code>Person</code> class.</li>
<li>In the above points we mentioned many scenarios where code has to be changed. All changes made, need to and should be tested. How can we test the <code>Person</code> class without including the message delivery class such as the <code>Email</code>? Testing, in many cases, is left as an afterthought. The way we have the <code>Person</code> class constructed makes it hard to test it without involving the <code>Email</code> class. Furthermore, how would we automate such test? How can we use JUnit or the like to automate out tests?</li>
<li>Moving forward in the project, the <code>Person</code> class starts to depend on another class that allow this object to write a letter using the <code>Pen</code> class for example. The <code>Person</code> class can use other ways to write a letter, such as <code>Pencil</code> class or <code>Typewriter</code> class, but this approach does not allow that.</li>
</ul><p>These limitations can be improved by changing the way we think and restructure our code in a modular way. This is independent from dependency injection as we will see in the following section.</p><h2>Change the way we think</h2><p>The <code>Email</code> class provides a service, that is, sending of messages over the Internet using the mail protocol. Instead of having the <code>Person</code> class initialising an instance of the <code>Email</code> class, we first create an interface, <code>MessageService</code>, and make the <code>Person</code> class using this interface instead. This removed the dependency that the <code>Person</code> class has on the <code>Email</code> and replaces it with an abstract message delivery interface.</p><p>The following three steps: define, implement and use, show how we can develop modular and extendable code. This approach also improves testing as we will see at the end of this article.</p><ol><li><strong>Define Interfaces</strong> <p>Many developers do not use interfaces as they see them as additional non-required code. This may be true (I said maybe as the <code>System</code> class makes use of interfaces) for the famous hello world program, definitely not true for the rest. Like with everything else, we have to see things in context and there will be cases when we can do without interfaces. Nevertheless, developing code using interfaces produce far more modular and extendable code as illustrated in the following examples. The example discussed in the previous section was quite simple, but nevertheless it included several pitfalls which can be easily avoided. Changing code at a later stage involves more work than having it right in the first place.</p><p>We start by defining the <code>MessageService</code> interface that includes one method, <code>sendMessage(String subject, String message)</code>. For simplicity we assume that no exceptions are thrown.</p><pre>public interface MessageService {
void sendMessage(String subject, String message);
}
</pre></li>
<li><strong>Implement Interfaces</strong> <p>In the list of limitations we mentioned four possible methods of sending a message: email, fast email, SMS and tweet. Let's create four classes that handle each message delivery method and have all these classes implement the interface created above.</p><pre>public class EmailService implements MessageService {
@Override
public void sendMessage(String subject, String message){
System.out.printf("Email: %s, %s%n ", subject, message);
}
}
public class FastEmailService implements MessageService {
@Override
public void sendMessage(String subject, String message){
System.out.printf("Fast Email: %s, %s%n ", subject, message);
}
}
public class SMSService implements MessageService {
@Override
public void sendMessage(String subject, String message){
System.out.printf("SMS: %s, %s%n ", subject, message);
}
}
public class TweetService implements MessageService {
@Override
public void sendMessage(String subject, String message){
System.out.printf("Tweet: %s, %s%n", subject, message);
}
}
</pre></li>
<li><strong>Use Interfaces</strong> <p>Finally, instead of using classes, we use interfaces. In the <code>Person</code> class, we replace the <code>Email</code> field with the <code>MessageService</code> service interface as shown in red below. </p><pre>public class Person {
<span style="color:red">private MessageService messageService;
public Person(MessageService messageService){
this.messageService = messageService;
}</span>
public void greetFriend(){
messageService.sendMessage(<em>parameters...</em>);
}
}
</pre><p>Note that the <code>Person</code> class is not initialising the message service but it is expecting it as a parameter of its constructor. This is a key element in the design. It improves modularity, extendibility and testing. The <code>Person</code> class is not dependent on any implementation, but on a service defined by an interface. This means that we can use the <code>Person</code> class without having to worry about the underlying implementation. Furthermore, different <code>Person</code> instance can be instantiated using different message services.</p></li>
</ol><p>One can argue that the new version of <code>Person</code> class became more complex to instantiate as it requires parameters. This is a fair statement and here is when dependency injection comes into play.</p><h2>Using Dependency Injection</h2><p>As mentioned in the introduction, dependency injection can help us initialising objects and provide these objects all the necessary resources (<em>ingredients</em>). For example, the <code>Person</code> class requires an instance of <code>MessageService</code>. The dependency injection framework will provide that for us. So to create an instance of <code>Person</code>, all we need to do is call something like: <code>dependecyFramework.getInstance(Person.class)</code>. Magically, (not really), the dependency injection framework will create an instance of the <code>Person</code> class and provide an instance of the a <code>MessageService</code> to the <code>Person</code> object.</p><p>The next natural question will be, how does the dependency injection framework knows how to initialise the <code>MessageService</code>? We need to tell the dependency injection framework how to create an instance of <code>MessageService</code>. With Google Guice we do that by creating a module (extends <code>AbstractModule </code>) as illustrated below: </p><pre>public class ProjectModule extends AbstractModule {
@Override
protected void configure() {
bind(MessageService.class).to(EmailService.class);
}
}
</pre><p>Here we are telling the dependency injection how to create an instance of the <code>MessageService</code> class. We also need to add an annotation to the <code>Person</code> class in order to allow the dependency injection framework to inject the necessary parameters.</p><pre>public class Person {
private MessageService messageService;
<span style="color:red">@Inject</span>
public Person(MessageService messageService){
this.messageService = messageService;
}
public void greetFriend(){
messageService.sendMessage(<em>parameters...</em>);
}
}
</pre><p>With everything set, we create an instance of the Person class using the dependency injection framework</p><pre>Injector injector = Guice.createInjector(new ProjectModule());
Person person = injector.getInstance(Person.class);
person.greetFriend();
</pre><p>We replaced a couple of lines of code with many others. What's the buzz about this? In the next section we will see some of the benefits of dependency injection and how this can be used to simplify our coding life</p><h2>Benefits of Dependency Injection</h2><p>In this section we will see some key benefits of dependency injection</p><ul><li><strong>Changing the message service</strong> <p>Let's change the delivery method from email to SMS. How would we do that?</p><p>We only need to change the <code>ProjectModule</code> class to map the <code>MessageService</code> class to the <code>SmsService</code> class as shown in red below.</p><pre>public class ProjectModule extends AbstractModule {
@Override
protected void configure() {
bind(MessageService.class).to(<span style="color:red">SmsService.class</span>);
}
}
</pre><p>This one change will affect all classes initialised with the dependency injection framework without having to change any of these classes. This leads us to another advantage, testing. </li>
<li><strong>Changing the message service</strong> <p>We can create a <code>MockService</code> class which can be using in JUnit test as shown next.</p><pre>public class MockService implements MessageService {
public String subject;
public String message;
@Override
public void sendMessage(String subject, String message) {
this.subject = subject;
this.message = message;
}
}
</pre><p>The above mock message service simply stores the parameters into two public fields. These fields can be used to retrieve the values of the parameters and used for testing ass illustrated next.</p><pre>public class TestPerson {
private Injector injector;
@Before
public void init() {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MockMessageService.class).in(Singleton.class);
bind(MessageService.class).to(MockService.class);
}
});
}
@Test
public void testGreetFriend() {
Person person = injector.getInstance(Person.class);
person.greetFriend();
MockService mockService = injector
.getInstance(MockService.class);
assertEquals("Greet", mockService.subject);
assertEquals("Hello my friend", mockService.message);
}
}
</pre><p>This may require some explanation. So here we go. We created an injection (Guice dependency injection) just for this testing and provided a custom module (as an abstract inner anonymous class). The custom module wires the <code>MessageService</code> with the <code>MockService</code> instead. Also, we set the <code>MockService</code> as singleton, that is, whenever we request an instance of this class from the injection we always get the same object (singleton). After <code> greetFriend()</code> is invoked, we test using JUnit to make sure that the correct parameters are being passed to the message service instance.</p><p>This design setup allows us to test the <code>Person</code> class independent from the other classes that it depends on in an automated manner.</p></li>
<li><strong>Changing the signature of the <code>Person</code> constructor</strong> <p>As we mentioned in the limitations, the <code>Person</code> class may evolve and include more functionality. Changing the signature of the <code>Person</code> constructor will not affect us as long as the injector knows how to provide the required parameters.</p><pre>public class Person {
@Inject
public Person(MessageService messageService,
WritingService writingService){
}
}
</pre><p>The <code>Person</code> class will still be initialised in the same way as it is now. Thus changing the <code>Person</code> constructor signature will not affect the other classes that make us of it.</p><pre>Person person = injector.getInstance(Person.class);
</pre><p>The same applies for anything that is initialised and handled through the injector.</p></li>
<li><strong>Passing the <code>Injector</code> as parameter</strong> <p>In a project we can have one instance shared throughout the project. This can be achieved by passing the Injector as a parameter to other objects that needs it. We setup the injector at the beginning (in a main method for example), and then have it set as a constructor parameter in all the classes that require an instance of the injector. Like that one injector will server all classes in the project.</p></li>
</ul><p></p><h2>Conclusion</h2><p>This ended up to be quite a long article. Dependency injection is quite simple to use and it has quite a "shallow" learning curve. This article does not explain how to use the actual dependency injection framework (such as Guice). Articles about that are easily found. This article described key benefits of using a dependency injection framework even in small projects.</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com6tag:blogger.com,1999:blog-6929422799523574458.post-24888739560614078592011-06-11T12:49:00.002+02:002011-06-11T12:50:57.954+02:00OutOfMemoryError when reading large volumes of records from MySQL<p>
When loading a large number of records from MySQL, an out of memory error (exception) may be thrown by the MyQSL connector. The connector reads all the data in memory (buffering) before it returns the result set. This may not be the case for other JDBC providers.
</p>
<p>
The follow code fragment will fail on the third line (shown in red) when invoking the <code>executeQuery()</code> method if the memory required to load the whole result is larger than the allocated heap size.
<pre>
Statement statement = connection.createStatement();
ResultSet resultSet =
<strong style="color:red;">statement.executeQuery("SELECT * FROM `large_table`");</strong>
while(resultSet.next()){
}
</pre>
<p>
One possible solution is to increase the heap size but this may not be required, especially if you are accessing small parts from the result set at one time. Increasing the heap size will only allow the program to consumes more resources that it actually requires.
</p>
<p>
The MYSQL statement interface (<code>com.mysql.jdbc.Statement</code>) provides a method called <code>enableStreamingResults()</code> which enables streaming over buffering, (as shown in red in the following code fragment).
</p>
<pre>
Statement statement = connection.createStatement();
<span style="color:green;">// This prevents the MYSQL connector from loading all the
// results into memory</span>
<strong style="color:red;">((com.mysql.jdbc.Statement) statement).enableStreamingResults();</strong>
ResultSet resultSet =
statement.executeQuery("SELECT * FROM `large_table`");
while(resultSet.next()){
}
</pre>
<p>This allows the code to read from a large table without consuming a large amount of memory.</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com1tag:blogger.com,1999:blog-6929422799523574458.post-54432161811679891882010-07-09T09:24:00.008+02:002010-08-23T10:25:21.127+02:00In line images<p>Many web sites include small images and icons in tool bars and menus. These images are downloaded one by one by the browser while the page is downloaded. In many cases, the establishing of connection is more expensive in terms of time and traffic than the actual image. By converting these images to base64 encoding text, the browser can download the page content and the images at one go. Here’s is the code of how to convert an image into a base64 string.</p>
<pre>public static String convertToInLineImage(
byte[] image, String type) {
// Convert a byte array to base64 string
char[] chars = new sun.misc.BASE64Encoder().
encode(image).toCharArray();
StringBuilder builder = new StringBuilder();
for (char c : chars) {
switch (c) {
case '\n':
case '\r':
continue;
default:
builder.append(c);
}
}
return "data:" + type + ";base64," + builder.toString();
}</pre>
<p>The above method simple converts an image from bytes into string. The string returned by this method should be placed within the image HTML style.</p>
<pre>
style="width:50px;
height:50px;
background:url('the-base64-string-here')
no-repeat scroll 0px 0px transparent;"</pre>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-21429613825814665532009-12-28T15:51:00.004+01:002009-12-28T16:57:01.845+01:00Upgrade to GWT 2<p>To upgrade the Eclipse Plugin to GWT 2, is an easy process. Unfortunately GWT is installed with the default name, <code>GWT</code>, <code>GWT (1)</code>, <code>GWT (2)</code> and so on, for any different release. Ideally, the name used is a meaning full one, such as <code>GWT 1.7.1</code> and <code>GWT 2.0.0</code>.</p>
<p>In this short article we discuss who to rename an existing GWT Eclipse Plugin and install GWT 2</p>
<h2>Rename the existing GWT Eclipse Plugin</h2>
<p>This step is optional.</p>
<p>By default, the GWT Eclipse plugin is installed with the name <code>GWT</code> as shown in the following figure. This can be misleading especially if you have multiple versions installed. Unfortunately, the name cannot be changed once installed. The only way to rename it is to remove it and then add it again with the proper name.</p>
<p>To rename the GWT Eclipse Plugin, please follow the steps below:</p>
<ol>
<li>From the menu, open <strong>Window > Preferences</strong></li>
<li>Expand the <strong>Google</strong> node and select the <strong>Web Toolkit</strong>
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3hvBCdUrizytPhEzuhRc4y7Hk1OOULP7DFif75WeHVr_kC1LcaUj83wvRzw19R_dWLyGxxzK3gqtH276KIuSeGFr4WWZJppGmJgjGdb5M4Pfs6ejNlRingpnT0pE08J2ovGiAG44QF6M/s1600-h/GWT2_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3hvBCdUrizytPhEzuhRc4y7Hk1OOULP7DFif75WeHVr_kC1LcaUj83wvRzw19R_dWLyGxxzK3gqtH276KIuSeGFr4WWZJppGmJgjGdb5M4Pfs6ejNlRingpnT0pE08J2ovGiAG44QF6M/s320/GWT2_1.png" width="320" /></a>
</p>
As you can notice, the name set to <code>GWT</code>.
</li>
<li>Select it and click the <strong>Remove</strong> button</li>
<li>Once removed, click the <strong>Add</strong> button</li>
<li>A dialog will open. Click the <strong>Browse</strong> button to locate the current GWT Eclipse plugin
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6MN-1A41oWbCp7YAIQtAA9VRHh9KkEH04__TFeEZwaIT-MvOPzHRf8AvBZzuL7NGMODaQlu8IWTIuQ7BPhoFJcupcX8tRb5sVI0RPOKf8iPsguXcRcxJOFnmTrhR0nLGSPpFeyMtInKY/s1600-h/GWT2_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6MN-1A41oWbCp7YAIQtAA9VRHh9KkEH04__TFeEZwaIT-MvOPzHRf8AvBZzuL7NGMODaQlu8IWTIuQ7BPhoFJcupcX8tRb5sVI0RPOKf8iPsguXcRcxJOFnmTrhR0nLGSPpFeyMtInKY/s320/GWT2_2.png" width="320" /></a>
</p>
</li>
<li>Browse to the GWT Eclipse plugin folder. This is usually found at:
<code>C:\Program Files\Eclipse\eclipse-jee-galileo-SR1-win32\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1</code>.
<p>Note that the version numbers may be different depending on the version you have installed.
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkLCXyvWLKi4v2fqZ3YYHDY9_hVXXjJ3wybqFUHUaYdJYqILBVPQtDHLmjH2gI8voc34p-LIFd-jMXPMLO_1za-fzMhUyKPgy2mLYlSAE3Qczrx_cdKNhcaHuOBVPwPXzGnBl7S2NlhIA/s1600-h/GWT2_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkLCXyvWLKi4v2fqZ3YYHDY9_hVXXjJ3wybqFUHUaYdJYqILBVPQtDHLmjH2gI8voc34p-LIFd-jMXPMLO_1za-fzMhUyKPgy2mLYlSAE3Qczrx_cdKNhcaHuOBVPwPXzGnBl7S2NlhIA/s320/GWT2_3.png" width="320" /></a>
</p>
</li>
<li>Set the display name to correspond to the version, <code>GWT X.X.X</code>, and press <strong>OK</strong>
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXGZ3R-3Jcvl8O48S_qZyI0qAnf7JNEqdvQo8SDAt8U-Aann85i9LSFT0S1h-nqitmm_s_QQT2pJ05tTi2B-ssjcisggtM0kKEz9ig-m6snnFBzBxCoqCCux_L4gv9R0bQv1Ad6ei7aXo/s1600-h/GWT2_4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="109" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXGZ3R-3Jcvl8O48S_qZyI0qAnf7JNEqdvQo8SDAt8U-Aann85i9LSFT0S1h-nqitmm_s_QQT2pJ05tTi2B-ssjcisggtM0kKEz9ig-m6snnFBzBxCoqCCux_L4gv9R0bQv1Ad6ei7aXo/s320/GWT2_4.png" width="320" /></a>
</p>
</li>
<li>Press <strong>OK</strong> to complete the process</li>
</ol>
<p>This complete the renaming process.</p>
<h2>Install the GWT 2 Eclipse plugin</h2>
<p>This is installed as any other <u>new</u> Eclipse plugin.</p>
<ol>
<li> From the menu, open <strong>Help > Install New Software...</strong>. Make sure to select the <strong>Install New Software...</strong> and NOT <em>Check for Updates</em></li>
<li>Select the Google Eclipse URL: <code>http://dl.google.com/eclipse/plugin/3.5</code> (for Eclipse 3.5), check both the Plugin and SDK options and press <strong>Next</strong> as shown in the image below.
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7kVBQBSM8_anSQEnpP6WILQrlOLNR4E98PZao_uU9kBDiEcrliZBxFRq3005OQtZAJun96f3FhyphenhyphenmOVGG64ja-RYx4dWLEmJ_ed-IgQjm-g02gANE5KX41hkkW6E1QR8-9mpXMj08qqAA/s1600-h/GWT2_5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7kVBQBSM8_anSQEnpP6WILQrlOLNR4E98PZao_uU9kBDiEcrliZBxFRq3005OQtZAJun96f3FhyphenhyphenmOVGG64ja-RYx4dWLEmJ_ed-IgQjm-g02gANE5KX41hkkW6E1QR8-9mpXMj08qqAA/s320/GWT2_5.png" width="320" /></a>
</p>
</li>
<li><em>Next</em>, <em>Next</em>, ..., <em>Next</em> through the installation. Once ready, restart Eclipse.</li>
</ol>
<p>The GWT 2 Eclipse plugin is installed, with the name GWT. It is recommended to rename it to GWT 2.0.0 following the steps above discussed.</p>
<h2>Draft Compile</h2>
<p>One of the new features available in GWT2 is the draft compile, which is ideal for development as it skips the optimisation processes carried out by the compiler reducing the compile time. This is a great feature for development, but the production code <strong>SHOULD NOT</strong> be compiled in this mode.</p>
<p>
To make use of this feature, simple add the <code>-draftCompile</code> to the advance compiler options as illustrated below.
<p align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRUbe9dj_zXOkYnBC9hhH6yGtK4K5VrGqfgMvh8_1a9Jj9gvEnKdXSUv7e1QNTjqYaHA4zuP0xz8Sw98NkYqanTDn4-KSL61bzO5GwoB2b1k6mT2VMHB1EzN-I4V0I9lDf95IGdTu-T2s/s1600-h/GWT2_6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRUbe9dj_zXOkYnBC9hhH6yGtK4K5VrGqfgMvh8_1a9Jj9gvEnKdXSUv7e1QNTjqYaHA4zuP0xz8Sw98NkYqanTDn4-KSL61bzO5GwoB2b1k6mT2VMHB1EzN-I4V0I9lDf95IGdTu-T2s/s320/GWT2_6.png" width="247" /></a>
</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com1tag:blogger.com,1999:blog-6929422799523574458.post-55026516593636260662009-12-17T11:01:00.006+01:002009-12-17T12:56:07.977+01:00Simple Java WAV Player<p>In this article we'll discuss a simple way how to play <code>wav</code> files in Java. We'll start with the complete example and explain each bit in the process. This example only involves one class, the one listed below.</p>
<pre><code>package com.albertattard.pmm;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
public class TheMusicPlayer {
public static void play(final InputStream inputStream) {
new Thread() {
@Override
public void run() {
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem
.getAudioInputStream(inputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
SourceDataLine sourceDataLine = null;
try {
AudioFormat audioFormat
= audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(
SourceDataLine.class, audioFormat);
sourceDataLine =
(SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
}
sourceDataLine.start();
byte[] data = new byte[524288];// 128Kb
try {
int bytesRead = 0;
while (bytesRead != -1) {
bytesRead =
audioInputStream.read(data, 0, data.length);
if (bytesRead >= 0)
sourceDataLine.write(data, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
sourceDataLine.drain();
sourceDataLine.close();
}
}
}.start();
}
public static void play(final String wavFile)
throws FileNotFoundException {
play(new FileInputStream(wavFile));
}
}</code></pre>
<p>Those of you who are in a hurry, just copy and paste the above code and get on with your life. The others who can spare sometime, just read the following part.</p>
<h2>Explained</h2>
<p>The class has two static overloaded methods which play the <code>wav</code> file provides as a parameter. The second method simple invokes the first method passing an instance of input stream (and instance of <a href="http://java.sun.com/javase/6/docs/api/java/io/FileInputStream.html" target="_blank"><code>FileInputStream</code></a>, which inherits from <a href="http://java.sun.com/javase/6/docs/api/java/io/InputStream.html" target="_blank"><code>InputStream</code></a>)</p>
<p>All the logic is found in the first <code>play()</code> method, and that's what we'll be explaining next.</p>
<p>Let say we have a program and would like to play a sound (saved as a <code>wav</code> file) when an event/scenario occurs. The code to do so is very straight forward as illustrated below (a copy and paste from the example above).</p>
<pre><code> AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem
.getAudioInputStream(<strong>The Input Stream</strong>);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
SourceDataLine sourceDataLine = null;
try {
AudioFormat audioFormat
= audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(
SourceDataLine.class, audioFormat);
sourceDataLine =
(SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
}
sourceDataLine.start();
byte[] data = new byte[524288];// 128Kb
try {
int bytesRead = 0;
while (bytesRead != -1) {
bytesRead =
audioInputStream.read(data, 0, data.length);
if (bytesRead >= 0)
sourceDataLine.write(data, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
sourceDataLine.drain();
sourceDataLine.close();
}
</code></pre>
<p>The above code fragment is made from three parts:</p>
<ul>
<li>Initialisation of the audio input stream</li>
<li>Initialisation of the <em>audio output</em></li>
<li>Playing the audio data</li>
</ul>
<p>We're reading bytes from the input stream (the famous <code>wav</code>) and instead of writing/printing these in the console (as we traditionally do with text files), we're <em>writing</em> to the speaker/sound card of the computer.</p>
<p>We start by initialising the It's good to point out that the <a href="http://java.sun.com/javase/6/docs/api/javax/sound/sampled/AudioInputStream.html" target="_blank"><code>AudioInputStream</code></a>, which inherits from the <code>InputStream</code>. This instance behaves the same like any other stream and can be treated/handled in the same manner as other streams.<p>
<pre><code>AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem
.getAudioInputStream(<strong>The Input Stream</strong>);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}</code></pre>
<p>Then we initialise the audio output (this is <strong><u>NOT</u></strong> an <a href="http://java.sun.com/javase/6/docs/api/java/io/OutputStream.html"><code>OutputStream</code></a>), that is, where the sound will be played. This has to match the audio input initialise in the previous step. Remember that there are many different sound files and not all these can be played with the following code.</p>
<pre><code>SourceDataLine sourceDataLine = null;
try {
AudioFormat audioFormat
= audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(
SourceDataLine.class, audioFormat);
sourceDataLine =
(SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
}</code></pre>
<p>The first two were quite straight forward. In the third step we're actually playing the sound by reading the bytes and play them in a similar fashion we do with other streams. We're reading a predefined amount of data (128k) into the array called <code>data</code> and saving the amount of bytes read in the other variable <code>bytesRead</code>.</p>
<pre><code>bytesRead = audioInputStream.read(data, 0, data.length);</code></pre>
<p>When the whole file is played, and there is no more data to be played, the <code>read()</code> method returns <code>-1</code> (like it does with any other <code>InputStream</code>). This will have the <code>while</code> condition to <code>false</code> ending the playing process.</p>
<p>It is good to note that the third step will consume the focus of program until the <code>wav</code> file is played. That is, if you have a two minute <code>wav</code> file, than the above code will take two minutes to execute. All the other parts of the program (that are executed by this thread) will have to wait for the sound/music to finish. Since this is not what we want, the static method <code>play()</code> wraps this code into a thread which is started at the end of the method.</p>
<pre><code>public static void play(final InputStream inputStream) {
new Thread() {
@Override
public void run() {
<strong>Code removed for brevity</strong>
}
}.start();
}</code></pre>
<p>Since the code is started within a thread the control is immediately returned to the calling method which can proceed without having to wait for the file to play.</p>
<p>To play a <code>wav</code> file, all we need to do is invoke the pay method with the <code>wav</code> file as a parameter as illustrated below.</p>
<pre><code>package com.albertattard.pmm;
public class TheMain {
public static void main(String[] args) {
// File downloaded from:
// http://freewavesamples.com/bowed-bass-c2
TheMusicPlayer.play(TheMain.class
.getResourceAsStream("Bowed-Bass-C2.wav"));
}
}</code></pre>
<p>It's good to point out that the <code>wav</code> file <a href="http://freewavesamples.com/files/Bowed-Bass-C2.wav" target="blank">Bowed-Bass-C2.wav</a> (available at: <a href="http://freewavesamples.com/bowed-bass-c2" target="_blank">http://freewavesamples.com/bowed-bass-c2</a>) is in the same directory/package as the above class.</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com6tag:blogger.com,1999:blog-6929422799523574458.post-5236220735585672742009-12-16T15:07:00.020+01:002010-08-23T10:23:18.356+02:00Playing with the Mouse<p>In this article I'll be discussing how we can you can enhance an graphical component by handling mouse events such as mouse clicks and movements. </p>
<p>This article will not discuss the graphical aspect and assumes that you know how to create a simple UI component extending the <a target="_blank" href="http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html"><code>JComponent</code></a> and adding this component into a <a target="_blank" href="http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html"><code>JFrame</code></a>. For more information about how to do this, please read the article: <a target="_blank" href="http://albertattard.blogspot.com/2009/10/practical-example-of-simple-java-ui.html">Practical Example of Simple Java UI Component</a>.
<p>A note of caution to the reader: This is not an exhaustive article about events and some topics are simple mentioned while others not discussed at all. While you're encouraged to learn as much as you can, it's best to first read this topic as provided here in the order provided and then expand your knowledge once you have read it.</p>
<h2>Create an Environment</h2>
<p>Let's start by create a simple components (that does nothing) which will add into a frame.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Graphics;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyComponent extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
}</code></pre>
<p>Always start with a super simple class and then slowly evolve it testing each change on the way. Don't wait for bulk changes to test as then it may be too late to understand what's wrong.</p>
<p>Now it's time to create the frame and add the above component to it.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class MyFrame extends JFrame {
private MyComponent myComp;
public MyFrame() {
initComponents();
}
private void initComponents() {
setLayout(null);
myComp = new MyComponent();
myComp.setBorder(
BorderFactory.createLineBorder(Color.RED));
myComp.setBounds(10, 10, 400, 200);
add(myComp);
}
}</code></pre>
<p>Now let's kick off this example by creating another with the main method and have this show rolling</p>
<pre><code>package com.albertattard.pwtm;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MyMain {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createShowFrame();
}
});
}
private static void createShowFrame() {
JFrame frame = new MyFrame();
frame.setTitle("Playing with the Mouse");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}</code></pre>
<p>Now that we have all the require components in place let's run. The above three classes should produce the following (or something very similar).</p>
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8cxwWyu8LssOFGi1blIDgE0zI-kXf-YIuBA8E10xEAMp_tSnP-GwjnKZL3gjXSM2MGd6CyXO44LhUbWrsYGiMKrUt4NjMbd_yGoQOM8XVQH5ghVUVWndT7ps7FQoh4mEyiiHP1BNhQJA/s1600-h/PWTM%2001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8cxwWyu8LssOFGi1blIDgE0zI-kXf-YIuBA8E10xEAMp_tSnP-GwjnKZL3gjXSM2MGd6CyXO44LhUbWrsYGiMKrUt4NjMbd_yGoQOM8XVQH5ghVUVWndT7ps7FQoh4mEyiiHP1BNhQJA/s320/PWTM%2001.png" width="320" /></a><br /></p>
<h2>Let's start playing</h2>
<p>Java provides three methods/mechanisms that allow us, the developers, to use to handle mouse events. Let say that we want to change the background colour of my component whenever the mouse hovers over it and rest the colour when the mouse moves away from the component.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/2009-12-16_1457.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=300&containerheight=200&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/2009-12-16_1457.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/b2025001-55a3-4de2-bd85-2b7040cb7f2c/" scale="showall"></embed>
</object>
</div>
<p>We want that our component (the class called <code>MyComponent</code> defined above) to do something when the mouse is moved over it. Then, we have to register a mouse listener within this component and act accordingly. The <code>JComponent</code> class (which <code>MyComponent</code> inherits from) has all the logic we need, that is, methods that allow us to register mouse listeners. Whenever mouse events are occur, these methods will advise/notify our listeners with the changes and we can act accordingly. We first start by registering a mouse listener and then implement the methods we're interested in as illustrated below.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyComponent extends JComponent {
public MyComponent() {
initListeners();
}
private void initListeners() {
addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent e) {
setBackground(Color.WHITE);
repaint();
}
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}</code></pre>
<p>Hold your horses, I'm lost.</p>
<p>There's lot of new code in this class, so let's start understanding this bit by bit. Let's start with the <code>initListeners()</code> method. This method is registering a mouse listener by calling the <code>addMouseListener ()</code> method inherited from the <code>JComponent</code> class and pass our listener. For simplicity, some code was removed.</p>
<pre><code> private void initListeners() {
addMouseListener(<strong>/* The Mouse Listener*/</strong>);
}</code></pre>
<p>After removing all the other code, this method becomes very simple and understandable. If you refer to the previous example, we also included a constructor which is calling this method, which I don't believe it requires explanation. The <code>paintComponent ()</code> method was also enhanced which now fills a rectangle with the set colour. This rectangle has the same size of our component which makes it appear as the background colour.</p>
<p>Let's now turn our attention to the <a target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseListener.html"><code>MouseListener</code></a>. What is it? Whenever a mouse event is fired, (in laymen terms) the JVM advise our listener about the change. It does so by execute one of the five methods defined by the <code>MouseListener</code> listed below:<p>
<ul>
<li><code>mouseClicked()</code></li>
<li><code>mouseEntered()</code></li>
<li><code>mouseExited()</code></li>
<li><code>mousePressed()</code></li>
<li><code>mouseReleased()</code></li>
</ul>
<p>The method names are self explanatory but the process may not be. We first create an instance of the <code>MouseListener</code>, which is an interface, and override these methods. Then we register our listener with the component. When the mouse is clicked on our component, the method <code>mouseClicked()</code> will be executed. When the mouse hovers on our component, the method <code>mouseEntered()</code> is executed and when the mouse moves away from our component, the <code>mouseExited()</code>.</p>
<p>One last thing before we return to our example. How many from the mouse listener's methods do we need to use to fulfil our requirement? Only two, as the requirement is to change the background when the mouse hovers in and out of our component. Java provides what are referred to adaptors. WTF? Java provides a skeleton class that implement this interfaces and provide default methods (methods that do nothing) for all the interface methods. We can then extend this class and override the method we want. Since the adaptor overrides all the interface methods, we only have to override those we're interested in, which simplifies our work.</p>
<p>Back to our <code>initListeners()</code> method. We're creating an instance of <a target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseAdapter.html "><code>MouseAdapter</code></a>, and registering it with our component.</p>
<pre><code> private void initListeners() {
addMouseListener(<strong>new MouseAdapter() {
public void mouseExited(MouseEvent e) {
setBackground(Color.WHITE);
repaint();
}
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
repaint();
}
}</strong>);
}</code></pre>
<p>As you can see from the above code fragment, we're only overriding two methods, the <code>mouseEntered()</code> and <code>mouseExited()</code> methods. In these methods we're changing the background colour and calling the repaint method. </p>
<p>Straight forward he</p>
<h2>Getting it to the next level</h2>
<p>That was fun, but let's improve it. Let's draw (fill) a circle following the mouse motion. </p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/PWTM_03.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&containerheight=400&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/PWTM_03.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/8975f307-8ea3-4066-a437-73ba4df2695b/" scale="showall"></embed>
</object>
</div>
<p>Before we can do so, we have to discuss another thing, the <a href="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseEvent.html" target="_blank"><code>MouseEvent</code></a>.</p> Before the event is fired and our listeners' methods invoked, information about the event is gathered (by something else which you don't need to care about, at least for now) and forwarded to you (the developer) as an event object, the <code>MouseEvent</code> in this case. This object contains information pertaining to our event, such as the mouse position, the time of the event and other things which may be useful when processing such event. We can (need to) use such information to achieve our goal as shown below.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyComponent extends JComponent {
<strong> private Point mousePoint; </strong>
public MyComponent() {
<strong> setForeground(Color.BLUE); </strong>
initListeners();
}
private void initListeners() {
addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent e) {
setBackground(Color.WHITE);
repaint();
}
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
repaint();
}
});
<strong> addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});
</strong> }
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
<strong> if (mousePoint != null) {
int ballSize = 15;
g.setColor(getForeground());
g.fillOval(mousePoint.x - ballSize / 2,
mousePoint.y - ballSize / 2,
ballSize, ballSize);
}
</strong> }
}</code></pre>
<p>The changes from the previous class are highlighted and discussed below.</p>
<p>An instance field was added to our component. Why? We need to transfer the mouse position, <em>magically</em> provided to us by the mouse events (discussed later on), to the paint method. Since we cannot call the paint method directly from the event (the <code>reapint()</code> call is something else), we need to save this information in the instance field, <code>mousePoint</code>, and the use it from the paint method. This instance field is accessible by both methods. First this field is updated by the method</p>
<pre><code> public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}</code></pre>
<p>within our new adaptor, <a href="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseMotionAdapter.html" target="_blank"><code></code></a>. The method <code>mouseMoved()</code> is invoked every time the mouse is moved within our component. This is important to understand. Only the mouse events that are related with our component are captured by our listeners. So when the mouse moves out of our component, this method will stop being invoked.</p>
<p>Next we'll discuss the mouse clicks</p>
<h2>Handling the clicks</h2>
<p>Let say that we also want to handle the mouse click that happen on our component. For simplicity we'll display a simple text in the top left corner listing the number of click that occure as shown below.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/PWTM_04.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/PWTM_04.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/395ff137-2905-46ce-a64b-509ec4026dbb/" scale="showall"></embed>
</object>
</div>
<p>A long story short, add a new instance field (called <code>clickCount</code>) of type <code>int</code> and paint its value in the paint method as highlighted below. Also, override the appropriate method in the mouse adaptor.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyComponent extends JComponent {
private Point mousePoint;
<strong> private int clickCount; </strong>
public MyComponent() {
setForeground(Color.BLUE);
initListeners();
}
private void initListeners() {
addMouseListener(new MouseAdapter() {
public void mouseExited(MouseEvent e) {
setBackground(Color.WHITE);
repaint();
}
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
repaint();
}
<strong> @Override
public void mouseClicked(MouseEvent e) {
clickCount++;
repaint();
}
</strong> });
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
if (mousePoint != null) {
int ballSize = 15;
g.setColor(getForeground());
g.fillOval(mousePoint.x - ballSize / 2,
mousePoint.y - ballSize / 2, ballSize, ballSize);
}
<strong> if (clickCount > 0) {
g.setColor(getForeground());
g.drawString("Click Count: " + clickCount, 10, 20);
} else {
g.setColor(getForeground());
g.drawString("No Clicks!!!", 10, 20);
}
</strong> }
}</code></pre>
<p>The above code is not rocket science but it has a little flaw. If you drag the mouse inside the component, the blue circle will not follow the mouse pointer as illustrated below.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/PWTM_05.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/PWTM_05.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/b45febaf-ee31-46fc-a06b-ddf78d26f5ee/" scale="showall"></embed>
</object>
</div>
<p>Why not? The <a href="http://java.sun.com/javase/6/docs/api/java/awt/event/MouseMotionListener.html"><code>MouseMotionListener</code></a>, which the <code>MouseMotionAdapter</code> implements has two methods but we're only overriding one as illustrated below.</p>
<pre><code> addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
});</code></pre>
<p>The other method, <code>mouseDragged()</code>, is used to handle mouse dragging events as illustrated code fragment below.</p>
<pre><code> addMouseMotionListener(new MouseMotionAdapter() {
<strong> @Override
public void mouseDragged(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}</strong>
@Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
}); </code></pre>
<p>Dragging is more complex than one may think and is discussed further in the following section</p>
<h2>Dragging the mouse</h2>
<p>For this example, we'll create a new component and will make use of it rather than keep changing the other one. Like before, we'll start with a simple example and keep building on it. We'll start with the following simple component.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyDragComponent extends JComponent {
private Rectangle draggableShape;
public MyDragComponent() {
draggableShape = new Rectangle(20, 20, 50, 50);
setForeground(Color.BLUE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(getForeground());
g2d.fill(draggableShape);
}
}</code></pre>
<p>This component simply draws a solid blue 50 by 50 rectangle at the x and y coordinates 20 as illustrated below</p>
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgX8b-ejtuDzCeKNJolyXYtb3VBMIezY9B9Q-zH2OMRym2HFjVvdxOo-BFqS6Qetx592ezrgjc0KdWXU7XDHW14x70pvQ8ou5TMpBI9WpZ1RtZP75rVtFec0E3mTTf5jh7lz4teomjuO8/s1600-h/PWTM%2006.png" target="_blank" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgX8b-ejtuDzCeKNJolyXYtb3VBMIezY9B9Q-zH2OMRym2HFjVvdxOo-BFqS6Qetx592ezrgjc0KdWXU7XDHW14x70pvQ8ou5TMpBI9WpZ1RtZP75rVtFec0E3mTTf5jh7lz4teomjuO8/s320/PWTM%2006.png" width="320" /></a>
</p>
<p>Remember to add this component to the frame before you test it out</p>
<p>Let's start be arm our rectangle with a red border when the mouse enters the box as shown below. Note that the component has a red border and the mouse events are triggered for any mouse activity within the component. We need to filter out movements outside the rectangle and only arm the rectangle when the mouse is on it.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=312&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/PWTM_07.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/PWTM_07.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/7d47d54f-7dcf-42da-8351-c92e7aabdc60/" scale="showall"></embed>
</object>
</div>
<p>How can we do that? Quiet simple. Like before, we create a field (called <code>mouseInside</code>) and will set it to <code>true</code> when the mouse is within the rectangle and <code>false</code> otherwise. The updates are highlighted below.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyDragComponent extends JComponent {
private Rectangle draggableShape;
<strong> private boolean mouseInside; </strong>
public MyDragComponent() {
draggableShape = new Rectangle(20, 20, 50, 50);
setForeground(Color.BLUE);
<strong> initListeners();</strong>
}
<strong> private void initListeners() {
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
repaint();
}
});
}</strong>
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(getForeground());
g2d.fill(draggableShape);
<strong> if (mouseInside) {
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(3));
g2d.draw(draggableShape);
g2d.setStroke(new BasicStroke(1));
}</strong>
}
}</code></pre>
<span class="question">Why are we resetting the stroke at the end of the paint component method?</span>
<span class="answer">Ideally you rest all changes made to the graphics component once done as other paint methods for this object such paint border method will inherit your changes. In this case, if you do not reset the stroke the border will be painted with this stroke.</span>
<p>The following code fragment does the trick. The method <code>mouseMoved ()</code> is continually called by the underlying system (so to say) every time the mouse is moved over our component. When the mouse point (retrieved from the mouse event provided as the method parameter) is within the rectangle area, the <code>mouseInside</code> field is set to <code>true</code>.</p>
<pre><code> public void mouseMoved(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
repaint();
}</code></pre>
<p>Let's not stop here. Let's make the rectangle draggable. By draggable I mean that the user can drag the rectangle around our component as shown below.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/PWTM_08.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&containerheight=400&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/PWTM_08.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/cb8fc588-b1ba-44cd-9573-fdb0bf3454ca/" scale="showall"></embed>
</object>
</div>
<p>This is not an easy task and some may find it hard to understand but let's not panic. The following code does the job.</p>
<pre><code>package com.albertattard.pwtm;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class MyDragComponent extends JComponent {
private Rectangle draggableShape;
private boolean mouseInside;
<strong> private Point lastMousePoint; </strong>
public MyDragComponent() {
draggableShape = new Rectangle(20, 20, 50, 50);
setForeground(Color.BLUE);
initListeners();
}
private void initListeners() {
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
<strong> lastMousePoint = e.getPoint();</strong>
repaint();
}
<strong> @Override
public void mouseDragged(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
if (mouseInside) {
if (lastMousePoint != null) {
draggableShape.x +=
e.getPoint().x - lastMousePoint.x;
draggableShape.y +=
e.getPoint().y - lastMousePoint.y;
}
}
lastMousePoint = e.getPoint();
repaint();
}</strong>
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(getForeground());
g2d.fill(draggableShape);
if (mouseInside) {
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(3));
g2d.draw(draggableShape);
g2d.setStroke(new BasicStroke(1));
}
}
}</code></pre>
<p>Let's starts discussing the code.</p>
<p>When the mouse is dragged within the rectangle, we're also moving it. The rectangle can be dragged from anywhere within. So we have to take under consideration where the mouse was clicked within the rectangle and shift the rectangle by the offset, that is, by the amount the mouse was moved. We cannot simply set the rectangle's <code>x</code> and <code>y</code> coordinates to match those of the event. The following sketch highlights this (hopefully).</p>
<p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhltt5pgeemVZauTdqblnFCvMlRATBNBmyCsmCZMZptH4Uud5W0KhBM7inX0FRJuhgslhvyYhipt4nuEVE1wjIkY_PL4m9qZ6RV-ja1URDsTfqP-YTIExKzhpfNKNT963Qnso08mPsRszU/s1600-h/PWTM_03.png" target="_blank" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhltt5pgeemVZauTdqblnFCvMlRATBNBmyCsmCZMZptH4Uud5W0KhBM7inX0FRJuhgslhvyYhipt4nuEVE1wjIkY_PL4m9qZ6RV-ja1URDsTfqP-YTIExKzhpfNKNT963Qnso08mPsRszU/s320/PWTM_03.png" width="320" /></a></p>
<p>To do this we added a new field called <code>lastMousePoint</code>, which is used to save the last mouse position (as the name infers). Instead of setting the rectangle coordinates equal to the mouse coordinates we adjust them by how much the mouse was moved using the following (copy and paste from above) logic.</p>
<pre><code> @Override
public void mouseDragged(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
if (mouseInside) {
if (lastMousePoint != null) {
<strong> draggableShape.x +=
e.getPoint().x - lastMousePoint.x;
draggableShape.y +=
e.getPoint().y - lastMousePoint.y;
</strong> }
}
lastMousePoint = e.getPoint();
repaint();
}</code></pre>
<p>It is important to also update the <code>lastMousePoint</code> field before we exit the above method.</p>
<p>A tip for the champions. If you observe the previous class, you notice that the field <code>lastMousePoint</code> is only used within the adaptor. Ideally we move this field within the adaptor as highlighted below.</p>
<pre><code> addMouseMotionListener(new MouseMotionAdapter() {
<strong> private Point lastMousePoint; </strong>
@Override
public void mouseMoved(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
lastMousePoint = e.getPoint();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
if (mouseInside) {
if (lastMousePoint != null) {
draggableShape.x +=
e.getPoint().x - lastMousePoint.x;
draggableShape.y +=
e.getPoint().y - lastMousePoint.y;
}
}
lastMousePoint = e.getPoint();
repaint();
}
});</code></pre>
<p>Too keep it simple, the above change will not apply to the rest of the examples</p>
<p>One last thing before we go. Note that we're able to drag the rectangle outside the component printable area. This is not always good and we would like to prevent this as illustrated below.</p>
<div style="margin-top: 1em; margin-left: 1em; margin-right: 1em;">
<object classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" width="320" height="213">
<param name="movie" value="http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/jingswfplayer.swf"></param>
<param name="quality" value="high"></param>
<param name="bgcolor" value="#FFFFFF"></param>
<param name="flashVars" value="containerwidth=320&containerheight=213&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/PWTM_09.swf&blurover=false"></param>
<param name="allowFullScreen" value="true"></param>
<param name="scale" value="showall"></param>
<param name="allowScriptAccess" value="always"></param>
<param name="base" value="http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/"></param>
<embed src="http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="320" height="213" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="containerwidth=600&containerheight=400&thumb=http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/FirstFrame.jpg&content=http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/PWTM_09.swf&blurover=false" allowFullScreen="true" base="http://content.screencast.com/users/albertattard/folders/Jing/media/d6e3a581-0e5e-4542-bca3-9cb94af3a227/" scale="showall"></embed>
</object>
</div>
<p>This is not a difficult change. All we need to do is cap the changes to the rectangle as illustrated in the following code fragment.</p>
<pre><code> @Override
public void mouseDragged(MouseEvent e) {
mouseInside = draggableShape.contains(e.getPoint());
if (mouseInside) {
if (lastMousePoint != null) {
draggableShape.x +=
e.getPoint().x - lastMousePoint.x;
draggableShape.y +=
e.getPoint().y - lastMousePoint.y;
<strong> draggableShape.x = Math.max(draggableShape.x, 0);
draggableShape.x = Math.min(draggableShape.x,
getWidth() - draggableShape.width);
draggableShape.y = Math.max(draggableShape.y, 0);
draggableShape.y = Math.min(draggableShape.y,
getHeight() - draggableShape.height);
</strong> }
}
lastMousePoint = e.getPoint();
repaint();
}</code></pre>
<p>The rest of the class is not listed for brevity.</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-25729818741174520602009-11-10T16:12:00.006+01:002009-12-17T09:46:43.602+01:00Capturing Tab key in GWT TextArea<p>A common thing developers have to deal with when using text areas in their web applications is the TAB key. Different from most of the other common web UI components, the text area component may require to capture the TAB key and "<em>display</em>" it as part of the text instead of transferring the focus to the next UI component in line.</p>
<p>This article will discuss how to capture the TAB key and prevent the transfer of focus within the text area. Technically speaking this code should happen within JavaScript, but this article makes use of the Google Web Toolkit (GWT). Here we're not going to discuss the pros and cons of GWT, but one should consider such API when developing JavaScript websites. Please refer to <a href="http://code.google.com/webtoolkit/" target="_blank">http://code.google.com/webtoolkit/</a> for more information about GWT.</p>
<p>For those of you who would only like to see the solution, please click <a href="#example">here</a> or scroll down to the bottom. For the others who would like to read about it; we'll start with a simple example and will be incrementing on it as we go along.</p>
<h2>The Solution</h2>
<p>We need to do the following things in order to capture the TAB key within the text area:</p>
<ul>
<li>Listen to key (Key Down) events</li>
<li>Filter the TAB key (check if the TAB key is pressed)</li>
<li>Prevent the default action and stop event propagation</li>
<li>Insert the tab character at the current cursor position</li>
<li>Register the listener with the text area</li>
</ul>
<p>Each of the above points are discussed, first individually and then merged together as one solution.</p>
<h3>Key Down Event Handler</h3>
<p>There are three types of key events (and handlers which handle the respective event):</p>
<ul>
<li>Key Down</li>
<li>Key Up</li>
<li>Key Pressed</li>
</ul>
<p>The first question that comes to mind is, why three? Very simple; there are situations, like ours, where you want to handle the events before they trigger other events (transfer focuse), while in other cases we just want to act after these happened, such as the key pressed event (spellchecker for example). In our case we want to disable the default behaviour from propagating any further and prevent the text area from losing its focus.</p>
<p>GWT provides the <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/event/dom/client/KeyDownHandler.html"><code>com.google.gwt.event.dom.client.KeyDownHandler</code></a> interface that can be registered with a text area and is invoked by the text area whenever a key is pressed. To be precise, this handler is invoked when the key is down (the first from the three handlers mentioned above). The <code>KeyDownHandler</code> interface has only one method called <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/event/dom/client/KeyDownHandler.html#onKeyDown(com.google.gwt.event.dom.client.KeyDownEvent)"><code>onKeyDown()</code></a> that expects one parameter of type: <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/event/dom/client/KeyDownEvent.html"><code>com.google.gwt.event.dom.client.KeyDownEvent</code></a>. The following code fragment shows how to create a key down handler (Java - GWT).</p>
<pre><code>KeyDownHandler handler = new KeyDownHandler() {
@Override
public void onKeyDown(KeyDownEvent event) {
// Handle key down event here
}
}</code></pre>
<span class="question">How come you're creating an instance of an interface?</span>
<span class="answer"> As you can see form the above example, Java allows to create new classes that extends or implements other classes and interfaces on-the-fly. These are called, anonymous inner classes. Anonymous, because the new class does not have a name. This is very convenient as you don't have to create a new class, but just implement in within the class you're using it.</span>
<p>We can now register the above handler with the text area as illustrated in the following code fragment</p>
<pre><code>TextArea textArea = new TextArea();
textArea.addKeyDownHandler(handler); </code></pre>
<p>The numbered list shown above, lists this step as last. It doesn't make a difference when you register the handler, as long as the handler is initialised and not <code>null</code>.</p>
<h3>Filter the TAB key</h3>
<p>The <code>onKeyDown()</code> method is invoked by the text area every time a key is pressed while it's in focus. The text area will only invoke this method when you're typing in it. With that said, we only need to act when the TAB key is pressed. All the other keys are ignored. To do that, we have to filter the TAB by using the its ASCII decimal value: <code>9</code>, as highlighted in the following code fragment.</p>
<pre><code>KeyDownHandler handler = new KeyDownHandler() {
@Override
public void onKeyDown(KeyDownEvent event) {
<strong> if (event.getNativeKeyCode() == 9) {
// Handle TAB key down event here
}</strong>
}
}</code></pre>
<p>The <code>if</code> statement will only yield <code>true</code> when the TAB key is pressed, otherwise <code>false</code></p>
<h3>Prevent the default action and stop event propagation</h3>
<p>By default, when the TAB key is presses, the focus is transferred from the UI component that has it to the next <a href=" http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/ui/Focusable.html" target="_blank"><code>com.google.gwt.user.client.ui.Focusable</code></a> component. We have to prevent the default behaviour by invoking the methods <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/event/dom/client/DomEvent.html#preventDefault()" target="_blank"><code>preventDefault()</code></a> and <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/event/dom/client/DomEvent.html#stopPropagation()" target="_blank"><code>stopPropagation()</code></a> on the <code>KeyDownEvent</code> instance provided as a parameter to the <code>onKeyDown()</code> method.</p>
<pre><code>KeyDownHandler handler = new KeyDownHandler() {
@Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == 9) {
<strong> event.preventDefault();
event.stopPropagation();</strong>
}
}
}</code></pre>
<p>The above code will capture the TAB key events and will prevent the text area from losing its focus, but unfortunately will not print the TAB key in the text area. We have to programmatically add this key to the text area text as shown in the following section</p>
<h3>Insert the tab character at the current cursor position</h3>
<p>This should be the least of our problems but one must pay attention. Remember that the user may be editing in the middle of the document so we cannot just append the TAB at the end. We have to insert the TAB just right where the cursor is as highlighted in the following code fragment.</p>
<pre><code>KeyDownHandler handler = new KeyDownHandler() {
@Override
public final void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == 9) {
event.preventDefault();
event.stopPropagation();
<strong> if(event.getSource() instanceof TextArea) {
TextArea ta = (TextArea) event.getSource();
int index = ta.getCursorPos();
String text = ta.getText();
ta.setText(text.substring(0, index)
+ "\t" + text.substring(index));
ta.setCursorPos(index + 1);
}</strong>
}
}
};</code></pre>
<p>This can be easier said than done for some. So let's start line by line. We're first checking that the source is of type <code>TextArea</code>. We don't have to do this, but it will prevent an exception should someone else use this handler with another UI component that text area. Next, we're casting the source which triggered the event into a <code>TextArea</code>. Then we retrieved the cursor position (as an integer) and all its text in the line following that. Now, we split the text retrieved in two parts: the part before the cursor and the part following the cursor. We create a new string made from, the both parts delimited with the TAB character with is attaching both parts shown below.</p>
<pre><code>ta.setText(text.substring(0, index)
+ "\t" + text.substring(index));</code></pre>
<p>Finally, we set the cursor location just after the TAB key, that is, one up in respect to the cursor before the key was pressed.</p>
<a name="example"></a><h2>The Example</h2>
<p>Complete example</p>
<pre><code>public static final KeyDownHandler DEFAULT_TEXTAREA_TAB_HANDLER = new KeyDownHandler() {
@Override
public final void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == 9) {
event.preventDefault();
event.stopPropagation();
final TextArea ta = (TextArea) event.getSource();
final int index = ta.getCursorPos();
final String text = ta.getText();
ta.setText(text.substring(0, index)
+ "\t" + text.substring(index));
ta.setCursorPos(index + 1);
}
}
};</code></pre>
<p>Use</p>
<pre><code>final TextArea textArea = new TextArea();
textArea.addKeyDownHandler(DEFAULT_TEXTAREA_TAB_HANDLER); </code></pre>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com4tag:blogger.com,1999:blog-6929422799523574458.post-25537860417502771942009-10-28T10:23:00.003+01:002009-10-28T10:38:22.732+01:00Practical Example of Entropy<strong>This article is the fruit of a discussion held between Maura Paterson, Paulo Cardoso and myself about Shannon's entropy in information theory.</strong>
<p>
Entropy, <code>H(x)</code>, can be thought of as a way of measuring how difficult it is to get an answer correct by guessing. In other words, entropy represents the uncertainty value. If the next outcome of the challenge at hand is certain (we all know what it will be), then the entropy is <code>0</code> as there is no uncertainty.
<p>
The entropy <code>H(x)</code>, where the value of <code>x</code> is selected randomly from the set <code>{x<sub>1</sub>, x<sub>2</sub>, ..., x<sub>n</sub>}</code> (of size <code>n</code>) can be calculates using the following formula:
<p align="center">
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiPQmWyIkafe_inqSUz4pU6YrrePbE_I6_kAPFeu-adyQVMYNTan91DXUWtUXrIdD5Zv9yWDUevSficqPfkHzR4lBwyPqmq00SEzDoAG_xJGUB6BcYmIgG-w37Ervu6X1xFy3IPkijjg0/s320/Entropy+01.jpg" />
<p>
where <code>b</code> is the number of symbols in the target alphabet and <code>p(x<sub>i</sub>)</code> is the probability mass function of outcome <code>x<sub>i</sub></code>. In this article the target alphabet is the binary alphabet which only contains two symbols: <code>{0, 1}</code>
<p>
<span class="question">Why are there two ways to calculate entropy?</span>
<span class="answer">The first formula is the general formula and suites all scenarios, while the second formula (<code>log<sub>b</sub>(n)</code>) is only used when the elements in the set <code>x</code> have equal probability to be selected (the selection is not biased)</span>
<p>
<strong>Example 1</strong>: If I pick a weekday (<em>Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday</em>) uniformly at random, then ask you to guess which day I picked, the best you can hope to do is guess randomly, and the entropy is <code>log<sub>2</sub>(7) = 2.81</code>. In this example we've used the simplest part of the formula (<code>log<sub>b</sub>(n)</code>) as all elements had the same probability.
<p>
<strong>Example 2</strong>: However, if I pick a weekday using the distribution that I pick <em>Sunday</em> with probability <code>1/2</code>, and each other day with probability <code>1/12</code> then we can use the formula to compute the fact that the entropy of this distribution is <code>2.29</code>, i.e. the uncertainty is less than in the previous case. This value is calculated as follows:
<pre><code>-( 1/2×log<sub>2</sub>(1/2)
+ 1/12×log<sub>2</sub>(1/12)
+ 1/12×log<sub>2</sub>(1/12)
+ 1/12×log<sub>2</sub>(1/12)
+ 1/12×log<sub>2</sub>(1/12)
+ 1/12×log<sub>2</sub>(1/12)
+ 1/12×log<sub>2</sub>(1/12) )
=
-( 1/2×log<sub>2</sub>(1/2)
+ 6/12×log<sub>2</sub>(1/12) )
= 2.29</code></pre>
<p>
This makes sense, because in the last scenario your best strategy is to guess that I've picked <em>Sunday</em> and you will be correct much more often than in the previous case.
<h2>Conditional Entropy</h2>
<p>
If you think in terms of bits, you need (almost) three bits to represent all the weekdays. Example:
<p>
<pre><code>000 = Sunday
001 = Monday
...
110 = Saturday
111 is not used.</code></pre>
<p>
<strong>Example 3</strong>: We established that the entropy <code>H(x)</code> of the original distribution was <code>log<sub>2</sub>(7) = 2.81</code>. Learning that the first bit is <code>0</code> gives you extra information, since we now know it can only be <em>Sunday, Monday, Tuesday or Wednesday</em>. In this case the entropy <code>H(x|the first bit of x is 0)</code> is <code>log<sub>2</sub>(4) = 2</code> (since there are four equiprobable possibilities remaining). The extra information has reduced the uncertainty.
<p>
The entropy <code>H(x|the first bit of x is 1)</code> is <code>log<sub>2</sub>(3) = 1.58</code>. Thus if <code>x</code> is the variable representing the day of the week and <code>y</code> is the variable representing the first bit of the encoding we have that the conditional entropy <code>H(x|y) = 4/7× log<sub>2</sub>(4) + 3/7×log<sub>2</sub>(3) = 4/7× 2 + 3/7×1.58 = 1.822</code>. The first half of the equation: <code>4/7×2</code> represents the option when the first bit is 0 while the second half, <code>3/7×1.58</code>, when the first bit is 1. So we see that in this case <code>H(x) > H(x|y)</code>, so we can conclude that learning the first bit of the encoding does give you some information about <code>x</code> (it reduces the uncertainty over the value of <code>x</code>).
<p>
In order to be correct you'd need to see three bits, unless the first two bits you saw were <code>11</code>, in which case you'd know the answer was <code>110</code>, since we are not using the binary string <code>111</code>. In fact this depends on the encoding you are using for each of the possibilities (for example, we could take the above encoding and add <code>10</code> zeros in front of each triple to get a new, very wasteful, encoding. In this case you'd have to see <code>13</code> bits most of the time.) However, the value of the entropy gives a lower bound on the expected number of bits that will be required no matter what encoding is used.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-403232393338050792009-10-13T14:12:00.013+02:002009-10-21T15:51:20.979+02:00Practical Example of Simple Java UI ComponentIn this article we'll discuss how to create a <u>simple</u> Java graphical component such as a <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JButton.html" target="_blank">javax.swing.JButton</a> (without going into details of event handling) and include it within an application. Our component will display (paint) a flat rectangle of a set colour as illustrated below.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAunccVsKmhJVD9Jqzg2lQ6eDkykZ5TLBdJOsg-ESeLF786PhwvxoqNUUKu7iGqjUgLg5AP40F5NrI_MyFBaGNUOkm1gfniVpE0pbSJyrwfTUOwJV9tbl4NO_xOhSpLc6cpjz4bkuKy0w/s1600-h/Custom+UI+Demo+1.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5392016484139971746" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAunccVsKmhJVD9Jqzg2lQ6eDkykZ5TLBdJOsg-ESeLF786PhwvxoqNUUKu7iGqjUgLg5AP40F5NrI_MyFBaGNUOkm1gfniVpE0pbSJyrwfTUOwJV9tbl4NO_xOhSpLc6cpjz4bkuKy0w/s320/Custom+UI+Demo+1.jpg" style="cursor: hand; cursor: pointer; height: 200px; width: 320px;" /></a>
<p>
We'll be making use of two classes one representing the simple custom component and the other will be mounting the frame and including our component in it. All classes discussed here are saved under the package "<code>com.albertattard.cgui</code>". You can change this to your own package. In this article we'll only be exploring the creation of simple custom UI component. Many other related topics will be only mentioned here but not discussed. While you are encouraged to explore all the topics that are only mentioned (but not discussed) here, one must be cautious not to overwhelm him/herself in the process.
<h2>
Custom UI Component</h2>
All Java Swing (don't worry if you don't know with Swing means but if you insist here is a link which may answer some of your questions: <a href="http://java.sun.com/docs/books/tutorial/uiswing/" target="_blank"> http://java.sun.com/docs/books/tutorial/uiswing/</a>) graphical components inherit from the <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html" target="_blank">javax.swing.JComponent</a> abstract class. Our component is no exception. So let's start by creating a simple class called: <code>FlatRectComponent</code>. This class will be extending the <code>JComponent</code> class mentioned earlier and will override the <code>paintComponent()</code> method as highlighted in the example below.
<p>
<pre><code>package com.albertattard.cgui;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class FlatRectComponent <strong>extends JComponent</strong> {
<strong> @Override
protected void paintComponent(Graphics g) {
// Clear the previous screen
super.paintComponent(g);
// Set the painting colour to magenta
g.setColor(Color.MAGENTA);
// Draw a solid rectangle at coordinates x and y set to
// 10px with width and height set to 100px
g.fillRect(10, 10, 100, 100);
}</strong>
}</code></pre>
<span class="question">Why did we override the <code>paintComponent()</code> method?</span>
<span class="answer">All UI programs are responsible from painting themselves on the screen. For example this article you're reading is an image displayed on your screen (unless you printed it on a piece of paper). The browser downloaded this article as HTML and transformed (or better rendered) it as an image. All other applications do the same. For example a button, is a simple set of paint instructions which makes it look real (as you see it on the screen). Also events, such as mouse hovering, may change the way the button or any other graphical component looks making the graphics interacting with the user inputs.</span>
<p>
In the case of Java, all graphical components are responsible of painting themselves by overriding the <code>paintComponent()</code> method and paint on the provided <a href="http://java.sun.com/javase/6/docs/api/java/awt/Graphics.html" target="_blank">java.awt.Graphics</a>. In the above example, we're simply painting a flat rectangle in magenta. Then this method is called by some other class which displays it on the screen as you see it. You don't have to worry about how or what invokes this method. Just remember that you cannot call it yourself.
<p>
Alone this class is not of much use. But since it's inheriting from the <code>JComponent</code> class, we can include it with other Java Swing components such as <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JFrame.html" target="_blank">javax.swing.JFrame</a>.
<h2>
Including it in a JFrame</h2>
Let's create a simple frame which will host our new component. For simplicity, we're not going to discuss <a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html" target="_blank">Layout Managers</a>. We're going to use the absolute layout where we specify the location and size for every component. An example of our frame class is shown below.
<p>
<pre><code>package com.albertattard.cgui;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class FrameDemo extends JFrame {
private static void createFrame() {
JFrame frame = new FrameDemo();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setTitle("Custom UI Demo");
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createFrame();
}
});
}
private FrameDemo() {
// Set the layout of this frame to absolute layout
setLayout(null);
// Create the flat rectangle component and add it to
// the frame
FlatRectComponent comp = new FlatRectComponent();
comp.setBounds(0, 0, 200, 200);
add(comp);
}
}</code></pre>
The above class contains two static methods and a constructor. Let's analyse these further starting from the <code>main()</code> method. The <code>main()</code> method is the first method called by the JVM. This is from where the application starts. This method calls the other static method <code>createFrame()</code> by scheduling a job on the AWT event dispatching thread. This sounds as complex as rocket science but you have nothing to be afraid from. For now all you have to do is copy and paste it. The static method <code>createFrame()</code> creates an instance of our frame class, <code>FrameDemo</code> and set the frame properties, such as title, size and location.
<p>
The constructor of this class starts by setting the layout manager to absolute layout. Then it creates an instance of our components and set its size and location accordingly. The <a href="http://java.sun.com/javase/6/docs/api/java/awt/Component.html#setBounds(int, int, int, int)" target="_blank">setBounds()</a> method takes four parameters, the first two represent the location as <em>x</em> and <em>y</em> coordinate while the latter to represent the <em>size</em>. Finally it adds this component to its container (don't worry about containers for now - this is the fort time I'm asking to accept something as is without having to dig any further). This is a very important step. Many forget to add the components and then wonder why these don't appear in the frame.
<p>
<span class="question">How many instances of our component can we include in the frame?</span>
<span class="answer">As many as you want. In practice there's a limit which is dependent on the amount of memory available to your application, but you don't have to worry about that neither as our application is fairly simple and consume very little memory. Let's amend the previous frame class and include another instance of the <code>FlatRectComponent</code> UI component. All we need to do is create another instance and adding this instance to the frame's container. We also need to set the bounds of the new component such that this don't conflict with the previous one as otherwise we may have a graphical issue. The following code fragment highlights the changes made to the frame class. Only the constructor was changed, the other methods are unchanged and thus not shown here. Also, note that a border was added to the components to visualise the component perimeter.</span>
<p>
<pre><code> private FrameDemo() {
setLayout(null);
// The first component
FlatRectComponent comp1 = new FlatRectComponent();
comp1.setBounds(0, 0, 200, 200);
<strong>comp1.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));</strong>
add(comp1);
<strong> // The second component
FlatRectComponent comp2 = new FlatRectComponent();
comp2.setBounds(250, 50, 200, 200);
comp2.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));
add(comp2); </strong>
}</code></pre>
The program should now display two, identical, components as illustrated below.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEiFt_6lOgOUmY3CpPIjpgMYDfXjZfxD5WPYyOKVNhCHuVGBEb29auJQttrZJ9qi7A4MXD64oL1S0Vv6zrDrS_6TQzarQfaLzEcPxticRv9-BQJqGVAuu6RQNJ30qy_dvNvZopMDmvUsI/s1600-h/Custom+UI+Demo+2.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5392035210533765554" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEiFt_6lOgOUmY3CpPIjpgMYDfXjZfxD5WPYyOKVNhCHuVGBEb29auJQttrZJ9qi7A4MXD64oL1S0Vv6zrDrS_6TQzarQfaLzEcPxticRv9-BQJqGVAuu6RQNJ30qy_dvNvZopMDmvUsI/s320/Custom+UI+Demo+2.jpg" style="cursor: hand; cursor: pointer; height: 214px; width: 320px;" /></a>
<h2>
Customising the Custom UI Component</h2>
As is, our component is not much of use as we cannot customise it. The <code>painComponent()</code> method make use of literals and constants and so our component will always look like that. In order to be able customise it we need to add some states to our custom UI component.
<p>
<span class="question">What are these?</span>
<span class="answer">States in objects are <em>instance fields</em>, or as some call them: <em>class variables</em>. The instance fields are used to save the state of the object. The state of the object is all information about the object. For example our custom UI component displays a rectangle. This rectangle needs to have an <em>x</em> and <em>y</em> coordinates and a <em>size</em>. A rectangle cannot exist without these states (properties). Try to draw a rectangle on a piece of paper yourself without making use of the mentioned states. You'll notice that you cannot as, as soon as you draw it, you have provided the <em>x</em>, <em>y</em> and <em>size</em> states. In this case we need to capture these states in some instance fields. The same applies for the rectangle colour.</span>
<p>
We can start by adding an instance of the <a href="http://java.sun.com/javase/6/docs/api/java/awt/Rectangle.html" target="_blank">java.awt.Rectangle</a> class and save our rectangle states (size and location) there. Alternatively, we can create four integer variables which represent the <em>x</em>, <em>y</em>, <em>width</em> and <em>height</em> values for our rectangle. Even though it may sound more complex I suggest we go with the first option as this give us other functionality already available in the <code>Rectangle</code> class, which otherwise we have to program, such as the <a href="http://java.sun.com/javase/6/docs/api/java/awt/Rectangle.html#translate(int, int)" target="_blank">translate()</a> method.
<p>
<pre><code>package com.albertattard.cgui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class FlatRectComponent extends JComponent {
<strong>private Rectangle rect = new Rectangle(10, 10, 100, 100); </strong>
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Make use of the 2D version of the Graphics component
<strong>Graphics2D g2D = (Graphics2D) g; </strong>
g2D.setColor(Color.MAGENTA);
<strong>g2D.fill(rect); </strong>
}
}</code></pre>
In the above example we've changed the way the rectangle is painted. Before we used literals, while now we're painting an instance of <code>Rectangle</code>. Also, now we're using a <a href="http://java.sun.com/javase/6/docs/api/java/awt/Graphics2D.html" target="_blank">java.awt.Graphics2D</a> component instead of the <code>Graphics</code> component. We're not going to go into much detail about this here as otherwise we'll be ending up writing a book. But in a nutshell, the <code>Graphics2D</code> inherits from the <code>Graphics</code> and adds more functionality (methods) which we can use. The object invoking out <code>paintComponent()</code> method (which we agreed not to discuss here) will be passing an instance of <code>java.awt.Graphics2D</code> to the <code>paintComponent()</code> method. All we're doing is recasting it back to its original form. Don't worry about this for now. All you need to know is that you should cast your <code>Graphics</code> to <code>Graphics2D</code>.
<p>
So far we have not yet provided any means (methods) which allow the rectangle instance field, <code>rect</code>, to be changed. That is, there is no way how one can change the <em>x</em>, <em>y</em> and <em>size</em> values for this instance. Let's add four methods, which can be used to set the any of the rectangle states.
<p>
<pre><code>package com.albertattard.cgui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
@SuppressWarnings("serial")
public class FlatRectComponent extends JComponent {
private Rectangle rect = new Rectangle(10, 10, 100, 100);
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.MAGENTA);
g2D.fill(rect);
}
<strong> public void setHeight(int height) {
rect.height = height;
repaint();
}
public void setWidth(int width) {
rect.width = width;
repaint();
}
public void setX(int x) {
rect.x = x;
repaint();
}
public void setY(int y) {
rect.y = y;
repaint();
}</strong>
}</code></pre>
Note that at the end of every <code>set<em>XXX</em>()</code> method we're calling the <code>repaint()</code> method. All we're doing here is instructing the frame's container (this is the guy which is invoking our <code>paintComponent()</code> method) to repaint this component. The frame's container will in turn call the <code>paintComponent()</code> method for this component and providing the appropriate information. It is important to do so after every change as otherwise your changes will not immediately appear. But these will appear only when the frame completely repaints all its components. Remember that you cannot call the <code>paintComponent()</code> yourself. All you can do is call the <code>repaint()</code> method.
<p>
So far we've only provided a means to customise our component. But we have not yet customized it. Let's do that. We can customise our component by calling the <code>set<em>XXX</em>()</code> from the frame class as highlighted bold below. The following code fragment only shows the constructor of the frame class as the other methods are unchanged.
<p>
<pre><code> private FrameDemo() {
setLayout(null);
// The first component
FlatRectComponent comp1 = new FlatRectComponent();
comp1.setBounds(0, 0, 200, 200);
<strong> comp1.setX(5);
comp1.setY(5);
comp1.setWidth(190);
comp1.setHeight(190); </strong>
comp1.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));
add(comp1);
// The second component
FlatRectComponent comp2 = new FlatRectComponent();
comp2.setBounds(250, 50, 200, 200);
<strong> comp2.setX(50);
comp2.setY(50);
comp2.setWidth(100);
comp2.setHeight(100); </strong>
comp2.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));
add(comp2);
}</code></pre>
The above program should produce the following outcome.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcd-ftO9STrZgfjI0P5CrK1C5R_gn8Ly071ZO-TZr1sPnJkwhg_2A4pvDyZ_r1LL1u3Z75__gWyA_4gqk5o55Ist9TBpf2iLXz1S5X8TfcCdHfIxnhSX_M3EuezSSPy7F4uSxAhU7Z9co/s1600-h/Custom+UI+Demo+3.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcd-ftO9STrZgfjI0P5CrK1C5R_gn8Ly071ZO-TZr1sPnJkwhg_2A4pvDyZ_r1LL1u3Z75__gWyA_4gqk5o55Ist9TBpf2iLXz1S5X8TfcCdHfIxnhSX_M3EuezSSPy7F4uSxAhU7Z9co/s320/Custom+UI+Demo+3.jpg" style="cursor: hand; cursor: pointer; height: 200px; width: 320px;" /></a>
<p>
Note that now the coloured rectangle size and location can be varied from the setter methods provided. This makes our component customizable. We can also change the paint colour by including an instance field representing the colour and a method in our custom UI component which changes the colour as illustrated below.
<p>
<pre><code>// imports not shown here
public class FlatRectComponent extends JComponent {
<strong>private Color rectColour = Color.MAGENTA; </strong>
// other field and methods are not show for brevity
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
<strong>g2D.setColor(rectColour); </strong>
g2D.fill(rect);
}
<strong> public void setRectangleColour(Color rectColour) {
this.rectColour = rectColour;
repaint();
}</strong>
}</code></pre>
All we need to do now is call this method and change the colour accordingly as highlighted below.
<p>
<pre><code> private FrameDemo() {
setLayout(null);
// The first component
FlatRectComponent comp1 = new FlatRectComponent();
comp1.setBounds(0, 0, 200, 200);
comp1.setX(5);
comp1.setY(5);
comp1.setWidth(190);
comp1.setHeight(190);
<strong>comp1.setRectangleColour(Color.GREEN); </strong>
comp1.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));
add(comp1);
// The second component
FlatRectComponent comp2 = new FlatRectComponent();
comp2.setBounds(250, 50, 200, 200);
comp2.setX(50);
comp2.setY(50);
comp2.setWidth(100);
comp2.setHeight(100);
<strong>comp2.setRectangleColour(Color.CYAN); </strong>
comp2.setBorder(
BorderFactory.createLineBorder(Color.BLACK, 1));
add(comp2);
}
</code></pre>
<p>The following screenshot shows the final version of our program.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMOrXLD5MfYsfZyI6Ydzy6U-J_w7bUrzUrwueiLnotXLedK6zxbD1WgNHr970mlXHa5xXGvPWIfMaSbMeyHU-YIFD1P044fjg5OkpxuAb2zCk_RfSQqbS3JUhjKmf82SRAoSxP7sWSUSk/s1600-h/Custom+UI+Demo+4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMOrXLD5MfYsfZyI6Ydzy6U-J_w7bUrzUrwueiLnotXLedK6zxbD1WgNHr970mlXHa5xXGvPWIfMaSbMeyHU-YIFD1P044fjg5OkpxuAb2zCk_RfSQqbS3JUhjKmf82SRAoSxP7sWSUSk/s320/Custom+UI+Demo+4.jpg" /></a>
<h2>Conclusion</h2>
In this article we've saw how to create a simple custom Java UI component and display a simple flat rectangle. We've also added methods which can be used to customise this component.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com1tag:blogger.com,1999:blog-6929422799523574458.post-85228452727385916592009-10-12T16:04:00.016+02:002009-10-21T15:54:01.536+02:00Generic close methodAll resources need to be released once ready from them. This is usually done by invoking a <em>close</em> or <em>dispose</em> method depending on the object. These methods are usually invoked form the <code>finally</code> block following the <code>try</code> and <code>catch</code> blocks to ensure that the resources are released. Also, these methods may throw an exception during the process which we rarely use. But if we don't capture the exception the finally block will fail and not fully complete, failing to release the following resources.
<p>
Let say we're copying form one stream to another. Then we need to close both streams at the end of the process as illustrated below.
<p>
<pre><code>package com.albertattard.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class CopyTwoStreams {
public static void main(String[] args) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
// copy code here
} finally {
in.close();
out.close();
}
}
}</code></pre>
<p>
If an exception is thrown while closing the input stream, the output stream is never closed as the finally block will stop executing.
<h2>Handling Exceptions within the <code>finally</code> block</h2>
There are several ways how we can handle exceptions within the <code>finally</code> block. One alternative is to make use of a <code>try</code> and <code>catch</code> blocks but that may look bad (from a visual perspective). Alternatively, we can have a method which closes our streams and also absorbing any exceptions that may be thrown during the process.
<p>
As from Java 1.5, the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/Closeable.html" target="_blank">java.io.Closable</a> interface was introduce to the Java IO package and most (if not all) classes (and interfaces) in this package implement this interface. As you can see from the JavaDoc, this interface has only one method named <code>close()</code>. The good thing about this interface is that you can define one generic method which handles the close invocation. Following is a simple example:
<p>
<pre><code>
public static IOException close(Closeable c){
if(c != null) {
try {
c.close();
} catch(IOException e) {
return e;
}
}
return null;
}
</code></pre>
<p>
So now we can change our previous code to make use of this new static method.
This method simply attempts the close a non-null closable object and returns <code>null</code> if either the object provided is <code>null</code> or it managed to close the object without any issues. Otherwise, the exception thrown in the process is returned (instead of propagated) to the caller.
<p>
<pre><code>package com.albertattard.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class CopyTwoStreams {
public static void main(String[] args) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
// copy code here
} finally {
<strong> close(in);
close(out);</strong>
}
}
}</code></pre>
<p>Any exceptions thrown during the first close are absorbed and only returned by the new static <code>close()</code> method. These will not disrupt the flow of the <code>finally</code> block and all streams' <code>close()</code> methods are invoked.
<p>
Unfortunately the above method cannot be used with classes and interfaces that do not implement or inherit from the <code>Closable</code> interface. Classes and interfaces outside the Java IO package such as the interface <a href=" http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html" target="_blank">java.sql.Connection</a> cannot benefit from such a method.
<h2>A generic approach</h2>
By using reflection, we can retrieve the <code>close()</code> method and dynamically invoke it. Our generic method can be used with anything that has a method called <em>close</em> which takes no parameters, just like the method defined by the <code>Closeable</code> interface. The advantage of this approach is that we don't have to handle different close objects with different methods which basically do the same thing - simple close the object and absorbing any exceptions thrown in the process.
<p>
<pre><code> public static <strong>Exception</strong> close(Object o){
if(o != null) {
try {
<strong> Class<?> clazz = o.getClass();
Method closeMethod =
clazz.getDeclaredMethod("close", new Class[0]);
closeMethod.invoke(o, new Object[0]); </strong>
} catch(<strong>Exception e</strong>) {
return e;
}
}
return null;
}</code></pre>
<p>
We had to make some changes to our original static <code>close()</code> method to make use of reflection (highlighted in the above example). In a nutshell our Java classes, fields and methods are represented by other Java classes which we can use and invoke. A more comprehensive explanation about reflection can be found in this article <a href="http://today.java.net/pub/a/today/2008/02/12/reflection-in-action.html" target="_blank">Reflection in Action</a>.
<h2>Conclusion</h2>
This short article illustrated how to write a simple generic method that can be used to invoke the <code>close()</code> method and return any exceptions thrown in the process. This approach makes use of reflection which adds flexibility but also add performance costs. <strong>This is the slowest approach for closing an object</strong>.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-78802797358027533762009-08-10T08:15:00.007+02:002009-10-21T15:56:24.515+02:00Install Eclipse UI Form EditorDeveloping Swing (or any other GUI) forms can be cumbersome and time consuming especially if you're a newbie or have complex screens to build. Form editors such as <a href="http://www.netbeans.org/kb/trails/matisse.html" target="_blank"><strong>NetBeans Matisse</strong></a> or <a href="http://www.cloudgarden.com/jigloo/" target="_blank"><strong>Eclipse plugin Jigloo</strong></a> can help you speed up the development time by providing a simple drag and drop form building. In this article we’re not comparing the form builders and in no way I'm saying that the mentioned form builders are better than others.
<p>
This article shows you how to installed <a href="http://www.cloudgarden.com/jigloo/" target="_blank">CloudGarden's Jigloo</a> plugin for Eclipse Galileo 3.5. The contents can be used also as a guide on how to install and remove plugins from Eclipse. Note that different versions of Eclipse may use different dialogs and include different options.
<p>
It is assumed that the computer you’re installing the plugin is connected to the Internet and have access to the following URI: <a href="http://cloudgarden1.com/update-site" target="_blank">http://cloudgarden1.com/update-site</a>.
<p>
<h2>
Install Jigloo Plugin</h2>
Eclipse provides a framework for its plugins. This simplifies the installation and removal process of plugins such as Jigloo. Open Eclipse, if not already opened. To add a new plugin,<a href="" name="InstallNewSoftware"></a> open the <strong>Help</strong> menu and select the <strong>Install New Software...</strong> menu item.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJA0Ru_m483UP0XyjcPnQKikUS1BsuHTxWwoDFOr3jr_NdFTgOLbn6lun9tEaT07xnY9JmSaNK5fs-f1Ps4J6wkzlZx1AVLMDZxrVWRq0HeKaF-UUKpMPUHFsS-bKpFR_GskztiDxyZA/s1600-h/01+-+Install+New+Software.gif" imageanchor="1" target="_blank">
<img alt="Help -> Install New Software" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkJA0Ru_m483UP0XyjcPnQKikUS1BsuHTxWwoDFOr3jr_NdFTgOLbn6lun9tEaT07xnY9JmSaNK5fs-f1Ps4J6wkzlZx1AVLMDZxrVWRq0HeKaF-UUKpMPUHFsS-bKpFR_GskztiDxyZA/s320/01+-+Install+New+Software.gif" />
</a>
<p>
The Install dialog will open from where you can add and install new plugins. Click on the <strong>Add...</strong> button to add a new site from where the plugin is downloaded and installed as shown in the following screenshot.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiCOlOefCQkNmgxLci26JcQ29z-kXQeZgj2s81W1XRnbDGy5jj1aduGpz_eUJUwgmJ0AYOAkLLHKAZ38aecgGx4ik40hzIFv5J_Z1T76KoooZqQDhwUbblxgVknvkFT3NYp3a64PooqHQ/s1600-h/02+-+Add+Site.gif" imageanchor="1" target="_blank">
<img alt="Add Site" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiCOlOefCQkNmgxLci26JcQ29z-kXQeZgj2s81W1XRnbDGy5jj1aduGpz_eUJUwgmJ0AYOAkLLHKAZ38aecgGx4ik40hzIFv5J_Z1T76KoooZqQDhwUbblxgVknvkFT3NYp3a64PooqHQ/s320/02+-+Add+Site.gif" />
</a>
<p>
Add the site details in the small dialog, titled <em>Add Site</em>, displayed. Enter a friendly name (it can be anything you like) and the location from where the plugin will be downloaded and installed. The location for Jigloo is: <strong>http://cloudgarden1.com/update-site</strong>.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSuVWoK6TcYz7ezoDM_EuwL3zxWg4DcCviTHoOdabNScbfYjCGW6fawDWP-3Ow184HBFYppvcNfpiGa8bxbVPcyLRkSKqnZjUrg7mGo2sDfnS8IDQ5b1n4xunbx9UrOOSR5jGRfyyFpfI/s1600-h/03+-+Add+Site+Details.gif" imageanchor="1" target="_blank">
<img alt="Enter Site Details" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSuVWoK6TcYz7ezoDM_EuwL3zxWg4DcCviTHoOdabNScbfYjCGW6fawDWP-3Ow184HBFYppvcNfpiGa8bxbVPcyLRkSKqnZjUrg7mGo2sDfnS8IDQ5b1n4xunbx9UrOOSR5jGRfyyFpfI/s320/03+-+Add+Site+Details.gif" />
</a>
<p>
Click <strong>OK</strong> to continue. As shown in the following screenshot, the new site <u>may</u> not be listed in the work with dropdown list.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhASt7aOFwADdFAigk8SDejoVUl5sRXkS_YoiN4z4U67XOPZtF5AP52t28DT-JZm5A6Yqn3ccV5HbbcWBqtBDbJ90blaDF4ltDK5yp9K0UtPWt9yJAyfUjUE9wRW6sUNaEzjKxDevnUXPg/s1600-h/04+-+Work+With.gif" imageanchor="1" target="_blank">
<img alt="Work With dropdown list (without the Jigloo site)" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhASt7aOFwADdFAigk8SDejoVUl5sRXkS_YoiN4z4U67XOPZtF5AP52t28DT-JZm5A6Yqn3ccV5HbbcWBqtBDbJ90blaDF4ltDK5yp9K0UtPWt9yJAyfUjUE9wRW6sUNaEzjKxDevnUXPg/s320/04+-+Work+With.gif" />
</a>
<p>
In this case, close the dialog and reopen it from the menu <strong>Help -> Install New Software...</strong> as described earlier (click <a href="http://draft.blogger.com/post-edit.g?blogID=6929422799523574458&postID=7880279735802753376#InstallNewSoftware">here</a> for details) for Eclipse to refresh the sites list. The new site will be displayed in the work with dropdown list. Select the <em>Jigloo</em> site and click <strong>Next</strong> to continue.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbUfpWjrmizOk0O5wtGLWhSLWceHTKynZrjeaijSr9BveA5Jmvj8dp6FFcd1zut2_HLgf88zIZGhBAKHZY9cMzflkFU3iihPDnRmrWaBYw1FNWpmXUa6_qIKHFnM1USq19Sim4KGJB7k/s1600-h/05+-+Work+With.gif" imageanchor="1" target="_blank">
<img alt="Work With dropdown list (with the Jigloo site)" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbUfpWjrmizOk0O5wtGLWhSLWceHTKynZrjeaijSr9BveA5Jmvj8dp6FFcd1zut2_HLgf88zIZGhBAKHZY9cMzflkFU3iihPDnRmrWaBYw1FNWpmXUa6_qIKHFnM1USq19Sim4KGJB7k/s320/05+-+Work+With.gif" />
</a>
<p>
Eclipse will list all available plugins from the selected site. Select the <strong>Jigloo GUI Builder</strong> and then click <strong>Next ></strong> to continue.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVWxMi5xwYsiZZ_aptSpAld-PeMI90NmtqlM8_pb7BBy6-uSQRkqCKoYDkzeTDfcFAEmZbIMsjyDvI2fDZSyoB8Ukzvh7AFEK0aePCdaIjlygQgxfKi-MjLbOJwBW47yLQ2y_FPi19Cx0/s1600-h/06+-+Add+Jigloo.gif" imageanchor="1" target="_blank">
<img alt="Add Jigloo" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVWxMi5xwYsiZZ_aptSpAld-PeMI90NmtqlM8_pb7BBy6-uSQRkqCKoYDkzeTDfcFAEmZbIMsjyDvI2fDZSyoB8Ukzvh7AFEK0aePCdaIjlygQgxfKi-MjLbOJwBW47yLQ2y_FPi19Cx0/s320/06+-+Add+Jigloo.gif" />
</a>
<p>
Wait for Eclipse to calculate the requirements and dependencies. When ready, Eclipse will list the installation details. Click <strong>Next ></strong> to continue. Read the license agreement and only proceed if you accept it. Eclipse will download the required files and installed these when ready.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjegrK5vxhgMRE5XvFTZlJuvp93hxtwfRPOwI9cvAiGwvhEoPZszN6XiW0yfGLVzMmIv8Gnmr0SbMHnsZ-4pKlKY_BCrorjs26kEwtghUHGOwiaV-m38RiIhwETTswS3bUTX8ev0lthAuA/s1600-h/10+-+Wait+for+Eclipse+to+Download+and+Install.gif" imageanchor="1" target="_blank">
<img alt="Wait for Eclipse to Download and Install" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjegrK5vxhgMRE5XvFTZlJuvp93hxtwfRPOwI9cvAiGwvhEoPZszN6XiW0yfGLVzMmIv8Gnmr0SbMHnsZ-4pKlKY_BCrorjs26kEwtghUHGOwiaV-m38RiIhwETTswS3bUTX8ev0lthAuA/s320/10+-+Wait+for+Eclipse+to+Download+and+Install.gif" />
</a>
<p>
When ready, a dialog will be displayed suggesting restart of Eclipse. Click <strong>Yes</strong> to restart Eclipse. Wait for Eclipse to restart.
<p>
<h2>
Create a JFrame </h2>
The main focus of this article is to illustrate how to install and remove Eclipse plugin Jigloo. The following online tutorial: <a href="http://www.cloudgarden1.com/swing_tutorial/index.html" target="_blank">http://www.cloudgarden1.com/swing_tutorial/index.html</a> provides detailed examples of how to use this plugin to create Swing based forms.
<p>
To create a new <code>JFrame</code>, we first need to create a new project (unless you have one created already). Create a project or select an existing one. Then press <strong>Ctrl+N</strong> simultaneously to open the <em>New</em> dialog. Expand the <strong>GUI Forms</strong> node, then the <strong>Swing</strong> node and select the <strong>JFrame</strong> option as shown below.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi81Iz636wO4uXDud6pLYgiDcHorf2wKcFzAaLm4jj_KW5wSgqWOY7h6OdSjel-DDPnbrKVEwLCDYOYjS6xVYHNJD-jmiaPygc4CmgPXe7HoH48FAHFaMHyCwH_fzgFncXRQ25rfYh15kg/s1600-h/13+-+New+JFrame.gif" imageanchor="1" target="_blank">
<img alt="New JFrame" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi81Iz636wO4uXDud6pLYgiDcHorf2wKcFzAaLm4jj_KW5wSgqWOY7h6OdSjel-DDPnbrKVEwLCDYOYjS6xVYHNJD-jmiaPygc4CmgPXe7HoH48FAHFaMHyCwH_fzgFncXRQ25rfYh15kg/s320/13+-+New+JFrame.gif" />
</a>
<p>
If the form is greyed out (disabled) that means that you have not selected a project. Make sure you either select an existing project or create a new one before you proceed.
<p>
Provide a package name and a name for the <code>JFrame</code>. Note that names in Java must start with a letter, underscore or a dollar sign. Numbers can be included but not as the first letter. Press <strong>Finish</strong> to complete the process.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz6NWmha3FVPz4hC5pD_jIjkTevd7HBw9LSRlrmUWFJ7nYPPOiCJVu7_f6RrcySO4TWEivSKk3p-TyUa_PuovMyo1o9AtrXHBv6fcGiEu-kTI9_OdjregSjouZTxOAseHo-UvR-lYd1os/s1600-h/14+-+JFrame+name.gif" imageanchor="1" target="_blank">
<img alt="Package and Frame names" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz6NWmha3FVPz4hC5pD_jIjkTevd7HBw9LSRlrmUWFJ7nYPPOiCJVu7_f6RrcySO4TWEivSKk3p-TyUa_PuovMyo1o9AtrXHBv6fcGiEu-kTI9_OdjregSjouZTxOAseHo-UvR-lYd1os/s320/14+-+JFrame+name.gif" />
</a>
<p>
Eclipse will open the new frame for editing. Components can be added and removed graphically in a drag and drop manner. For more about this, please refer to the tutorial: <a href="http://www.cloudgarden1.com/swing_tutorial/index.html" target="_blank">http://www.cloudgarden1.com/swing_tutorial/index.html</a>
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzWNZiZFpMooPmA8ArI-2pY_-qmse2tcsfwLHH9Z4sRM14hYbuH2YsFPRN7SN3QuIMGmcWMzWhbCJ1WbTyeSyX7jlLy9WwYrYYeB8YwDahz77FzO6FV1KkoaLwmsUHpU5kfiwNDCtoIXs/s1600-h/15+-+New+JFrame.gif" imageanchor="1" target="_blank">
<img alt="Eclipse" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzWNZiZFpMooPmA8ArI-2pY_-qmse2tcsfwLHH9Z4sRM14hYbuH2YsFPRN7SN3QuIMGmcWMzWhbCJ1WbTyeSyX7jlLy9WwYrYYeB8YwDahz77FzO6FV1KkoaLwmsUHpU5kfiwNDCtoIXs/s320/15+-+New+JFrame.gif" />
</a>
<p>
<h2>
Uninstall the Plugin</h2>
To uninstall a plugin, open the <strong>Help</strong> menu and select <strong>About Eclipse</strong> menu item. The about dialog will be displayed.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0XzYReDmxD2u3l37AJuuI6KOyusq8nxI_0vTCmEnZIFibKbjDTUygg7U-7UtXFpw-htLTW030LafQP_G905aufvjB9WqP5p-kaynMd8GGUByox4sw0qVphUh8bmaLj5zekJEO5899MAg/s1600-h/16+-+Help+About.gif" imageanchor="1" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0XzYReDmxD2u3l37AJuuI6KOyusq8nxI_0vTCmEnZIFibKbjDTUygg7U-7UtXFpw-htLTW030LafQP_G905aufvjB9WqP5p-kaynMd8GGUByox4sw0qVphUh8bmaLj5zekJEO5899MAg/s320/16+-+Help+About.gif" /></a>
<p>
Click on the <strong>Installation Details</strong> button. The Eclipse Installation Details dialog will open. With the <strong>Installed Software</strong> tab selected, select the Jigloo plugin and click <strong>Uninstall…</strong>.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoeE3Dbrb3fY2g-v-RdNqen33fFapcsUci-kxs6CQ39HZj_A6rm7bVUfRN3jUhmXZ6giEdX6rFf9yt3JRAWsHKiE_fvLrhUFsY_JFWcYH98N5iJae47cgwOkAyugRDWM5lPKFzcYqa82s/s1600-h/18+-+Uninstall.gif" imageanchor="1" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoeE3Dbrb3fY2g-v-RdNqen33fFapcsUci-kxs6CQ39HZj_A6rm7bVUfRN3jUhmXZ6giEdX6rFf9yt3JRAWsHKiE_fvLrhUFsY_JFWcYH98N5iJae47cgwOkAyugRDWM5lPKFzcYqa82s/s320/18+-+Uninstall.gif" alt="Uninstall"/>
</a>
<p>
Wait for Eclipse to calculate the requirements and dependencies. Click <strong>Finish</strong> on the <em>Uninstall</em> dialog to confirm the uninstallation. Wait for Eclipse to finish the uninstallation and click <strong>Yes</strong> when prompting to restart.<p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-68242105866318521802009-08-06T09:36:00.009+02:002009-10-21T16:03:26.792+02:00Relations made simpler with JPAOne of the differences between rational databases and object oriented programming (OOP) is the way data elements are represented. To handle this difference, additional code (sometimes referred to as data access objects) that translates from records to objects and vice-versa has to be produced and maintained in order for an application to communicate with the database.
<p>
This article illustrates how <a href="http://jcp.org/en/jsr/detail?id=220" target="_target">JSR-220</a>, or as better known Java Persistence API (JPA), can help reducing the amount of code and effort required to synchronise both worlds.
<p>
In order to complete the examples illustrated here, the following jar files have to be in the classpath: <code>toplink-essentials.jar</code>; <code>toplink-essentials-agent.jar</code>; and <code>derby.jar</code>. These can be downloaded from: <a href="http://www.oracle.com/technology/products/ias/toplink/JPA/index.html" target="_blank">Oracle Toplink JPA</a> and <a href="http://developers.sun.com/javadb/" target="_blank">JavaDB</a> respectively. These examples can be executed on databases other than the JavaDB (formerly known as Derby). To execute them on other databases you need the appropriate JDBC jar file.
<p>
A simple address book application (with no graphical user interface) will be used to illustrate the examples discussed here. The application data is made from four classes: <code>Address</code>; <code>Person</code>; <code>Contact</code>; and <code>Group</code>. The following figure illustrates the relations between these classes.
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ6tQhyphenhyphen1jrqZET36Ti_wd97NAmkWL6Q7HxVxLkdfgB9mEV-uo7oqNbZeOnBRsKOMMTrQYYZhmYAKAJjy_Ymo2SNSYgUyAacED74m-PZCwBt1dbgM4zh49joeMUBWpZ_CQtzwBnb10G2SA/s1600-h/Objects.png" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ6tQhyphenhyphen1jrqZET36Ti_wd97NAmkWL6Q7HxVxLkdfgB9mEV-uo7oqNbZeOnBRsKOMMTrQYYZhmYAKAJjy_Ymo2SNSYgUyAacED74m-PZCwBt1dbgM4zh49joeMUBWpZ_CQtzwBnb10G2SA/s320/Objects.png" /></a>
<br />
<i>Figure 1. Relation between Classes</i>
<p>
The counter tables are illustrated in the following figure
<p>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtDs0Dx1vOSOg1Q0NRVqCY8CdMzOtWmENIOL9XG5_UhP7dt8eNJJc_6ndO0taEVQN6SULpfeMfaEnqR__fdbzxABPeh_UmTNUnvVmrHNZRwlozZA9AMnsVvdmvdf8AOqwfjAusaNjNNoQ/s1600-h/Database.png" target="_blank"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtDs0Dx1vOSOg1Q0NRVqCY8CdMzOtWmENIOL9XG5_UhP7dt8eNJJc_6ndO0taEVQN6SULpfeMfaEnqR__fdbzxABPeh_UmTNUnvVmrHNZRwlozZA9AMnsVvdmvdf8AOqwfjAusaNjNNoQ/s320/Database.png" /></a>
<br />
<i>Figure 2. Relation between Classes</i>
<p>
The above relations are summarised below
<ul>
<li>One or more persons can be living in the same address</li>
<li>Persons can be grouped together</li>
<li>A person can be in more than one group</li>
<li>A person has a set of contacts (numbers, emails)</li>
<li>A person has a main contact</li>
<li>A contact cannot be shared between two persons</li>
</ul>
<p>
Note that even in a simple application like this, the number of classes and tables required to represent the data in the respective format are different. This adds to the complexity required to translate between both worlds.
<h3>Setting up the Database</h3>
<p>
The <code>SetupDatabase</code> class, listed below, can be used to setup the database referred to from this article. It first drops all foreign keys (using the <code>alter</code> command) and tables and then re-creates everything. The altering and dropping processes will produce errors when executed for the first time as the tables in question are not available. Finally it populates them with some default data. Run the <code>SetupDatabase</code> class twice to make sure that everything is in place. The second time round should produce no errors. Note that this class requires the jar file <code>derby.jar</code> (or the libraries of your database) in the classpath.
<p>
<pre><code>package x2x;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
public class SetupDatabase {
private static String[] buildDatabase = {
"ALTER TABLE CONTACTS DROP CONSTRAINT CONTACT_PERSON_1",
"ALTER TABLE PERSONS DROP CONSTRAINT PERSON_ADDRESS_1",
"ALTER TABLE PERSONS DROP CONSTRAINT PERSON_CONTACT_1",
"ALTER TABLE PERSONS_GROUPS DROP CONSTRAINT PERSON_GROUP_1",
"ALTER TABLE PERSONS_GROUPS DROP CONSTRAINT PERSON_GROUP_2",
"DROP TABLE ADDRESSES",
"DROP TABLE CONTACTS",
"DROP TABLE GROUPS",
"DROP TABLE PERSONS_GROUPS",
"DROP TABLE PERSONS",
"CREATE TABLE ADDRESSES (ADDRESS_ID INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1), ADDRESS VARCHAR(255) NOT NULL)",
"CREATE TABLE CONTACTS (CONTACT_ID INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1), CONTACT_TYPE VARCHAR(255) NOT NULL, CONTACT_VALUE VARCHAR(255) NOT NULL, PERSON_ID INTEGER NOT NULL)",
"CREATE TABLE GROUPS (GROUP_ID INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1), GROUP_NAME VARCHAR(255) NOT NULL)",
"CREATE TABLE PERSONS (PERSON_ID INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1), LAST_NAME VARCHAR(255) NOT NULL, FIRST_NAME VARCHAR(255) NOT NULL, ADDRESS_ID INTEGER NOT NULL, MAIN_CONTACT_ID INTEGER NOT NULL)",
"CREATE TABLE PERSONS_GROUPS (GROUP_ID INTEGER NOT NULL, PERSON_ID INTEGER NOT NULL, PRIMARY KEY (GROUP_ID, PERSON_ID))",
"INSERT INTO ADDRESSES (ADDRESS) VALUES ('123, Somewhere road, Some Place')",
"INSERT INTO ADDRESSES (ADDRESS) VALUES ('456, Anywhere road, Another Place')",
"INSERT INTO ADDRESSES (ADDRESS) VALUES ('789, Around the corner road, Near By Place')",
"INSERT INTO ADDRESSES (ADDRESS) VALUES ('012, Up the Hill, Not far away Place')",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Phone (Work between 7 and 15)', '00112233', 1)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Mobile (Work)', '99887766', 2)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Fax (Work)', '23452345', 2)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Email (Work)', 'peterwhite@somecompany.com', 1)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Email (Personal)', 'marybrown@somefreemail.com', 4)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Mobile (Personal)', '67678989', 5)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Phone (Home)', '78784545', 3)",
"INSERT INTO CONTACTS (CONTACT_TYPE, CONTACT_VALUE, PERSON_ID) VALUES ('Phone (Home)', '45453232', 2)",
"INSERT INTO PERSONS (FIRST_NAME, LAST_NAME, ADDRESS_ID, MAIN_CONTACT_ID) VALUES ('Peter', 'White', 1, 4)",
"INSERT INTO PERSONS (FIRST_NAME, LAST_NAME, ADDRESS_ID, MAIN_CONTACT_ID) VALUES ('John', 'Smith', 2, 2)",
"INSERT INTO PERSONS (FIRST_NAME, LAST_NAME, ADDRESS_ID, MAIN_CONTACT_ID) VALUES ('Jane', 'Smith', 2, 7)",
"INSERT INTO PERSONS (FIRST_NAME, LAST_NAME, ADDRESS_ID, MAIN_CONTACT_ID) VALUES ('Mary', 'Brown', 3, 5)",
"INSERT INTO PERSONS (FIRST_NAME, LAST_NAME, ADDRESS_ID, MAIN_CONTACT_ID) VALUES ('Jack', 'Black', 4, 6)",
"INSERT INTO GROUPS (GROUP_NAME) VALUES ('Family')",
"INSERT INTO GROUPS (GROUP_NAME) VALUES ('Colleagues')",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (1, 1)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (1, 2)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (1, 3)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (2, 1)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (2, 2)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (2, 4)",
"INSERT INTO PERSONS_GROUPS (GROUP_ID, PERSON_ID) VALUES (2, 5)",
"ALTER TABLE CONTACTS ADD CONSTRAINT CONTACT_PERSON_1 FOREIGN KEY (PERSON_ID) REFERENCES PERSONS (PERSON_ID)",
"ALTER TABLE PERSONS ADD CONSTRAINT PERSON_ADDRESS_1 FOREIGN KEY (ADDRESS_ID) REFERENCES ADDRESSES (ADDRESS_ID)",
"ALTER TABLE PERSONS ADD CONSTRAINT PERSON_CONTACT_1 FOREIGN KEY (MAIN_CONTACT_ID) REFERENCES CONTACTS (CONTACT_ID)",
"ALTER TABLE PERSONS_GROUPS ADD CONSTRAINT PERSON_GROUP_1 FOREIGN KEY (PERSON_ID) REFERENCES PERSONS (PERSON_ID)",
"ALTER TABLE PERSONS_GROUPS ADD CONSTRAINT PERSON_GROUP_2 FOREIGN KEY (GROUP_ID) REFERENCES GROUPS (GROUP_ID)", };
public static void main(String[] args) {
Connection connection = null;
try {
String driver = "org.apache.derby.jdbc.EmbeddedDriver";
try {
System.out.print("Loading the appropriate driver...");
Class.forName(driver).newInstance();
System.out.println("Done");
} catch (ClassNotFoundException e) {
System.err.println("Unable to load the JDBC driver " + driver);
System.err.println("Please check your CLASSPATH.");
e.printStackTrace();
System.exit(-1);
} catch (InstantiationException e) {
System.err.println("Unable to instantiate the JDBC driver "
+ driver);
e.printStackTrace();
System.exit(-1);
} catch (IllegalAccessException e) {
System.err.println("Not allowed to access the JDBC driver "
+ driver);
e.printStackTrace();
System.exit(-1);
}
Properties props = new Properties();
props.put("user", "x2x");
props.put("password", "x2x");
String dbName = "x2x_db";
System.out.print("Connecting with the x2x database...");
connection = DriverManager.getConnection("jdbc:derby:" + dbName
+ ";create=true", props);
connection.setAutoCommit(false);
System.out.println("Done");
System.out.println("Executing the drop, create and insert queries");
for (String sql : buildDatabase) {
try {
System.out.print("Executing '" + sql + "' ");
connection.createStatement().execute(sql);
connection.commit();
System.out.println("Done");
} catch (Throwable t) {
connection.rollback();
System.out.println("Failed");
t.printStackTrace();
}
}
System.out.println("Done");
System.out.println("Finished");
} catch (Exception e) {
System.out.println("Failed");
e.printStackTrace();
} finally {
if(connection != null){
try {
connection.close();
}catch(Throwable t){}
}
}
}
}</code></pre>
<h3>Java Persistence API (JPA)</h3>
<p>
For someone who's new to this field, the persistence API may be somewhat daunting, but one should not judge a book by its cover. The persistence API facilitates programming by reducing it. Before its introduction, a programmer had to manage the connection, and interact with the database him/herself. Now, with the new persistence API, all this code is intelligently incorporated within the API. With the help of annotations, the persistence API knows how to handle the class at hand and synchronise it with the database side seamlessly for the developer using it. We said enough already. Let's start working.
<h3>Entity</h3>
<p>
The <code>Address</code> class is used to represent an address in Java while the <code>ADDRESSES</code> table is used to save the data within the database. How will the persistence API synchronise these two?
<p>
For a class to be used with the persistence API, it must include the <code>@Entity</code> annotation. This means that the class will be persisted with the database using the JPA. The <code>@Entity</code> annotation alone is not enough to do the job as it's illustrated in the following listing. Note that all our examples are saved under the same package called <code>x2x</code>.
<p>
<pre><code>package x2x;
import javax.persistence.*;
@Entity
@Table(name = "ADDRESSES")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ADDRESS_ID")
private long id;
@Column(name = "ADDRESS", nullable = false)
private String address;
//...
}</code></pre>
<p>
The above listing includes a total of five annotations. The <code>@Table</code> annotation is used to provide information about the table this class or better entity is to be synchronised with. By default, the class name is taken as the table name, but this can be differently set as required. All entity classes must have a primary key, which is marked with the <code>@Id</code> annotation. The address id, in this case, is also automatically generated by the database. Another annotation called <code>@GeneratedValue</code> is used to indicate that the value of this field is automatically generated by the database. By default the persistence API will use the field's name as the column name. When these are different, the <code>@Column</code> annotation has to be used to set the appropriate column name.
<h3>Relationships</h3>
<p>
Classes are logically related to each other through the use of fields. For example "<em>a person has one address while one address can be used by more than one person</em>" is represented by a reference of the <code>Address</code> class in the <code>Person</code> class as shown in bold in the following listing.
<p><pre><code>//...
public class Person {
<strong>private Address address;</strong>
//...</code></pre>
<p>
The persistence API provides a set of annotations which marks the relation between entities. There are four types of relations:
<ul>
<li>One-to-One</li>
<li>One-to-Many</li>
<li>Many-to-One</li>
<li>Many-to-Many</li>
</ul>
<p>
Each of these is discussed in detail below.
<h3>One-to-One</h3>
<p>
A person object has many contacts, but it has only one main contact. The relation between the main contact and person is one-to-one. The following listing illustrates a fragment from the <code>Person</code> class capturing this relation. Note that in this example, the relation between these two is unidirectional. The <code>Contact</code> class is not aware of this relation.
<p>
<pre><code>//...
public class Person {
<strong>
@OneToOne(optional = false)
@JoinColumn(name = "MAIN_CONTACT_ID",
referencedColumnName = "CONTACT_ID")
private Contact mainContact;
</strong>
//...</code></pre>
<p>
Before we can understand how the relation between the entities works, let's recall the database relation between these two tables: The foreign key <code>MAIN_CONTACT_ID</code> in the <code>PERSONS</code> table is pointing to the primary key <code>CONTACT_ID</code> in the <code>CONTACTS</code> table. The <code>@OneToOne</code> annotation is very straightforward. It sets the relation between the two entities as one-to-one. The <code>optional</code> attribute sets the relation as obligatory. The other annotation, <code>@JoinColumn</code>, is very simple too. The <code>name</code> annotation attribute points to the foreign key while the <code>referencedColumnName</code> points to the primary key in the reference table (<code>CONTACTS</code>).
<h3>One-to-Many</h3>
<p>
A person can have many contacts. Thus there are two relations between the same two entities. The first one was discussed before. The second relation between these two is one-to-many. One person can have many contacts. A different fragment from the <code>Person</code> class is illustrated below. What's different from the previous example is that this relation is bidirectional.
<p>
<pre><code>//...
public class Person {
<strong>
@OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
private List<Contact> contacts;
</strong>
//...</code></pre>
<p>
As many of you would have predicted, the annotation which represents the one-to-many relation is called <code>@OneToMany</code>. Since this relation is bidirectional, the attribute <code>mappedBy</code> must provide the field's name that owns the relation in the other class. Note that this value is case-sensitive. The <code>cascade</code> attribute is an optional attribute defaulted to none. It can be set to one of the <code>javax.persistence.CascadeType</code> enum values: <code>ALL</code>; <code>MERGE</code>; <code>PERSIST</code>; <code>REFRESH</code>; <code>REMOVE</code>. This attribute is used by the persistence API to control what actions to cascade to the target entity. In our example all actions are propagated to the contacts instances related to this one.
<h3>Many-to-One</h3>
<p>
When the above is viewed from the other end we have: many contacts belong to one person. The relation between contacts and person is many-to-one.
<p>
<pre><code>//...
public class Contact {
<strong>
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(nullable = false, name = "PERSON_ID")
private Person person;
</strong>
//...</code></pre>
<p>
The annotation <code>@ManyToOne</code> set the relation between the two classes through the following field: <code>person</code>. The field's name must match the value given to the <code>mappedBy</code> attribute in the <code>@OneToMany</code> in the <code>Person</code> class.
<p>
The annotation <code>@JoinColumn</code> can be seen as the representation of a foreign-key-column which connects the <code>CONTACTS</code> table with the <code>PERSONS</code> table.
<h3>Many-to-Many</h3>
<p>
A person may belong to many groups and a group can contain as many persons as required. The relation between the group and person is said to be many-to-many.
<p>
In all the relations discussed so far there was a table for class entity and the same tables used matched the classes involved. The common way for representing the many-to-many relation within a database is to use three tables: one for persons, one for groups and one to map the persons and groups together. In OOP, only two classes are required, the <code>Person</code> class and the <code>Group</code> class. Both classes can in turn contact a list of the other.
<p>
The persistence API provides several annotations to ease the linking process as shown in <strong>bold</strong> the following <code>Group</code> class listing.
<p>
<pre><code>//...
public class Group {
<strong>
@ManyToMany
@JoinTable(name = "PERSONS_GROUPS")
private List<Person> contacts;
</strong>
//...
}</code></pre>
<p>
The annotation <code>@ManyToMany</code> is used to mark the many-to-many relation between this class (<code>Group</code>) and the field's content type class (<code>Person</code>), referred to as the <em>inverse class</em>. The field must be of type <code>Set</code>, <code>List</code>, <code>Map</code> or <code>Collection</code> (or any subclasses) as only these types are supported. The program will compile if other types are used but will produce a runtime exception.
<p>
The persistence API requires more information to link these two tables together. The <code>@JoinTable</code> annotation is used to provide information about the third table, the one that maps the person and group records. The <code>@JoinTable</code> annotation has six parameters, of which only one was used above. Two other parameters which are commonly used are the <code>inverseJoinColumns</code> and the <code>joinColumns</code>. The <code>joinColumns</code> represents the fields used in this entity (<code>Group</code>) to map to the other entity (<code>Person</code>), while the <code>inverseJoinColumns</code> represents the fields used by the other entity (<code>Person</code>) to map with this one (<code>Group</code>).
<p>
Together with the <code>@JoinTable</code>, the <code>@JoinColumn</code> annotation can be used to label the respective columns. These were not included in the above listing as the persistence API default values happen to match the database column names. The above listing can be changed as shown in bold in the following listing to also point to the respective column.
<p>
<pre><code>@ManyToMany
@JoinTable(name = "PERSONS_GROUPS"<strong>,
joinColumns = { @JoinColumn(name = "GROUP_ID") },
inverseJoinColumns = { @JoinColumn(name = "PERSON_ID") }
</strong>)
private List<Person> contacts;
</code></pre>
<h3>The Persistence.xml file</h3>
The persistence API requires one xml file called <i>persistence.xml</i>, saved within the <i>META-INF</i> folder. This xml files includes the list of classes which will be managed by the persistence API together with database connection url, username and password and other parameters. The embedded version of the JavaDB is used in this article, thus the transaction type has to be set to resource local and the embedded version of the driver is used instead.
<p>
The database name and the persistence unit name do not necessary have to have the same name, but it's a good practice to use at least similar ones. Since the database is already set up, the <code>toplink.ddl-generation</code> is set to <code>none</code>. The <i>persistence.xml</i> is illustrated below.
<p>
<pre><code><?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="x2x_db" transaction-type="RESOURCE_LOCAL">
<provider>
oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
</provider>
<class>x2x.Address</class>
<class>x2x.Contact</class>
<class>x2x.Group</class>
<class>x2x.Person</class>
<properties>
<property name="toplink.jdbc.user"
value="x2x" />
<property name="toplink.jdbc.password"
value="x2x" />
<property name="toplink.jdbc.url"
value="jdbc:derby:x2x_db" />
<property name="toplink.jdbc.driver"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="toplink.ddl-generation"
value="none" />
</properties>
</persistence-unit>
</persistence></code></pre>
<h3>Entity Manager</h3>
<p>
Now that we have everything set up, we can start querying the database using the <code>javax.persistence.EntityManager</code>. The first thing we need to create an instance of the entity manager using a factory such as <code>javax.persistence.EntityManagerFactory</code> as shown in the following listing.
<p>
<pre><code>EntityManagerFactory factory =
Persistence.createEntityManagerFactory("x2x_db");
EntityManager manager = factory.createEntityManager();</code></pre>
<p>
The persistence unit name must be provided to the factory to load the proper information from the <i>persistence.xml</i> file. With our entity manager created we can do anything with it without having to worry about complex data access objects. Selecting all persons and put them in a list can be achieved in two lines of code as shown below.
<p>
<pre><code>Query selectAllQuery =
manager.createQuery("SELECT p FROM Person p");
List<Person> allPersons = selectAllQuery.getResultList();
for (Person p : allPersons) {
//...
}</code></pre>
<p>
It's good to understand that even though the parameter passed to the create query method above is very similar to SQL, it's not. Note that the persons table is called <code>PERSONS</code> and not <code>Person</code>. So how did it work? The provided name is the name of the entity we're querying.
<p>
This query not only loaded the persons' data from the <code>PERSONS</code> table but also loaded the address, groups and contacts information from the same database. All this was done without additional code. We can do more than simply loading data. A new address, for example, can be created and inserted without having to wonder about the SQL code behind it as illustrated below.
<p>
<pre><code>Address newAddress = new Address();
newAddress.setAddress("The new Place, Persistence Ave, Java");
manager.getTransaction().begin();
manager.persist(newAddress);
manager.getTransaction().commit();
System.out.println("New Address id: " + newAddress.getId());</code></pre>
<p>
The same address can be updated and deleted in a similar fashion.
<p>
<pre><code>// Update
newAddress.setAddress("The other Place, Persistence Ave, Java");
manager.getTransaction().begin();
manager.persist(newAddress);
manager.getTransaction().commit();
// Delete
manager.getTransaction().begin();
manager.remove(newAddress);
manager.getTransaction().commit();</code></pre>
<h3>Conclusion</h3>
JPA like other new APIs introduced new features that improve the productivity and minimise the maintenance costs. The traditional data access object classes can be replaced by the use of annotation. This article merely covers the relational aspect of this vast API. Further reading about the class <code>Query</code>, and annotations <code>@NamedQuery</code> and <code>@NamedQueries</code> would prove very useful especially when it comes to retrieving information from the database.
</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-16912402256791181012009-08-03T12:29:00.004+02:002009-10-04T07:48:23.965+02:00JSP compile error in Eclipse<p>One of the most common problem when using Eclipse to develop web pages (JSPs) is the default <em>JRE</em> settings. By default Eclipse sets the default system JRE as its <em>JRE</em>. This sounds all good, but JSPs require a JDK instead of a JRE - this sounds weird. This article shows you how to solve this very small issue by changing the Eclipse Installed <em>JRE</em>s settings.
</p><p>To avoid confusion in this article, I'm going to use italics to refer to the <em>JRE</em> Eclipse name (nothing to do with Java unless otherwise told), that is, the name Eclipse uses and has nothing to do with the Java JRE. Also, JDK means Java Development Kit and JRE (not in italics) means Java Runtime Environment.
</p><h2>Set Eclipse Installed <em>JRE</em>s</h2>
<h3>Check your JDK</h3>
<p>Before you proceed, make sure that you have a JDK installed. You can do so by executing the following command on your command prompt.
</p><pre><code>
C:\>javac -version
javac 1.6.0_02
</code></pre>
<p>In my case I have a copy of Java 1.6 update 2 installed. Your version may be different from the one displayed above, depending on the version you have installed. As long as the above command returns something (similar to the above) it's OK. If the above returns an <strong>error</strong> similar to following, it means that either you don't have a JDK installed or the JDK bin directory is not in your system path.
</p><pre><code>
C:\>javac -version
'javac' is not recognized as an internal or external command, operable program or batch file.
</code></pre>
<p>In this case, browse to the folder where you <em>think</em> Java is installed (on Windows this is usually: <code>C:\Program Files\Java</code> or <code>C:\Program Files (86)\Java</code> in case of 64 bit Windows version) and check it yourself. Alternatively, visit Sun's website (<a href="http://java.sun.com/" target="_blank">http://java.sun.com</a>) and download and install the JDK from there. <u>Make sure to download the <strong>JDK</strong> and not the JRE</u>.
</p><h3>Set the Installed <em>JRE</em>s</h3>
<p>Open Eclipse if it is not already running. Open the <strong>Preferences</strong> from the <strong>Windows</strong> menu as shown below.
</p><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-i1hbruKInv4nox0rvuYWIoiEgYMz9MdMnejZ1v_NBNUBaZrk67BbNPXAMOcdz_UfUCI2alMB2scbCLkZQxW0qJjZzo-_DYAYSBeOZR08r1wIZKcRbzN9xZWuRnoEUtwprOqhfqVxDe4/s1600-h/Eclipse-Image1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-i1hbruKInv4nox0rvuYWIoiEgYMz9MdMnejZ1v_NBNUBaZrk67BbNPXAMOcdz_UfUCI2alMB2scbCLkZQxW0qJjZzo-_DYAYSBeOZR08r1wIZKcRbzN9xZWuRnoEUtwprOqhfqVxDe4/s320/Eclipse-Image1.gif" /></a></div>
<p>Expand the <strong>Java</strong> node and select the <strong>Installed <em>JRE</em>s</strong> sub-node.
</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2_kLDMw6YRrsU6gFaNoDCSTQJLqXpgNGzyaB7FBf44bwh8l-ToQG71BiIcPmOmz2-rKo695FGUWTaTwYVdPJ0O0SJJapiNy31ePr8YkqM7mkMnHxbsRzpBX_5nGfKnB_RD3PBnSLbHvI/s1600-h/Eclipse+Image+2.gif">
<img style="cursor:pointer; cursor:hand;width: 320px; height: 254px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2_kLDMw6YRrsU6gFaNoDCSTQJLqXpgNGzyaB7FBf44bwh8l-ToQG71BiIcPmOmz2-rKo695FGUWTaTwYVdPJ0O0SJJapiNy31ePr8YkqM7mkMnHxbsRzpBX_5nGfKnB_RD3PBnSLbHvI/s320/Eclipse+Image+2.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5376005872383493202" /></a>
</div>
<p>JSPs require that Eclipse default Installed <em>JRE</em> is actually pointing to a JDK and not a JRE. Thus if your default Installed <em>JRE</em> is pointing to a JRE instead, you need to replace it with your JDK. This may sound weird since the dialog is asking you for a <em>JRE</em>.
</p><p>The process is very simple:
</p><ol>
<li>First add a new <em>JRE</em> by clicking the <strong>Add</strong> button.
You cannot just remove your only <em>JRE</em> without first adding another <em>JRE</em>.
</li>
<li>Select <strong>Standard VM</strong> option from the list and click <strong>Next</strong>.
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuOWAbyxu1XYzSUUMZ3LowNsi12B2CYhF62aqngLtxwz4MynrFrF_a1KfqwMaYgzZtGdC7Fvq4Uz8PYR4dT0YD5U54SnlrOWqz-LZ7ePmdSOV1ykT5e3LRq1xSqmKb4DkbevPhkoYFVxQ/s1600-h/Eclipse-Image3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuOWAbyxu1XYzSUUMZ3LowNsi12B2CYhF62aqngLtxwz4MynrFrF_a1KfqwMaYgzZtGdC7Fvq4Uz8PYR4dT0YD5U54SnlrOWqz-LZ7ePmdSOV1ykT5e3LRq1xSqmKb4DkbevPhkoYFVxQ/s320/Eclipse-Image3.gif" /></a></div>
</li>
<li>Click the <strong>Directory</strong> button or manually enter the path to your (latest or which one you require) JDK directory on your local machine.
Note that the JDK directory is the folder where JDK was installed. See the next screen shot.</li>
<li>Wait for Eclipse to verify your entry and list the libraries.
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6igu0HkPnVvKQF2Tub6t3QaJrGkxO2U6KBfhrMLoX-6tT1hqi5YBoAbR2-TIluoolC8_UwOlZnvjE3JoT8ftD7lcmbK12FAk3TcjeGf6nb2WNNqX4hve7r1pRdjviJ9hg2peImKJuR-s/s1600-h/Eclipse-Image4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6igu0HkPnVvKQF2Tub6t3QaJrGkxO2U6KBfhrMLoX-6tT1hqi5YBoAbR2-TIluoolC8_UwOlZnvjE3JoT8ftD7lcmbK12FAk3TcjeGf6nb2WNNqX4hve7r1pRdjviJ9hg2peImKJuR-s/s320/Eclipse-Image4.gif" /></a></div>
</li>
<li>Optionally, you can change the <strong><em>JRE</em> name</strong> to a name of your liking.</li>
<li>Click <strong>Finish</strong> to complete the process.</li>
<li>Set the new <em>JRE</em> (that is, the JDK just added) as your default <em>JRE</em> by checking the checkbox near the <em>JRE</em> friendly name (usually the first column).</li>
<li>Optionally, you can remove the other <em>JRE</em> by first selecting it (not setting it as your default) and pressing the <strong>Remove</strong> button.</li>
<li>Click <strong>OK</strong> to close the preferences dialog.</li>
</ol>
<p>With the default <em>JRE</em> set to a JDK, test your JSPs and confirm that the errors are now gone and the JSPs are now compiling.</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com30tag:blogger.com,1999:blog-6929422799523574458.post-21622672107619381242009-06-30T10:23:00.001+02:002012-12-29T18:30:01.795+01:00Practical Example of GSON<strong>Please note that this page has moved to: <a href="http://www.javacreed.com/simple-gson-example/">http://www.javacreed.com/simple-gson-example/</a>.<br />
</strong><br />
<p>GSON is a Java API, developed by Google, used to convert between Java objects and JSON objects. This article discusses and provides examples about this API and how it can be used. More information about this API can be found at: <a href="http://sites.google.com/site/gson/" target="_blank">http://sites.google.com/site/gson/</a>.<br />
<p>This is the first from three articles about GSON. No GSON or JSON experience is required as this article acts as a primer for the other two articles. The <a href="http://albertattard.blogspot.com/2012/06/practical-example-of-gson-part-2.html">second article</a> provides more examples about the use of GSON deserializer (from JSON to Java) and the <a href="" title="coming soon">third</a> and final article provides more examples about the GSON serializer (from Java to JSON). All code for all three articles is available at: <a href="http://code.google.com/p/gson-practical-examples/source/checkout">http://code.google.com/p/gson-practical-examples/source/checkout</a>.<br />
<h2>Download and Install</h2>Before you can do any work with this API, you need to download the library (<em>jar file</em>) and include it in the classpath. The library, together with the source and JavaDocs, can be downloaded from: <a href="http://code.google.com/p/google-gson/downloads/list" target="_blank">http://code.google.com/p/google-gson/downloads/list</a>. Once downloaded, add the <code>gson-<em><version></em>.jar</code> to the classpath. For those readers who prefer to use <a href="http://maven.apache.org/" target="_blank">maven</a> to manage the dependencies (JAR files), add the following dependency to the <code>pom.xml</code>.<br />
<pre><code>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.1</version>
</dependency>
</code>
</pre>Change the <code><version>2.2.1</version></code> as required. All code examples shown in this article use the version listed above. A copy of the <code>pom.xml</code> file can be found <a href="http://code.google.com/p/gson-practical-examples/source/browse/trunk/pom.xml" target="_blank">here</a>.<br />
<p>If this library is to be used in a web application, make sure to have a copy saved under the <code>WEB-INF/lib</code> folder. Alternatively, the library can be added to the application server and made available to the web application. <br />
<h2>A Simple Example</h2>The GSON API provides a stateless class, <a href="http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/Gson.html" target="_target"><code>Gson</code></a>, that handles the conversions between Java and JSON objects. An instance of this class can be created by invoking the default constructor or as shown in the simple example below, using the <a href="http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/GsonBuilder.html" target="_target"><code>GsonBuilder</code></a> class. The <code>GsonBuilder</code> class provides customisation and allows the developer to instantiate <code>Gson</code> as required. <br />
<pre><code>
package com.albertattard.examples.gson.part1_1;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class SimpleExample1 {
public static void main(String[] args) {
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", System.out);
gson.toJson(123, System.out);
}
}
</code></pre>In the above example, we've created an instance of <code>Gson</code> and converted the Java <code>String</code> and <code>int</code> to JSON objects. The above code produces the following as its output to the command prompt: <br />
<pre><code>"Hello"123</code></pre>It's not rocket science, but it's a start. Note that the output of the above is all going to the command prompt. The <code>toJason()</code> method takes two parameters, the Java object to be converted to JSON and an instance of <a href="http://java.sun.com/javase/7/docs/api/java/lang/Appendable.html" target="_blank"><code>Appendable</code></a>. We can easily change the out to a file or network stream. <br />
<pre><code>
package com.albertattard.examples.gson.part1_1;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class SimpleExample2 {
public static void main(String[] args) <strong style="color:red">throws IOException</strong> {
<strong style="color:red">Writer writer = new FileWriter("Output.json");</strong>
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", <strong style="color:red">writer</strong>);
gson.toJson(123, <strong style="color:red">writer</strong>);
<strong style="color:red">writer.close();</strong>
}
}
</code></pre><strong>Why is the variable declared as a <code>Writer</code> when the actual type is <code>FileWriter</code>?</strong> <br />
It is a good practice to have your variables as generic as possible. In the above example, we're only using methods defined by the <code>Appendable</code> and <code>Writer</code> interfaces. Having the variable type more specific than required will make the code less portable and harder to maintain as we'll see in the following example.<br />
<p>Note that in the above example we are not handling the steams (<code>Writer</code>) properly. Ideally the resources are closed within the <code>finally</code> block or used within the try-with-resources as shown below. We've ignored this to keep the code as simple as possible.<br />
<pre><code>
public static void main(String[] args) throws IOException {
<strong style="color:red">try (Writer writer = new FileWriter("Output.json")) {</strong>
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", writer);
gson.toJson(123, writer);
<strong style="color:red">}</strong>
}
</code>
</pre><p>The above code produces the file: <code>Output.json</code> with the JSON objects. Note that here we used the character streams and not the byte streams. We cannot use the byte streams as the <code>toJson()</code> method is expecting an <code>Appendable</code> instance and the byte streams are not descendants from the <code>Appendable</code> interface. The <code>Appendable</code> interface works with characters and not bytes. Java provides the <a href="http://java.sun.com/javase/7/docs/api/java/io/InputStreamReader.html" target="_blank"><code>InputStreamReader</code></a> and the <a href="http://java.sun.com/javase/7/docs/api/java/io/OutputStreamWriter.html" target="_blank"><code>OutputStreamWriter</code></a> classes that convert byte streams into character streams as illustrated in the following example. <br />
<pre><code>
package com.albertattard.examples.gson.part1_1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class SimpleExample3 {
public static void main(String[] args) throws IOException {
Writer writer = <strong style="color:red">new OutputStreamWriter(
new FileOutputStream("Output.json"));</strong>
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", writer);
gson.toJson(123, writer);
writer.close();
}
}
</code></pre>As you can see, we only needed to change the instantiation part. The rest (expect for the imports) of the code is unchanged. <br />
<h2>Consuming JSON objects</h2>Let's say that we need to consume JSON objects and load them as Java objects. Assume that a web server will produce the following JSON when queried: <br />
<pre><code>
{
NAME:"Albert Attard",
P_LANGUAGE:"Java",
LOCATION:"Malta"
}
</code></pre>This JSON object contains three fields with their respective values. Let's say that we need to consume the JSON object and create a Java object that represents this data. To make this example more interesting, let assume that we're only interested from the name and the location fields. <br />
<p>First we need to create a Java class with the fields that we want to represent (name and location). Let's call the class <code>Person1</code>. <strong>The name of this class is irrelevant, but the name of the fields is not</strong>. The field names must match (including the case) with the names in JSON. Also, the class must include a default constructor. As shown below, the fields name and location are in uppercase as found in JSON. The JSON field <code>P_LANGUAGE</code> is ignored as the Java object does not include a field with this name. It is understandable that the fields' names do not follow the Java naming convention, but for the time being let's keep things simple. More about this is discussed in <a href="http://albertattard.blogspot.com/2012/06/practical-example-of-gson-part-2.html">part 2</a>.<br />
<pre><code>
package com.albertattard.examples.gson.part1_2;
public class Person1 {
private String NAME;
private String LOCATION;
<span style="color:green">// Getters and setters are not required for this example.</span>
<span style="color:green">// GSON sets the fields directly.</span>
@Override
public String toString() {
return NAME + " - " + LOCATION;
}
}
</code></pre>With the Java object ready, we can read the JSON objects and load them as Java objects as illustrated below. To simulate a real life situation, we're using a byte stream as input with default encoding. Also note that the JSON content is saved into a file (which is not usually the case) located in the same directory of the following class. <br />
<pre><code>
package com.albertattard.examples.gson.part1_2;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonToJava1 {
public static void main(String[] args) throws IOException {
Reader reader = new InputStreamReader(JsonToJava1.class
.getResourceAsStream("Server1.json"));
Gson gson = new GsonBuilder().create();
Person1 p = gson.fromJson(reader, Person1.class);
System.out.println(p);
reader.close();
}
}
</code></pre>This should produce: <code>Albert Attard - Malta</code>. Gson parsed the JSON object and created an instance of the <code>Person1</code> class. <br />
<h2>Nested JSON Objects</h2>Let's take the above example one step further and include a nested object as illustrated in the following JSON code fragment. <br />
<pre><code>
{
NAME:"Albert Attard",
P_LANGUAGE:"Java",
LOCATION:"Malta"<strong style="color:red">,
EXAM: {
SUBJECT:"Programming",
GRADE:4.5
}</strong>
}
</code></pre>Here we have an <code>EXAM</code> field which is made from two other fields: <code>SUBJECT</code> and <code>GRADE</code>. Likewise, we need to modify the <code>Person1</code> class defined above to include the <code>EXAM</code> field and create a new Java class to represent the <code>SUBJECT</code> and <code>GRADE</code> fields. <br />
<p>We first create the new class that will represent the nested object. As we discussed before, the class name is irrelevant but the fields' names must match those define in JSON. <br />
<pre><code>
package com.albertattard.examples.gson.part1_3;
public class Exam1 {
private String SUBJECT;
private double GRADE;
<span style="color:green">// Getters and setters are not required for this example.</span>
<span style="color:green">// GSON sets the fields directly.</span>
@Override
public String toString() {
return SUBJECT + " - " + GRADE;
}
}
</code></pre>Now we can modify the <code>Person1</code> class (<code>Person2</code> in the following example) and include a new field with the same name as in JSON of type <code>Exam1</code> as shown next. Instead we created a new class to keep track of the progress made. <br />
<pre><code>
package com.albertattard.examples.gson.part1_3;
public class Person2 {
private String NAME;
private String LOCATION;
<strong style="color:red">private Exam1 EXAM; </strong>
@Override
public String toString() {
return NAME + " - " + LOCATION <strong style="color:red">+ " (" + EXAM + ")"</strong>;
}
}
</code></pre>Note that the changes required are minimal as Gson dynamically discovers (through reflection) the class and its fields. This article does not cover reflection. For more information about reflection please refer to: <a href="http://today.java.net/pub/a/today/2008/02/12/reflection-in-action.html" target="_blank">Reflection in Action</a>. <br />
Finally, let's test the new changes. <br />
<pre><code>
package com.albertattard.examples.gson.part1_3;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonToJava2 {
public static void main(String[] args) throws IOException {
Reader reader = new InputStreamReader(JsonToJava2.class
.getResourceAsStream("Server2.json"));
Gson gson = new GsonBuilder().create();
<strong style="color:red">Person2 p = gson.fromJson(reader, Person2.class);</strong>
System.out.println(p);
reader.close();
}
}
</code></pre>Instead of using person 1, we're using the new class which include the new exam field. <br />
<h2>Conclusion</h2>Even though it may be a new concept, JSON is very simple and straight forward. The Gson API makes it very simple to use and even though not discussed here, it provides a great deal of flexibility.<br />
<p>For more GSON examples please visit the <a href="http://albertattard.blogspot.com/2012/06/practical-example-of-gson-part-2.html">second part (part-2)</a>, where we explore more complex examples and discuss how to use the GSON deserializer to take full control over the deserialization process.<br />
Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com27tag:blogger.com,1999:blog-6929422799523574458.post-76294212995045281102009-06-18T13:55:00.006+02:002009-06-26T08:26:31.561+02:00PreparedStatement and NULLs in the WHERE ClauseThe <code>java.sql.PreparedStatement</code> comes with a method for setting nulls as values for the parameters: <a hef="http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setNull(int, int)" target="_blank"><code>setNull(int, int)</code></a>. This method is very tricky and does not work as expected when it comes to the SQL WHERE clause.<br />
<p>This article talks about a common pitfall that may developers fall in and never test. More details about the prepared statement interface can be found at <a href="http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html" target="_blank">http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html </a><br />
<h2>The Problem</h2>Consider the following query <code>SELECT * FROM EMPLOYEES WHERE MANAGED_ID = ?</code>. This query returns all employees for a given manager id. The following code fragment illustrates how this query is used to retrieve all employees for manager id 100.<br />
<p><pre><code>
PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM EMPLOYEES WHERE MANAGED_ID = ?");
statement.setLong(1, 100L);
ResultSet resultSet = statement.executeQuery();
</code></pre><p>The above code works well for any manager id. But what if we would like to select all employees that do not have a manager, that is, the manager id column is set to <code>NULL</code> (SQL NULL)? If we do the following we will get nothing back, even if there are employees with no manager assigened.<br />
<p><pre><code>
PreparedStatement statement = connection.prepareStatement(
"SELECT * FROM EMPLOYEES WHERE MANAGED_ID = ?");
statement.setNull(1, Types.INTEGER);
ResultSet resultSet = statement.executeQuery();
</code></pre><p>Why? The advantage of the prepared statement is that the statement is compiled once and it is executed many times. This provides performance benefits but comes with a cost. That is, once the statement is compiled, the only things that can change are the parameters' values. The equals sign stays there. This instead of having our SQL statement <code>WHERE MANAGER_ID IS NULL</code> we have <code>WHERE MANAGER_ID = NULL</code>, which does not yield the same results.<br />
<h2>The Solution</h2><p>The solution is very simple. We have to modify the string version of the SQL statement to handle NULLs. Assume we have the following method that returns a list of employees for a given manager id, where a connection is already established and available to the same method.<br />
<p><pre><code>
public List<employee> getEmployeesWithManagerId(Long managerId)
throws SQLException {
List<employee> employees = new ArrayList<employee>();
String select = "SELECT * FROM EMPLOYEES WHERE MANAGER_ID "
+ (managerId == null?"IS NULL":"= ?");
PreparedStatement statement =
connection.prepareStatement(select);
if(managerId != null){
statement.setLong(1, 100L);
}
ResultSet resultSet = statement.executeQuery();
while(resultSet.next()){
// Get the employee details and add it to the list
}
return employees;
}
</code></pre><p>Why are we still using the prepared statement? Can we use the select statement instead and concatenate the values? Yes you can but not suggested as the prepared statement also provides protection against SQL injections.<br />
<h2>Conclusion</h2>Even though very simple, this is a common bug which can be easily iron out with proper testing. Since the database columns can accept <code>NULL</code>s, refrain from using Java primitives and use their wrappers instead. Note that the result set <code>getXXX</code> methods return the primitive values which can be tricky too. A 0 (zero - the default value for most of the primitives) is returned if the database field was <code>NULL</code>. In that case make sure to use to the method <a href="http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#wasNull()" target="_target">wasNull()</a>.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-74941343941981007892009-06-04T11:17:00.024+02:002009-06-09T15:56:25.942+02:00From XML to Java using SAX Parser<p>XML is a common way to save data especially while in transit between applications. For example, a program used to register students (written by a company) needs extract/load data produced by another program written by another company (may be in a different language). One of the best ways to do this is by having the source program producing an XML file and the destination program loading this file. <p>This article discusses how the Java SAX parser can be used to load an XML file as a List of Java objects. <h2>The problem</h2><p>Assume we need to develop a program that read the following simple XML file and loads it as a list of Java objects. The file is called <code>Test.xml</code>. <p><pre><code><a name="Test.xml"></a>
<students>
<student name="Albert Attard">
<class>Java</class>
<class>Math</class>
<grade>65</grade>
</student>
<student name="Mary Borg">
<class>English</class>
<grade>93</grade>
</student>
<student name="Joe Vella">
<class>Math</class>
<class>English</class>
<grade>47</grade>
</student>
<student name="Paul Galea">
<class>Math</class>
<class>Maltese</class>
<grade>52</grade>
</student>
</students>
</code></pre><p>The above XML file contains a list of four students, each student having a name, a list of classes that he/she will attend and their grade. The student name is an attribute of the student tag while the class and grade are inner tags of the student tag. <h2>Loading data from XML file</h2><p>There are various ways how we can load data from XML files in the Java language, each have cons and prons. Two common ways are DOM and SAX. What are these and why we're using one and not the other? The main difference between the two is that the DOM parser loads the XML file in a tree structure using DOM related classes. Once loaded, we can then create our structure from the DOM tree. On the other hand SAX parser does not load the XML but triggers a series of events thought which we can build our structure. SAX does not load anything into the memory. <h2>The SAX parser</h2><p>Before proceeding, let's first understand the <a href="http://java.sun.com/javase/6/docs/api/javax/xml/parsers/SAXParser.html" target="_blank">SAXParser</a> and the required elements. The SAX parser requires a handler to handle the events triggered by the same SAX parser. The handler is a java class that extends the <a href="http://java.sun.com/javase/6/docs/api/org/xml/sax/helpers/DefaultHandler.html" target="_blank">DefaultHandler</a> and provides implementation for some (or many) of the methods in the default handler. Note that the default handler implements a set of interfaces and provides a default implementation (methods doing nothing) for all inherited abstract methods. <p align="center"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWVOy60Sc2EbuplDC6uTPw4PNy24uRSpRUvMu4JJIQcNASBS8A2VPsOOkOMmUjLodxdLQ0i1nEQAQgQ-WIa0buHGFjcerr9bRTWLHqObRP_azRNu6VX1fqacutVdtYZDXji5GD199Ios/s1600-h/SAX_Handler_1.jpg" target="_blank"><img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSWVOy60Sc2EbuplDC6uTPw4PNy24uRSpRUvMu4JJIQcNASBS8A2VPsOOkOMmUjLodxdLQ0i1nEQAQgQ-WIa0buHGFjcerr9bRTWLHqObRP_azRNu6VX1fqacutVdtYZDXji5GD199Ios/s320/SAX_Handler_1.jpg" border="0" alt="SAX Parser" id="BLOGGER_PHOTO_ID_5343462235334893170" /></a> <p>The SAX parser is created using the <a href="http://java.sun.com/javase/6/docs/api/javax/xml/parsers/SAXParserFactory.html" target="_blank">SAXParserFactory</a> and the XML file is parsed using the provided handler (the default handler in this case) as illustrated in the following example: <p><pre><code><a name="Example1"></a>
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
public class Example1 {
public static void main(String[] args) throws Exception {
DefaultHandler handler = new DefaultHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser p = factory.newSAXParser();
p.parse(Example1.class.getResourceAsStream("Test.xml"),
handler);
}
}
</code></pre><p>Note that, here I'm using the default package for all examples and the <a href="#Test.xml"><code>Test.xml</code></a> file is in the same folder as the class files. If you move the classes into a package make sure to also move the xml file with them or emend the file path accordingly. <p>Executing the above example will produce nothing as the default handler simply ignores all events triggered by the parser. The SAX parses starts parsing the file and for every tag opened and close it invokes specific methods in the handler and pass the information from the XML file. Let's create a simple handler and some basic methods to helps us understand this better. This handler will be used to load a list of students from the XML file define above (<a href="#Test.xml">Test.xml</a>). <p><pre><code><a name="StudentHandler1"></a>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StudentHandler1 extends DefaultHandler {
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
}
@Override
public void endElement(String uri, String localName,
String name) throws SAXException {
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName,
String name,Attributes attributes)
throws SAXException {
}
}
</code></pre><p>The above class override four methods from the default handler class. <p>The <code> startDocument</code> method is invoked once when the SAX parser start parsing the XML document. This method has not parameters and can be used to initialise fields (similar to a constructor or initialising block). The default handler also includes the <code>endDocument</code> method which is invoked when the SAX parser is done parsing the file. This method can be used as a destructor method (or the final block) to clean up or wrap up and resources/fields as required. <p>The <code>startElement</code> method is invoked when the SAX parser encounters an XML tag. For example, this method is invoked when the SAX parser encounters an open tag such as: <code><students></code>. Similar, the <code>endElement</code> method is invoked by the parser when the close tag is found (for example: <code></students></code>). <p>Finally, the <code>characters</code> method is invoked when the parser encounters the tag body. The tag body is the text (not XML) within the tags. For example, the characters for the grade XML tag: <code><grade>85</grade></code>, is 85. Note that whitespaces are not removed or truncated and must be handled by the handler. <h2>Simple example</h2><p>Let's start with a simple example that counts the number of students in the XML file (<a href="#Test.xml">Test.xml</a>). All we need to do here is create an integer field, initialise it to 0 in the start document method and for every student tag we increment this variable. We removed the unnecessary method from the previous handler (<a href="#StudentHandler1">StudentHandler1 </a>) and added the end document method. <p><pre><code><a name="StudentHandler2"></a>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StudentHandler2 extends DefaultHandler {
private int studentsCount;
@Override
public void endDocument() throws SAXException {
System.out.println(studentsCount);
}
@Override
public void startDocument() throws SAXException {
studentsCount = 0;
}
@Override
public void startElement(String uri, String localName,
String name, Attributes attributes)
throws SAXException {
if ("student".equalsIgnoreCase(name)) {
studentsCount++; <span style="color: green;">// Increment statement</span>
}
}
}
</code></pre><p>Note that we enclosed the increment statement within the <em>if statement</em>. The <em>if statement</em> is checking the name of the XML tag. Note that our XML document has four different tags: <code>students</code>, <code>student</code>, <code>class</code> and <code>grade</code>. We only want to increment our counter when the <code>student</code> tag is opened. Also, the <em>if statement</em> is comparing the tag but ignoring case (case insensitive) as XML is not case sensitive and the tags may be in upper case. <p>Now, using the new handler (<a href="#StudentHandler2">StudentHandler2</a>), we can process our XML file (<a href="#Test.xml">Test.xml</a>) and see how many students we have. <p><pre><code><a name="Example2"></a>
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class Example2 {
public static void main(String[] args) throws Exception {
<strong>StudentHandler2 handler = new StudentHandler2();</strong>
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser p = factory.newSAXParser();
p.parse(Example2.class.getResourceAsStream("Test.xml"),
handler);
}
}
</code></pre><p>The above should produce 4 when executed against the <a href="#Test.xml">Test.xml</a> file. <p>As you can see, we didn’t loaded any data from the XML file into the memory. Instead we only performed the require operation (counting the number of student in this case). Using DOM here would be an overkill as all the students would have been loaded into the memory for nothing. We only required a count. I'm not saying that DOM is not good. All I'm saying is that DOM is not the right tool for this job. <h2>Some XML processing</h2><p>Let's improve our parser and calculate the average grade for all students. In order to calculate the average, we need to first calculate the sum and then divide by the number of students. This is not as simple as it sound as the SAX parser invokes the handler's methods independent from the tag. For example, the <code>startElement</code> method is invoked for every XML open tag. Same applies for all other handler methods. Thus we have to keep track which tag we're handling. <p>Let's understand this problem first. We need to get the contents between the grade's XML tag. This can be retrieved from the characters method. But this method is executed for every tag (as we established above). So we first need to see which tag is being processed from the start element method. Using a <code>boolean</code> field (referred to as <code>addToTotal</code> in the following example), we set this field to <code>true</code> when the start element method is invoked for the grade tag. Then, we only process characters when this field is set to true. We have to remember to set this field to <code>false</code> once the grade tag is processed. This can be done in the end element method. All this is captured in the following example. Note that changes are shown in <strong>bold</strong>. <p><pre><code><a name="StudentHandler3"></a>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StudentHandler3 extends DefaultHandler {
<strong>private boolean addToTotal;</strong>
<strong>private StringBuffer buffer;</strong>
private int studentsCount;
<strong>private int totalGrade;</strong>
<strong>@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (addToTotal) {
buffer.append(ch, start, length);
}
}</strong>
@Override
public void endDocument() throws SAXException {
System.out.println(studentsCount);
<strong>System.out.println(totalGrade * 1.0 / studentsCount);</strong>
}
<strong>@Override
public void endElement(String uri, String localName,
String name) throws SAXException {
if ("grade".equalsIgnoreCase(name)) {
addToTotal = false;
totalGrade += Integer.parseInt(buffer.toString().trim());
}
}</strong>
@Override
public void startDocument() throws SAXException {
studentsCount = 0;
<strong>totalGrade = 0;</strong>
}
@Override
public void startElement(String uri, String localName,
String name, Attributes attributes)
throws SAXException {
if ("student".equalsIgnoreCase(name)) {
studentsCount++;
} <strong>else if ("grade".equalsIgnoreCase(name)) {
addToTotal = true;
buffer = new StringBuffer();
}</strong>
}
}
</code></pre><p>Why are we using a string buffer in the <code>characters</code> method? The XML tag body (where the grade value is) can be very long and spread across multiple lines. For example, we can have the following: <p><pre><code>
<grade>
65
</grade>
</code></pre><p>In this case, the character method will be invoked three times (one for every line). Initially, it will be called with the new-line UNICODE symbol (<code>\n</code>), then with the text <code>65</code>, and finally with the other new-line UNICODE symbol. Thus we first need to accumulate all content (in this case: <code>\n65\n</code>) and then remove all leading and trailing whitespaces before parsing it into an integer. Note that our example will throw a <a href="http://java.sun.com/javase/6/docs/api/java/lang/NumberFormatException.html" target="_blank">NumberFormatException</a> is the given grade is not an integer. <h2>Handling XML attributes</h2><p>The XML student tag also includes an attribute, the student name. We can get this value and from the start element method's <a href="http://java.sun.com/javase/6/docs/api/org/xml/sax/package-summary.html" target="_blank">Attributes</a> parameter. The attribute parameter holds all attributes that belong to the tag being handled. The SAX parser takes care of populating the attributes when parsing the XML document. <p><pre><code><a name="StudentHandler4"></a>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StudentHandler4 extends DefaultHandler {
@Override
public void startElement(String uri, String localName,
String name, Attributes attributes)
throws SAXException {
if ("student".equalsIgnoreCase(name)) {
<strong>String studentName = attributes.getValue("name");
System.out.println(studentName);</strong>
}
}
}
</code></pre><p>The above handler will list all student names one following another. We can enhance this handler and save all students and their grade in a list as illustrated below. Ideally, before we proceed we create a Java class that represents the student. In this case the class only requires two fields, that is, the name and the grade. Note that in our problem we're not handling the student's class XML tag (we're ignoring it). <p><pre><code><a name="Student1"></a>
public class Student1 {
private int grade;
private String name;
// The getters and setters are omitted for brevity
@Override
public String toString() {
return name + " " + grade;
}
}
</code></pre><h2>Putting it all together</h2><p>Let's now combine everything together and build a list of student from the XML file. We need to change some of the fields and introduce new ones. For example, we need a list to put all the students in (<code>listOfStudents</code>) and we need a temporary variable to save the student until this is added into the list (<code>student</code>). No changes are highlighted in the following example as there are many changes. <p><pre><code>
import java.util.List;
import java.util.Vector;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StudentHandler5 extends DefaultHandler {
private StringBuffer buffer;
private boolean isStudentGrade;
private List<student1> listOfStudents;
private Student1 student;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (isStudentGrade) {
buffer.append(ch, start, length);
}
}
@Override
public void endDocument() throws SAXException {
System.out.println(listOfStudents);
}
@Override
public void endElement(String uri, String localName,
String name) throws SAXException {
if ("grade".equalsIgnoreCase(name)) {
isStudentGrade = false;
student.setGrade(
Integer.parseInt(buffer.toString().trim()));
} else if ("student".equalsIgnoreCase(name)) {
listOfStudents.add(student);
student = null;
}
}
@Override
public void startDocument() throws SAXException {
listOfStudents = new Vector<student1>();
}
@Override
public void startElement(String uri, String localName,
String name, Attributes attributes)
throws SAXException {
if ("student".equalsIgnoreCase(name)) {
String studentName = attributes.getValue("name");
student = new Student1();
student.setName(studentName);
} else if ("grade".equalsIgnoreCase(name)) {
isStudentGrade = true;
buffer = new StringBuffer();
}
}
}
</code></pre><p>Why the student is added into the list when the student close tag is processed when we could do this at the grade close tag? The reason behind that is if in the future we also add more fields, such as the student's class, we can easily do so with minimal changes to the code. <h2>Conclusion</h2><p>In this article I covered how to use the SAX parse for simple processing of XML files. The SAX parser is ideal when we need to perform some processing such as count the number of students or calculate the average grade without having to load the entire XML file into the memory.Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com2tag:blogger.com,1999:blog-6929422799523574458.post-45376137068629579912008-12-06T14:19:00.021+01:002008-12-29T15:21:38.251+01:00Generate all combinations of chars<p>Generating all combinations of the characters is not a simple task and one must think before starting any coding. The problem size (example 4 represents all combinations between <code>'a'</code> and <code>'ZZZZ'</code>) can vary and this makes the problem more complex to solve but simpler to program! There are various ways how to solve this problem. The solution discussed here describes how to convert an integer into a sequence of characters.</p>
<p>
This article describes how to write a Java program which returns all combinations of characters for a given length. Note that even though this is a programming related article it requires a good knowledge of mathematics. The examples make use of <em>logs</em> and <em>power of</em> to carry out the calculations required.
</p>
<h2>An overview of the solution</h2>
<p>
The solution discussed here describes how to convert an integer into a sequence of characters. Let's have a simple example, the integer <code>0</code> is equivalent to <code>['a']</code>, while integer <code>1</code> is equivalent to <code>['b']</code> and the integer <code>51</code> is equivalent to <code>['Z']</code>. This is great for a problem of size one. What about a problem of size two? In this case <code>0</code> is still <code>['a']</code> and <code>1</code> is still <code>['b']</code> and <code>51</code> is still equivalent to <code>['Z']</code>. Now <code>52</code> is (or should be) equivalent to <code>['a', 'a']</code>. The array size has changed from one to two. The integer <code>53</code> is equivalent <code>['a', 'b']</code> and so on.
</p>
<p>
Not everything that shines is gold! Let's switch to numbers instead of characters for now so we appreciate the problem that this will lead us into. We have ten numbers, from 0 until 9. The leading 0s are usually ignored and are not used. This creates a problem for our solution as the <code>0</code> is representing the char <code>'a'</code>. What I'm saying here? In numbers the value <code>00140</code> is equivalent to <code>140</code>, but this is not the case with our solution as the combination: <code>'aabda'</code> is not equivalent to <code>'bda'</code>. To avoid this problem we have to build sets of combinations with unique size. Thus the value <code>0</code> for problem size 4 is <code>'aaaa'</code> while the same value for a problem with size 7 will be: <code>'aaaaaaa'</code>. This is covered mathematically below.
</p>
<p>
Let's start with the simplest version of the problem when the size is one, that is, all the characters available in the English alphabet.
</p>
<h2>Convert an int into a char</h2>
<p>
We need to provide map for all characters in the alphabet. The following function does so by returning the char <code>'a'</code> for the integer <code>0</code> and the char <code>'z'</code> for the int <code>25</code>. The char <code>'A'</code> is returned for the int <code>26</code> while the char <code>'Z'</code> is returned for the int <code>51</code>. Integer values outside the mentioned range (0 and 51 inclusive) will throw an illegal argument exception.
</p>
<pre>
<code>
public static char getCharForInt(int i)
throws IllegalArgumentException {
if (i < 0 | i >= BASE) {
throw new IllegalArgumentException(
"Integer value out of range: " + i);
}
int length = (BASE) / 2;
// Lower case char
if (i < length) {
return (char) (i + 'a');
}
// Upper case char
return (char) (i - length + 'A');
}
</code>
</pre>
<p>This method is quite straight forward and simple to understand. This method returns just a single character which is only valid for a problem with size one. We need yet another method to generate an array of these. And that's what we're discussing next. Like here, this method will expect an integer and it will return the relative array of chars for the given integer. But before we proceed it's good to note that the method makes use of a constant named <code>BASE</code> which is declared at class level as illustrated below.</p>
<pre>
<code>
private static final int BASE = ('z' - 'a') + ('Z' - 'A') + 2;
</code>
</pre>
<h2>Build an array of chars for a given int</h2>
<p>
If we can provide a map of chars to ints programmatically, then we can also provide a map between an integer (referred to as key in this method) to an array of chars in conjunctions with the previous method. How? Let's have a numerical example first. The number 143 (base 10) can be expressed as: <code>1 * 10<sup>2</sup> + 4 * 10<sup>1</sup> + 3 * 10<sup>0</sup></code>. So to convert the number <code>143<sub>10</sub></code> into the array of chars <code>['1', '4', '3']</code> we need to perform the following steps:
</p>
<pre>
<code>
0) 143 / 10<sup>2</sup> = 1
1) 143 – (10<sup>2</sup>*1) / 10<sup>1</sup>
1) 143 – (100) / 10<sup>1</sup> = 4
2) 143 - ((10<sup>2</sup>*1) + (10<sup>1</sup>*4)) / 10<sup>0</sup>
2) 143 - (140) / 10<sup>0</sup> = 3
</code>
</pre>
<p>
Using the above approach we can convert the key integer value into an array of characters by changing the base from 10 to our base: 52. Before we can sing victory, we have to appreciate that this approach has a limitation. It will work well for the least significant character but it will miss one on the other characters. What am I saying? Let's have another example first:
</p>
<p>
<style>
table.ctx th {
background: #666666;
color: #FFFFFF;
text-align: center;
}
</style>
<table class="ctx" width="100%" style="border:1px solid #666666">
<tr>
<th>Key</th>
<th>Expression</th>
<th>Value</th>
<th>Expected</th>
<th>Output</th>
</tr>
<tr>
<td>0</td>
<td>0 * 52<sup>0</sup></td>
<td>0</td>
<td>'a'</td>
<td>'a'</td>
</tr>
<tr>
<td>52</td>
<td>
52 * 52<sup>1</sup>
<br/>
0 * 52<sup>0</sup>
</td>
<td>
1
<br/>
0
</td>
<td>'aa'</td>
<td>'ba'</td>
</tr>
</table>
</p>
<p>
When dividing 52 by 52 we get 1, which is equivalent to <code>'b'</code> not the answer we wanted! A simple way around this problem the solution and to reduce the number conditions we're going to make a small change to solution discussed before. We'll build sets of combinations with unique size. Thus the key value <code>0</code> for problem size 4 is <code>['a', 'a', 'a', 'a']</code> while the same value for a problem with size 7 will be: <code>['a', 'a', 'a', 'a', 'a', 'a', 'a'] </code>.
</p>
<p>
This immediately provokes the following question, how are we going to generate all combinations? We can still obtain all combinations by first generating all combinations for size one and size two and so on.
</p>
<p>
With that out of the way, we can proceed in our adventure. The following code provides the algorithm used to generate all combination for a specific size.
</p>
<pre>
<code>
private static char[] getCharsFormKey(int key, int size) {
char[] chars = new char[size];
for (int i = size - 1, j = 0; i >= 0; i--, j++) {
// Get the divider for this character position
int divider = (int) Math.pow(BASE, i);
// Calculate the character index by dividing the
// key with the divider
int c = key / divider;
chars[j] = getCharForInt(c);
// Deduct the processed numbers
key -= (c * divider);
}
return chars;
}
</code>
</pre>
<p>
Given a key integer and a size, this method returns the equivalent array of chars mapping the given key integer. Note that an illegal argument exception is thrown if the key integers requires a larger array that the specified size. This immediately brings us the following question: can we calculate the size automatically to fit the given key value? Yes and to do so we need to make use of the <a hre=" http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html" target="_blank">BigDecimal</a> class to perform some calculations. We can determine the number of digits within a number by calculating the log to base 10 of that number incrementing it by one. In our case we have to calculate the log to base 52. There is not function ready which does that. But we can calculate the log of any base by using log to base 10 or ln as log<sub>n</sub>(X) is equivalent to log<sub>10</sub>(X) / log<sub>10</sub>(n).
</p>
<pre>
<code>
private static char[] getCharsFormKey(int key) {
int size = 1;
if (key > 0) {
BigDecimal keyDB =
new BigDecimal(String.valueOf(Math.log(key)));
size = (int) (keyDB.divide(
BASE_LOG_BD, RoundingMode.HALF_UP).doubleValue()
) + 1;
}
return getCharsFormKey(key, size);
}
</code>
</pre>
<p>
This method may be more attractive as it requires less parameters. The calculations involved here take some time and affect the performance. This method is mentioned for the sake of completeness and should be avoided if possible. This method makes use of a constant named <code>BASE_LOG_BD</code> which is declared at class level as illustrated below. Also note that the string version of the big decimal class is used as the double version is more prone to error as discussed at: <a href="http://www.opensourcestrategies.com/ofbiz/ofbiz_bigdecimal_cookbook.txt" targer="_blank">http://www.opensourcestrategies.com/ofbiz/ofbiz_bigdecimal_cookbook.txt</a>.
</p>
<pre>
<code>
private static final BigDecimal BASE_LOG_BD =
new BigDecimal(String.valueOf(Math.log(52)));</code>
</pre>
</p>
<h2>Generating all combinations</h2>
<p>
To generate all combinations for a problem size 4, that is, generate all combinations starting from <code>'a'</code> until <code>'ZZZZ'</code>. We need two loops in order to achieve this: one to generate all combinations for a specific size or length, while the other to go through all sizes/lengths starting from 1 until the problem size, four in this case.
</p>
<pre>
<code>
int size = 4;
for (int i = 1; i <= size; i++) {
int maxKeyForSize = (int) Math.pow(BASE, i);
for (int j = 0; j < maxKeyForSize; j++) {
char[] chars = getCharsFormKey(j, i);
String text = String.copyValueOf(chars);
System.out.println(text);
}
}
</code>
</pre>
<h2>Conclusion</h2>
<p>
This article describes how to generate all combinations of characters for a given size using the mathematical functions <em>ln</em> and <em>power of</em>.
</p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-64900179374658370902008-11-14T14:44:00.024+01:002009-06-04T10:38:38.447+02:00Sorting Objects using Comparator<p>Sorting is common functionality required by many applications. Questions like: <em>How do we sort in Java?</em> or <em>What should we use as sorting algorithm?</em> need to answered before we can perform any kind of sorting. Definitely we're not the first ones who require this feature and others have already done it before for us. So we can simple use the Java API provided to perform sorting.
<p>The following article explains the concept of sorting and how to use the Java API to solve this problem and closes with some programming tips.
<h2>Concept behind sorting</h2>
<p>In order to be able to sort elements we need to be able to compare them. What does this mean? If you have two things and you need to pick one of them, which one would you pick? Let's make this more realistic. If you're not rich and you can choose between €1 and €100, which one would you choose? I don't know what would you do, but I would go for the hundred. Why? Because 100 is greater than 1! I was able to make this decision because I was able to compare the choice at hand. If instead of numbers I said choose between <code>A</code> and <code>B</code>, where <code>A</code> and <code>B</code> can be anything, would you be able to do an informed decision? No, it would be pure gamble - a matter of luck. There is no way to compare <code>A</code> and <code>B</code> without further knowledge.
<p>In order to be able to sort two elements (or more), you need to be able to compare them. Similar to the problem discussed above, we need to be able to evaluate elements and then sort them based on this value. For example, if we need to sort the following list: <code>{8, 5, 9}</code>, we know that <code>5</code> is less than <code>8</code> so these two have to be swapped. Sorting numbers is very simple and straight forward. We cannot say the same for any other object (Java and real). For example, if we have a list of boxes, how would we sort them? If we're sorting by size, we first determine the size of each and then using the size value (a number) as sorting criteria. So in order to sort any kind of object, all we need to do is to convert the object into a number that we can compare with. So if we have the following list of objects: <code>{a, b, c, d}</code> (the letters in the previous list is used only to define the object name and has no effect on the sorting) with sorting values <code>{4, 3, 7, 5}</code> respectively, we know that object <code>b</code> should come first while object <code>c</code> should be placed last and so on.
<h2>How do we implement this in Java?</h2>
<p>Java provides a set of classes and interfaces which we can use to sort lists and arrays. Most of the following examples will use lists but the same concept can be applied for arrays. A final example will show this.
<p>Let's start by creating a list of Integers and sort these using the <a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List)" target="_blank">Collections.sort</a> method. The <a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html" target="_blank">Collections</a> class (part of the <a href="http://java.sun.com/javase/6/docs/technotes/guides/collections/index.html" target="_blank">Java Collection Framework</a>) provides a list of static methods which we can use when working with collections such as list, set and the like. So in a nutshell, we can sort a list by simply calling: <code>java.util.Collections.sort(<em>the list</em>)</code> as shown in the following example:
<p>
<pre><code><a name="Example1"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example1 {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<Integer>();
ints.add(4);
ints.add(3);
ints.add(7);
ints.add(5);
Collections.sort(ints);
System.out.println(ints);
}
}
</code></pre>
<p>The above class creates a list of four integers and, using the collection's sort method, sorts this list (in one line of code) without us having to worry about the sorting algorithm.
<p>Java was able to sort this list because it <em>knows</em> how to compare integers as the <a href="http://java.sun.com/javase/6/docs/api/java/lang/Integer.html" target="_blank">Integer</a> class implements the <a href="http://java.sun.com/javase/6/docs/api/java/lang/Comparable.html" target="_blank">Comparable</a> interface. Note that, as from Java 1.5, the primitive <code>int</code> value is <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html" target="_blank">autoboxed</a> into an <code>Integer</code> (the object wrapper for int) before added to the list. Thus in order to be able to make use of the collection's sort method, all we need to do is implement the comparable interface by our objects.
<p>Let's take this example one step further and create our own class. Let's create a list of students and sort them by their grade (which is a number). The student class will have two fields: name and grade. In order to be able to use the sort method from the collections class, as we did in the above example (<a href="#Example1">Example1</a>), we have to implement the comparable interface and its method, as illustrated below:
<p>
<pre><code><a name="Student1"></a>
public class Student1 <strong>implements Comparable<Student1></strong> {
private int grade;
private String name;
public Student1(String name, int grade) {
setName(name);
setGrade(grade);
}
@Override
public int compareTo(Student1 o) {
return grade - o.grade;
}
@Override
public String toString() {
return name + " " + grade;
}
// Getters and setters are removed for brevity
} </code></pre>
<p>The <code>compareTo</code> method should return a negative integer, zero, or a positive integer if this student's grade is less than, equal to, or greater than the specified/given student's grade. The simplest way to do it is to subtract the grades of these students. Why and how would that help sorting? If this student's grade is larger than the grade of the given student, then a positive number is returned, while if the grades are equal, zero is returned. This follows the method's contract/specifications. Note that our job is to provide information to the sorting algorithm and not sorting the objects ourselves.
<p>The <code>toString</code> method was overridden so that we can see readable results when we print the list. Otherwise the output will look something like: <code>[Student1@19821f, Student1@addbf1, Student1@42e816, Student1@9304b1]</code> (instead of: <code>[Joe Vella 47, Paul Galea 52, Albert Attard 65, Mary Borg 93]</code>) which is not readable.
<p>Let's modify the previous class (<a href="#Example1">Example 1</a>) and sort a list of students.
<p>
<pre><code><a name="Example2"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example2 {
public static void main(String[] args) {
List<Student1> students = new ArrayList<Student1>();
students.add(new Student1("Albert Attard", 65));
students.add(new Student1("Mary Borg", 93));
students.add(new Student1("Joe Vella", 47));
students.add(new Student1("Paul Galea", 52));
Collections.sort(students);
System.out.println(students);
}
}
</code></pre>
<h2>Making full use of the API</h2>
<p>How can we sort the student by both name and grade? In order to achieve this using the comparable interface (above) we have to add more fields to the student class in order to be able to determine which field we're sorting on. <u>The following approach is not recommended and included here only for demonstration and comparisons purposes</u>. Changes are shown in <strong>bold</strong>.
<p>
<pre><code><a name="Student2"></a>
public class Student2 implements Comparable<Student2> {
private int grade;
private String name;
<strong>private int sortBy;</strong>
public Student2(String name, int grade, <strong>int sortBy</strong>) {
setName(name);
setGrade(grade);
<strong>setSortBy(sortBy);</strong>
}
<strong>@Override
public int compareTo(Student2 o) {
switch (sortBy) {
case 1: // Sort by name
return name.compareTo(o.name);
default: // Sort by grade by default
return grade - o.grade;
}
}</strong>
// Getters, setters and toString method are removed for
// brevity
}
</code></pre>
<p>We had to add a new field in the student class, called <code>sortBy</code>, which we have to set to 1 in order to sort the students by their name. Any other value will sort the students by their grade as illustrated in the following example. Ideally we use enums instead of int as the data type of the <code>sortBy</code> field which will prevent illegal values. Changes are shown in <strong>bold</strong>.
<p>
<pre><code><a name="Example3"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example3 {
public static void main(String[] args) {
List<Student2> students = new ArrayList<Student2>();
students.add(new Student2("Albert Attard", 65<strong>, 1</strong>));
students.add(new Student2("Mary Borg", 93<strong>, 1</strong>));
students.add(new Student2("Joe Vella", 47<strong>, 1</strong>));
students.add(new Student2("Paul Galea", 52<strong>, 1</strong>));
// Sort by name
Collections.sort(students);
System.out.println(students);
<strong>// Change these to sort them by grade
for(Student2 student:students){
student.setSortBy(0);
}
Collections.sort(students);
System.out.println(students);</strong>
}
}
</code></pre>
<p>This approach has two main pitfalls. First, the student class has to include fields and methods that are not related to the student object. Sorting properties are not student properties. The other issue is that for any new fields or sorting order we have to change the student class and emend the <code>compareTo</code> method accordingly, adding complexity to a method making it harder to maintain. Also, the sorting method is bound with the student class and cannot be used alone (apart from the object). The sorting state are saved with the object's state which is not what we want. For every student we have an instance of the <code>sortby</code> field, which we cannot make static. Why? If we have two lists, one to be sorted by name and the other by grade, then the static value will be shared by all instance of student and may effect the sorting outcome.
<p>Java provides another way to compare objects. Instead of implementing the comparable interface (<a href="#Student2">Student2</a>), we can implement the <a href="http://java.sun.com/javase/6/docs/api/java/util/Comparator.html" target="_blank">Comparator</a> interface. What's the difference? The main difference between these two interfaces is that the comparable interface defines one method <code>compareTo</code>, which takes <strong>one</strong> parameter. This parameter is compared with <em>this</em> object (the instance of student). In other words, the student object has a method which makes it able to compare to another student. On the other hand, the comparator interface defines one method (in reality two, but we're not interested from the <a href="http://java.sun.com/javase/6/docs/api/java/util/Comparator.html#equals(java.lang.Object)" target="_blank">second one</a>) that takes two parameters (of the same type) and returns the comparison of these two objects (an int exactly the same as the method <code>compareTo</code> from the comparable interface). As such, the comparator allows us to remove the unnecessary fields and methods from the student class and move these elsewhere as illustrated below.
<p>With reference to the <a href="#Student1">Student1</a> class defined above.
<p>
<pre><code><a name="StudentGradeComparator1"></a>
import java.util.Comparator;
public class StudentGradeComparator1 implements Comparator<Student1> {
@Override
public int compare(Student1 a, Student1 b) {
return a.getGrade() - b.getGrade();
}
}
</code></pre>
<p>How can we use this? The collections class has an overloaded version of the sort method (<a href=" http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List, java.util.Comparator)" target="_blank">http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List, java.util.Comparator)</a>). The overloaded version accepts two parameters: the list to be sorted and an instance of comparator. The comparator outcome will be used by the sorting algorithm to determine the elements' magnitude and relation. Changes from the previous examples, are shown in <strong>bold</strong>.
<p>
<pre><code><a name="Example4"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example4 {
public static void main(String[] args) {
List<Student1> students = new ArrayList<Student1>();
students.add(new Student1("Albert Attard", 65));
students.add(new Student1("Mary Borg", 93));
students.add(new Student1("Joe Vella", 47));
students.add(new Student1("Paul Galea", 52));
Collections.sort(students, <strong>new StudentGradeComparator1()</strong>);
System.out.println(students);
}
}
</code></pre>
<p>How can we sort by name? We can create another class that implements comparator and compare the student class as required. All we need to do is replace the compare method as shown below.
<p>
<pre><code>
@Override
public int compare(Student1 a, Student1 b) {
return <strong>a.getName().compareTo(b.getName())</strong>;
}
</code></pre>
<h2>Making the difference</h2>
<p>Let's analyse the <a href="StudentGradeComparator1">StudentGradeComparator1</a> class created above. This class has no fields, thus we can say that this class is stateless. Do we need to create more than one instance of this class? No. We don't need to have more than one instance of this class as the fields of this class (that are none) never change. So we can have one instance a always use it. This is referred to the singleton pattern. In simple terms, this pattern prevents the user to create more than one instance of this object. For more information about this, please refer to: <a href="http://java.sun.com/developer/JDCTechTips/2006/tt0113.html" target="_blank">http://java.sun.com/developer/JDCTechTips/2006/tt0113.html</a> article. Why should we have it? Every object created consumes memory. Since our class (<a href="StudentGradeComparator1">StudentGradeComparator1</a>) is stateless, there is no need to enable/allow the user to create hundreds or thousands instance of this class as these will be identical. Changes are shown in <strong>bold</strong>.
<p>
<pre><code><a name="StudentGradeComparator2"></a>
import java.util.Comparator;
public class StudentGradeComparator2 implements Comparator<Student1> {
<strong>private static final StudentGradeComparator2 instance =
new StudentGradeComparator2();</strong>
<strong>public static StudentGradeComparator2 getInstance() {
return instance;
}</strong>
<strong>private StudentGradeComparator2() {
}</strong>
@Override
public int compare(Student1 a, Student1 b) {
return a.getGrade() - b.getGrade();
}
}
</code></pre>
<p>This got more complex, but in reality it got simpler. The student class only contain code related to the student, while the <em>sorting</em> classes contain the code required by the comparator. This means that each class is doing only thing.
<p>How can we use it? Instead of creating an instance of the comparator, we call the get instance method: <code>Collections.sort(students, StudentGradeComparator2.getInstance())</code> as shown in <strong>bold</strong> below:
<p>
<pre><code><a name="Example5"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example5 {
public static void main(String[] args) {
List<Student1> students = new ArrayList<Student1>();
students.add(new Student1("Albert Attard", 65));
students.add(new Student1("Mary Borg", 93));
students.add(new Student1("Joe Vella", 47));
students.add(new Student1("Paul Galea", 52));
Collections.sort(students,
<strong>StudentGradeComparator2.getInstance()</strong>);
System.out.println(students);
}
}
</code></pre>
<p>How can we sort the students by their grade but in descending order? Taking this another level, we can have two instances of the comparator class (not singleton anymore): one to sort ascending and the other descending. Here we're extending the singleton concept to prevent the user from freely creating instances. We can remove the get instance method and allow access to the static fields as shown below. Since, the class is radically changed, no changes are highlighted.
<p>
<pre><code><a name="StudentGradeComparator3"></a>
import java.util.Comparator;
public class StudentGradeComparator3 implements Comparator<Student1> {
public static final StudentGradeComparator3 ASC =
new StudentGradeComparator3(1);
public static final StudentGradeComparator3 DESC =
new StudentGradeComparator3(-1);
private final int order;
private StudentGradeComparator3(int order) {
this.order = order;
}
@Override
public int compare(Student1 a, Student1 b) {
return order * (a.getGrade() - b.getGrade());
}
}
</code></pre>
<p>Here we removed the get instance method and included two instances <code>ASC</code> and <code>DESC</code>. We added an integer (named <code>order</code>) with values 1 or -1 which is used to switch the sorting polarity. Note that when a number is multiplied by a negative number, its sign (negative or positive) is changed. Changing the sign will change the sorting order. This field is constant (not static) and is set through the solo private constructor by the two static fields.
<p>
<pre><code><a name="Example6"></a>
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Example6 {
public static void main(String[] args) {
List<Student1> students = new ArrayList<Student1>();
students.add(new Student1("Albert Attard", 65));
students.add(new Student1("Mary Borg", 93));
students.add(new Student1("Joe Vella", 47));
students.add(new Student1("Paul Galea", 52));
Collections.sort(students, <strong>StudentGradeComparator3.ASC</strong>);
System.out.println(students);
Collections.sort(students, <strong>StudentGradeComparator3.DESC</strong>);
System.out.println(students);
}
}
</code></pre>
<h2>Arrays</h2>
<p>We can easily adopt the above example for arrays. Instead of using collection's sort method we use the array's version (<a href="http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#sort(T[], java.util.Comparator)" target="_blank">http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#sort(T[], java.util.Comparator)</a>).
<p>
<pre><code><a name="Example7"></a>
import java.util.Arrays;
public class Example7 {
public static void main(String[] args) {
Student1[] students = { new Student1("Albert Attard", 65),
new Student1("Mary Borg", 93),
new Student1("Joe Vella", 47),
new Student1("Paul Galea", 52) };
Arrays.sort(students, StudentGradeComparator3.ASC);
System.out.println(students);
}
}
</code></pre>
<p>The same comparator is used to sort the array of students.
<h2>Conclusion</h2>
This article discusses how to perform sorting without having to worry about the sorting algorithm. From the collections Java doc:
<p>"<em>...the sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n log(n) performance. The specified list must be modifiable, but need not be resizable. This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n<sup>2</sup> log(n) performance that would result from attempting to sort a linked list in place...</em>
<p>One thing to take away from this article is don't reinvent the wheel. Before implementing something, have a look around as most probably others did it before youAnonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0tag:blogger.com,1999:blog-6929422799523574458.post-8409568320789108192008-09-28T18:31:00.013+02:002013-01-02T09:07:46.092+01:00Practical Example of Swing Timer<p>If you have to do something repetitively, what would you use? The first quick answer would be: loops (iteration). But that would prevent other things from happening until the loop is done! Threads can solve the seizing of control problem. But threads may be complex for someone who is new to programming and require some skill. What else can we use? <a href=" http://java.sun.com/javase/6/docs/api/javax/swing/Timer.html" target="_blank"><strong>Swing Timer</strong></a>! </p><h2>Swing Timer</h2><p>Swing timer provides a unique wrapper which presents threads in an event driven fashion. Imagine we need to display the text <code>"hello"</code> in the console every one second without having to seize the control. How would we do that using the swing timer class? </p><p style="padding-left:10px;"><em> Note that there are three Timer classes in the Java API. We're using <a href=" http://java.sun.com/javase/6/docs/api/javax/swing/Timer.html" target="_blank">javax.swing.Timer</a>. Make sure you have the correct import. </em></p><pre><code>
ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent event){
System.out.println("hello");
}
};
Timer displayTimer = new Timer(1000, listener);
displayTimer.start();
</code>
</pre><p>The swing timer has only one constructor which takes two parameters: the time gap (sometimes referred to as delay, in milliseconds) and an action listener. The swing timer fires an action event at specific intervals, which is handled by the action listener. The interval can be adjusted and more listeners can be added (and removed) as needs be using the <code>setDelay(int)</code> and <code>addActionListener(ActionListener)</code> (and <code>removeActionListener(ActionListener)</code>) methods. But let's keep it simple. For more details about available functionality provided by the swing timer class please refer to the <a href=" http://java.sun.com/javase/6/docs/api/javax/swing/Timer.html" target="_blank">javax.swing.Timer API</a>. </p><h3>Start the timer</h3><p>No action will happen until the <code>start()</code> method is invoked. When the start method is invoked the timer waits for some time (referred to as initial delay) before it fires the first action event. This is governed by the initial delay which is initially set equal to the time gap provided as the constructor's first parameter. The initial delay can be adjusted accordingly using the <code>setInitialDelay(int)</code> method. It's important to set this value before invoking the start method. </p><pre><code>
Timer displayTimer = new Timer(1000, listener);
displayTimer.setinitialDelay(0);
displayTimer.start();
</code>
</pre><p>The above example will fire the first action immediately, as the initial delay is set to 0 milliseconds. It will trigger subsequent events with a one second (1000 milliseconds) interval. </p><h3>Stop the timer</h3><p>One of the best features provided by the swing timer is the ability to start and stop and even restart the timer without having to worry about the thread lifecycle. </p><p style="padding-left:10px;"><em> Those who already worked with threads know that a thread cannot be restarted. Once ready, it must die (unreferenced) and another instance has to be instantiated in order to perform the thread's work. </em></p><p>To stop the swing timer, simple call the <code>stop()</code> method. This will stop the swing timer from firing any subsequent action events. </p><pre><code>
displayTimer.stop();
</code>
</pre><p>The swing timer can be restarted by simply calling the <code>start()</code> method again. </p><h3>Restarting the swing timer</h3><p>The swing timer can be restarted using the <code>stop()</code> <code>start()</code> methods. Alternatively, the <code>restart()</code> method can be used which cancels any pending firings of events and starts all over. </p><pre><code>
displayTimer.restart();
</code>
</pre><h3>A graphical example</h3>Let's create a simple applet which has a bouncing ball. The ball will stop moving once the user presses any key and starts bouncing again once another key is pressed again. This example will toggle the state of the swing timer between running and stopped. The swing timer provides a method called <code>isRunning()</code> which returns <code>true</code> if the swing timer is running, <code>false</code> otherwise. </p><pre><code>
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (moveBallTimer.isRunning()) {
moveBallTimer.stop();
} else {
moveBallTimer.start();
}
}
});
</code>
</pre><p>The full applet code listed below </p><pre><code>
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import javax.swing.JApplet;
import javax.swing.Timer;
public class SwingTimerAppletDemo1 extends JApplet {
private static final long serialVersionUID = 656209471758159755L;
private Ellipse2D ball;
private Timer moveBallTimer;
private int moveX;
private int moveY;
@Override
public void init() {
ball = new Ellipse2D.Double(0, 0, 10, 10);
moveX = 5;
moveY = 5;
moveBallTimer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
moveBall();
repaint();
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (moveBallTimer.isRunning()) {
moveBallTimer.stop();
} else {
moveBallTimer.start();
}
}
});
}
protected void moveBall() {
int width = getWidth();
int height = getHeight();
Rectangle ballBounds = ball.getBounds();
if (ballBounds.x + moveX < 0) {
moveX = 5;
} else if (ballBounds.x + ballBounds.width + moveX > width) {
moveX = -5;
}
if (ballBounds.y + moveY < 0) {
moveY = 5;
} else if (ballBounds.y + ballBounds.height + moveY > height) {
moveY = -5;
}
ballBounds.x += moveX;
ballBounds.y += moveY;
ball.setFrame(ballBounds);
}
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.fill(ball);
}
@Override
public void start() {
moveBallTimer.start();
}
@Override
public void stop() {
moveBallTimer.stop();
}
}
</code>
</pre><p>The above program is mainly doing two things: listens for user input through the keyboard and moving/bouncing the ball around the applet. This was possible as the swing timer makes use of threads to fire an action event and wait until the delay is over to fire the next action event. While waiting, the application can do other things such as listens to the user input. </p><p>What will happen if an action event is fired before the previous one has finish execution? By default the swing timer will merge consecutive action events into one. This behaviour is determined by the <code>coalesce</code> property. If set to <code>false</code> using the <code>setCoalesce(boolean)</code> method, the swing timer will fire all action event. This will cause queuing of action events as these are triggered at a faster rate than are handled. </p><h3>Conclusion</h3><p>The swing timer is a good candidate for invoking repetitive tasks without seizing the control. On the other hand, the tasks cannot be long lasting ones as otherwise it may block other things from happening making the application less responsive. The swing worker should be used for long lasting jobs. </p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com6tag:blogger.com,1999:blog-6929422799523574458.post-57168980790763558162008-09-04T20:24:00.027+02:002013-01-02T09:08:03.099+01:00Practical Example of Swing Worker<p><strong>Please note that this page has moved to: <a href="http://www.javacreed.com/swing-worker-example/">http://www.javacreed.com/swing-worker-example/</a></strong>.</p><p>Java provides a neat way to carry out long lasting jobs without have to worry about threads and hanging the application. It's called <a href="http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html" target="_blank">SwingWorker</a>. It's not the latest thing on Earth (released with Java 1.6) and you may have already read about it. What I never came across was a practical example of the swing worker. </p><h2>Swing Worker</h2><p><a href="http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html" target="_blank">SwingWorker</a> is an abstract class which hides the threading complexities from the developer. It's an excellent candidate for applications that are required to do tasks (such as retrieving information over the network/internet) which may take some time to finish. It's ideal to detach such tasks from the application and simply keep an <em>eye</em> on their progress. But before we hit the road and start working with the swing worker we have to see what <em>"eye"</em> are we going to put on our worker so to say. </p><p>The following example illustrates a simple empty worker that will return/evaluate to an integer when the given task is finished. It will inform the application (the <em>"eye"</em> thing) with what's happening using objects of type string, basically text messages. </p><pre><code>
import javax.swing.SwingWorker;
public class MyBlankWorker extends SwingWorker<Integer, String> {
// Some code must go here
}
</code>
</pre><p>The string worker class provides two place holders (generics). The first one represents the type of object returned when the worker has finished working. The second one represents the type of information that the worker will use to inform (update) the application with its progress. The swing worker class also provides means to update the progress by means of an integer which has nothing to do with the two generics mentioned before. </p><h3>Practical Example</h3><p>Example: Let say we need to find the number of occurrences of a given word with in some documents. So we would be writing something like: </p><pre><code>
import java.io.File;
import javax.swing.SwingWorker;
public class SearchForWordWorker
extends SwingWorker<Integer, String> {
private final String word;
private final File[] documents;
public SearchForWordWorker(String word, File[] documents){
this.word = word;
this.documents = documents;
}
@Override
protected Integer doInBackground() throws Exception {
int matches = 0;
for(int i=0, size=documents.length; i<size; i++){
// Update the status: the keep an eye on thing
publish("Searching file: "+documents[i]);
try {
// Do the search stuff
// Here you increment the variable matches
} finally {
// Close the current file
}
// update the progress
setProgress( (i+1) * 100 / size);
}
return matches;
}
}
</code>
</pre><p>The first thing that comes into mind is where is the text <em>"Searching file: ..."</em> is going? The swing worker class provides another method called process which accepts a list (of type string in our case) and used to process the published information (which can be an object of any kind). Overriding this method, allows us to take full control of this information. </p><pre><code>
@Override
protected void process(List<String> chunks){
for(String message : chunks){
System.out.println(message);
}
}
</code>
</pre><p>The above example is not much useful. We may need to update the status bar of an application or the text of the progress bar or a label sitting somewhere in the application. Since we may be monitoring this worker from various UI components, ideally we add a level of isolation between the worker and the UI components. In many examples, the worker was fed UI components as constructor parameters. I would go for interfaces instead to make the design pluggable when possible. </p><p>In other occasions a worker may be used to populate a table which information is coming from a slow source. In this case we may use the table model as one of the workers parameter and the array of objects representing the row. The following example makes use of the default table model as the design is simpler. </p><pre><code>
import java.util.List;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableModel;
public class PopulateTableWorker
extends SwingWorker<DefaultTableModel, Object[]> {
private final DefaultTableModel model;
public PopulateTableWorker(DefaultTableModel model){
this.model = model;
}
@Override
protected DefaultTableModel doInBackground() throws Exception {
// While there are more rows
while(Math.random() < 0.5){
// Get the row from the slow source
Object[] row = {1, "Java"};
Thread.sleep(2000);
// Update the model with the new row
publish(row);
}
return model;
}
@Override
protected void process(List<Object[]> chunks){
for(Object[] row : chunks){
model.addRow(row);
}
}
}
</code>
</pre><p>Note that the table model interface does not support addition of new rows. Alternatively we can make use of the table model interface. The model must be able to add a new row when this is required as otherwise an exception may be thrown. </p><pre><code>
import java.util.List;
import javax.swing.SwingWorker;
import javax.swing.table.TableModel;
public class PopulateTableWorker
extends SwingWorker<TableModel, Object[]> {
private final TableModel model;
private int rowIndex = 0;
public PopulateTableWorker(TableModel model){
this.model = model;
}
@Override
protected TableModel doInBackground() throws Exception {
// While there are more rows
while(Math.random() < 0.5){
// Get the row from the slow source
Object[] row = {1, "Java"};
Thread.sleep(2000);
// Update the model with the new row
publish(row);
}
return model;
}
@Override
protected void process(List<Object[]> chunks){
for(Object[] row : chunks){
for(int columnIndex=0, size=row.length;
columnIndex<size;
columnIndex++){
model.setValueAt(row[columnIndex], rowIndex, columnIndex);
}
}
rowIndex++;
}
}
</code>
</pre><p>Back to our example, we can have an interface called <em>Informable</em> (or you can pick a name of your liking) with one method: <em>messageChanged(String message)</em>, which will be invoked whenever some progress is made and published. </p><pre><code>
public interface Informable {
void messageChanged(String message);
}
</code>
</pre><p>The worker also requires an instance of the interface as it will be used to publish the results through. </p><pre><code>
import java.io.File;
import java.util.List;
import javax.swing.SwingWorker;
public class SearchForWordWorker
extends SwingWorker<Integer, String> {
private final String word;
private final File[] documents;
private final Informable informable;
public SearchForWordWorker(String word,
File[] documents,
Informable informable){
this.word = word;
this.documents = documents;
this.informable = informable;
}
@Override
protected Integer doInBackground() throws Exception {
int matches = 0;
for(int i=0, size=documents.length; i<size; i++){
// Update the status: the keep an eye on thing
publish("Searching file: "+documents[i]);
try {
// Do the search stuff
// Here you increment the variable matches
} finally {
// Close the current file
}
// update the progress
setProgress( (i+1) * 100 / size);
}
return matches;
}
@Override
protected void process(List<String> chunks){
for(String message : chunks){
informable.messageChanged(message);
}
}
}
</code>
</pre><p>The above worker can be easily plugged into the application as show in the following example. This application has three graphical components: a label acting as a title displaying the latest message published by the worker; a text area which displays all messages published by the worker; and a progress bar showing the progress made. </p><p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6jeC0NDmtTZPB8lIb1huuWnSRnS_EUene6J4oICeOiuhSOwVMoEaE2bhDt0me5O8HfHl_zbh1uTWXgi3Tcb8nE-27_ro5pVroAItuQA4SfMqH-TRc8Y1Kt_i1e9FIsrufxcTomQXjZbE/s1600-h/Application.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6jeC0NDmtTZPB8lIb1huuWnSRnS_EUene6J4oICeOiuhSOwVMoEaE2bhDt0me5O8HfHl_zbh1uTWXgi3Tcb8nE-27_ro5pVroAItuQA4SfMqH-TRc8Y1Kt_i1e9FIsrufxcTomQXjZbE/s320/Application.png" border="0" alt="Demo: Swing Worker Application" id="BLOGGER_PHOTO_ID_5243713316617297378" /></a> </p><p>The label and text area are governed by <em>Informable</em> interface. The progress bar is governed by the worker's progress property. </p><pre><code>
import java.awt.*;
import java.beans.*;
import java.io.*;
import javax.swing.*;
public class Application extends JFrame {
// The UI Components
private JLabel label;
private JProgressBar progressBar;
private JTextArea textArea;
private void initComponents(){
// The interface will update the text of the UI components
Informable informable = new Informable(){
@Override
public void messageChanged(String message){
label.setText(message);
textArea.append(message + "\n");
}
};
// The UI components
label = new JLabel("");
add(label, BorderLayout.NORTH);
textArea = new JTextArea(5, 30);
add(new JScrollPane(textArea), BorderLayout.CENTER);
progressBar = new JProgressBar();
progressBar.setStringPainted(true);
add(progressBar, BorderLayout.SOUTH);
// The worker parameters
String word = "hello";
File[] documents = {new File("Application.java"),
new File("Informable.java"),
new File("SearchForWordWorker.java")};
// The worker
SearchForWordWorker worker =
new SearchForWordWorker(word, documents, informable){
// This method is invoked when the worker is finished
// its task
@Override
protected void done(){
try {
// Get the number of matches. Note that the
// method get will throw any exception thrown
// during the execution of the worker.
int matches = get();
label.setText("Found: "+matches);
textArea.append("Done\n");
textArea.append("Matches Found: "+matches+"\n");
progressBar.setVisible(false);
}catch(Exception e){
JOptionPane.showMessageDialog(Application.this,
"Error", "Search",
JOptionPane.ERROR_MESSAGE);
}
}
};
// A property listener used to update the progress bar
PropertyChangeListener listener =
new PropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event) {
if ("progress".equals(event.getPropertyName())) {
progressBar.setValue( (Integer)event.getNewValue() );
}
}
};
worker.addPropertyChangeListener(listener);
// Start the worker. Note that control is
// returned immediately
worker.execute();
}
// The main method
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
Application app = new Application();
app.initComponents();
app.setDefaultCloseOperation(EXIT_ON_CLOSE);
app.pack();
app.setVisible(true);
}
});
}
}
</code>
</pre><p>The above example builds the application and kicks off the worker. The worker updates the application through the <em>Informable</em> instance. While the worker is performing it task, the application can carry on doing other things (event listening and painting) without hanging. </p><h3>Cancel the Worker</h3><p>Can we cancel the task? Yes. The worker can be stopped or better cancelled. The worker provides a method called cancel which accepts a parameter of type <em>boolean</em>. This parameter determines whether or not the worker should be waked up should it be found sleeping. </p><pre><code>
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import javax.swing.*;
public class Application extends JFrame {
private JLabel label;
private JProgressBar progressBar;
private JTextArea textArea;
private JButton button;
private SearchForWordWorker worker;
private void initComponents(){
// The interface will update the text of the UI components
Informable informable = new Informable(){
@Override
public void messageChanged(String message){
label.setText(message);
textArea.append(message + "\n");
}
};
// The UI components
label = new JLabel("");
add(label, BorderLayout.NORTH);
textArea = new JTextArea(5, 30);
add(new JScrollPane(textArea), BorderLayout.CENTER);
// The cancel button
button = new JButton("STOP");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Cancel the worker and wake it up should it be sleeping
worker.cancel(true);
}
});
add(button, BorderLayout.EAST);
progressBar = new JProgressBar();
progressBar.setStringPainted(true);
add(progressBar, BorderLayout.SOUTH);
// The worker parameters
String word = "hello";
File[] documents = {new File("Application.java"),
new File("Informable.java"),
new File("SearchForWordWorker.java")};
// The worker
worker = new SearchForWordWorker(word, documents, informable){
@Override
protected void done(){
try {
int matches = get();
label.setText("Found: "+matches);
textArea.append("Done\n");
textArea.append("Matches Found: "+matches+"\n");
progressBar.setVisible(false);
}catch(Exception e){
JOptionPane.showMessageDialog(Application.this,
"Error", "Search",
JOptionPane.ERROR_MESSAGE);
}
}
};
// A property listener used to update the progress bar
PropertyChangeListener listener =
new PropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event) {
if ("progress".equals(event.getPropertyName())) {
progressBar.setValue( (Integer)event.getNewValue() );
}
}
};
worker.addPropertyChangeListener(listener);
// Start the worker. Note that control is
// returned immediately
worker.execute();
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
Application app = new Application();
app.initComponents();
app.setDefaultCloseOperation(EXIT_ON_CLOSE);
app.pack();
app.setVisible(true);
}
});
}
}
</code>
</pre><p>This will cause the worker's <em>get</em> method to throw the exception <a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/CancellationException.html">CancellationException</a> to indicate that the worker was forced cancellation. </p><h3>Conclusion</h3><p>One thing to take from this article is: when possible do not refer to UI components directly from the worker. The worker is better viewed as the subject of the <a href="http://java.sun.com/developer/JDCTechTips/2006/tt0113.html#2">observer pattern</a>. Provide an interface which the worker will use to communicate with its owner (application). </p>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com23tag:blogger.com,1999:blog-6929422799523574458.post-20472797001890784342008-09-01T11:35:00.025+02:002008-09-04T11:38:02.575+02:00Automatic logon on Intranet Sites from Java Web Application<p>
We can have Microsoft Internet Explorer providing information of the current logged in user when accessing <strong>intranet sites</strong>. Then we can use <a href="http://msdn.microsoft.com/en-us/library/aa378749.aspx" target="_blank">NTLM</a> to retrieve such information as discussed in this article.
</p>
<p>
Note that <a href="http://web.mit.edu/Kerberos/" target="_blank">Kerberos</a> is more secure than NTLM.
</p>
<h2>Configure Internet Explorer for Windows Native Authentication</h2>
<p>
The following article is an abstract from: <a href="http://download.oracle.com/docs/cd/B28196_01/idmanage.1014/b15995/odip_actdir.htm#i1010999" target="_blank">http://download.oracle.com/docs/cd/B28196_01/idmanage.1014/b15995/odip_actdir.htm#i1010999</a>
</p>
<p>
Configure Internet Explorer to use Windows Native Authentication. How you do this depends on which version you have.
</p>
<ul>
<li>Internet Explorer 5.0 and Later</li>
<li>Internet Explorer 6.0 Only</li>
</ul>
<h3>Internet Explorer 5.0 and Later</h3>
<p>
To configure Internet Explorer 5.0 and later, perform the following steps:
</p>
<ol>
<li>From the menu bar, select Tools, then, from the Tools menu, select Internet Options.</li>
<li>In the Internet Options dialog box, select the Security tab.</li>
<li>On the Security tab page, select Local Intranet, then select Sites.</li>
<li>In the Local intranet dialog box, select Include all sites that bypass the proxy server; then click Advanced.</li>
<li>In the advanced version of the Local intranet dialog box, enter the URL of the middle tier server.</li>
<li>Click OK to exit the Local intranet dialog boxes.</li>
<li>In the Internet Options dialog box, select the Security tab; then choose Local intranet; then choose Custom Level.</li>
<li>In the Security Settings dialog box, scroll down to the User Authentication section and then select Automatic logon only in Intranet zone.</li>
<li>Click OK to exit the Security Settings dialog box.</li>
</ol>
<h3>Internet Explorer 6.0 Only</h3>
<p>
If you are using Internet Explorer 6.0, perform the above steps in "Internet Explorer 5.0 and Later" then perform the following steps:
</p>
<ol>
<li>From the menu bar, select Tools, then, from the Tools menu, select Internet Options.</li>
<li>In the Internet Options dialog box, select the Advanced tab.</li>
<li>On the Advanced tab page, scroll down to the Security section.</li>
<li>Select Enable Integrated Windows Authentication (requires restart).</li>
</ol>
<p>
The above setting can be applied using Group Policy Objects. Please refer to: <a href="http://support.microsoft.com/kb/274846" taget="_blank">http://support.microsoft.com/kb/274846</a> for further information about this.
</p>
<h2>Retrieve username from Java Servlet</h2>
<p>
The following code is also available at: <a href="http://www.rgagnon.com/javadetails/java-0441.html" target="_blank">http://www.rgagnon.com/javadetails/java-0441.html</a>
</p>
<p>
The method <code>doIt</code> (within a Servlet) gets the authorisation from the request header if it is available.
</p>
<pre>
<code>
protected void doIt(HttpServletRequest request,
HttpServletResponse response) throws IOException {
String auth = request.getHeader("Authorization");
if (auth == null) {
response.setStatus(response.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
response.flushBuffer();
return;
}
if (auth.startsWith("NTLM ")) {
byte[] msg =
new sun.misc.BASE64Decoder()
.decodeBuffer(auth.substring(5));
int off = 0, length, offset;
if (msg[8] == 1) {
byte z = 0;
byte[] msg1 =
{ (byte)'N', (byte)'T', (byte)'L', (byte)'M', (byte)'S',
(byte)'S', (byte)'P', z, (byte)2, z, z, z, z, z, z, z,
(byte)40, z, z, z, (byte)1, (byte)130, z, z, z, (byte)2,
(byte)2, (byte)2, z, z, z, z, z, z, z, z, z, z, z, z };
response.setHeader("WWW-Authenticate",
"NTLM "
+ new sun.misc.BASE64Encoder().encodeBuffer(msg1));
response.sendError(response.SC_UNAUTHORIZED);
return;
} else if (msg[8] == 3) {
off = 30;
length = msg[off + 17] * 256 + msg[off + 16];
offset = msg[off + 19] * 256 + msg[off + 18];
String remoteHost = new String(msg, offset, length);
length = msg[off + 1] * 256 + msg[off];
offset = msg[off + 3] * 256 + msg[off + 2];
String domain = new String(msg, offset, length);
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
String username = new String(msg, offset, length);
PrintWriter out = response.getWriter();
out.println("Username: " + username);
out.println("RemoteHost: " + remoteHost);
out.println("Domain: " + domain);
}
}
}
</code>
</pre>Anonymoushttp://www.blogger.com/profile/05001967782991767837noreply@blogger.com0