<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Richard Bair&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/" />
<modified>2007-11-06T14:58:36Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/rbair/231</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2007, rbair</copyright>
<entry>
<title>Leaving For Dublin</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/11/leaving_for_dub.html" />
<modified>2007-11-06T14:58:36Z</modified>
<issued>2007-11-06T14:58:29Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.8578</id>
<created>2007-11-06T14:58:29Z</created>
<summary type="text/plain">Luan O&apos;Carroll was gracious enough to invite me to speak at the Irish Java Technology Conference this week in Dublin. Whooorah!</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>Luan O'Carroll was gracious enough to invite me to speak at the Irish Java Technology Conference this week in Dublin. For those who will be attending, I've got <b>quite</b> a bit of news from the desktop team which I think you'll be quite interested in hearing. I'm speaking Thursday morning ("Swinging RIAs" talk) and also Friday morning.</p>

<p>Friday morning I'll be giving Chet's and Romain's "Filthy Rich Clients" talk, which is always a barn burner. It's also, in my opinion, really important material that is both fun and interesting. If you are in the area, stop by!</p>

<p>And if you aren't in the area, I suggest getting a plane ticket and meeting up in Dublin :-)</p>]]>

</content>
</entry>
<entry>
<title>Nimbus Bugs</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/10/nimbus_bugs.html" />
<modified>2007-10-02T16:18:53Z</modified>
<issued>2007-10-02T16:18:34Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.8355</id>
<created>2007-10-02T16:18:34Z</created>
<summary type="text/plain">Recently, the Nimbus L&amp;F became available with the early access builds of Java 6 update 5. We have some folks try it out, but not know where to file bugs. Ok. So this is going to be a boring blog, but I wanted to get the word out on how to help us debug Nimbus.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>So you want to file a bug against Nimbus? First, thank you very much! Jasper and I want Nimbus to be rock solid, and welcome all the bug reports we can get.</p>

<p>Bugs are filed in the same way as all other bugs in Swing: via bugs.sun.com. You can use <a href="http://bugs.sun.com/bugdatabase/search.do?process=1&category=java&bugStatus=&subcategory=classes_swing&type=&keyword=Nimbus">this link</a> to  view current bugs. As you will see, all Nimbus bugs are prefixed either with Nimbus LAF or Nimbus L&F. Please continue this naming convention, as it helps us locate which bugs belong to Nimbus.</p>

<p>That's really all there is to it!</p>]]>

</content>
</entry>
<entry>
<title>App Framework JavaPolis Talk Online</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/05/app_framework_j.html" />
<modified>2007-05-22T18:53:14Z</modified>
<issued>2007-05-22T18:53:07Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.7477</id>
<created>2007-05-22T18:53:07Z</created>
<summary type="text/plain">Hans Muller&apos;s App Framework talk from this past JavaPolis is now online at http://parleys.com</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[Short blog, but be sure to check out Hans Muller's talk from this past JavaPolis on the Swing Application Framework JSR (JSR 296). 

It is hosted over at <a href="http://www.bejug.org/confluenceBeJUG/display/PARLEYS/JSR-296+Swing+Application+Framework?showComments=true">Parleys.com</a>.]]>

</content>
</entry>
<entry>
<title>Remi&apos;s Property Proposal</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/01/remis_property.html" />
<modified>2007-01-24T17:39:36Z</modified>
<issued>2007-01-24T17:39:29Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.6400</id>
<created>2007-01-24T17:39:29Z</created>
<summary type="text/plain">For those of use who&apos;d like to see Properties in the language, things are starting to get interesting. Remi Forax recently spelled out a more complete proposal, which I tend to like. Quite a bit. With a few tweaks.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>This is going to be a short one. To begin, be sure to read <a href="http://weblogs.java.net/blog/forax/archive/2007/01/property_reload.html">Remi Forax's blog</a> about his refined property proposal. Read it? Good.</p>

<p>I think Remi is really on the right track, and I can't wait to get the next build of his javac compiler to play with it. In the week or so since I last blogged on properties, I've had a chance to consider and reconsider a bunch of alternatives. I came up with the same basic set of criteria that Remi has. But there are a couple things in his proposal that I'd tweak.</p>

<p>In my last entry, I made the case for needing the property feature to support auto-generating getters/setters so that current frameworks that rely on the JavaBeans spec continue to work with the new properties. Frameworks such as JSR 295 (beans binding), Spring, JPA, etc. jhook pointed out that we actually don't need to do this: as long as the java.beans.Introspector can read the new Property information in the class file, then frameworks would continue to work perfectly, without the need of introducing auto-generated getters/setters.</p>

<p>After thinking about it more, I am not in favor of auto generated getters and setters. It just feels wrong. You can read the source file and there will be no method "setFoo". Yet in another source file, there you are, calling "setFoo"! Called me old fashioned, call me over the hill. It just doesn't sit right.</p>

<p>Instead, I'm of the opinion that if properties are introduced in the language, they should be a clean implementation. Let the Introspector bridge the gap. And stick with Java's core language tenet: keep it readable!</p>

<p>This is why I really like Remi's proposal (which Joe Nuxoll also proposed at one point):
<pre><code>
    public property String foo; #read/write property
    public property String bar get; #readonly property
    public property String baz set; #writeonly property
    public property String wow get() {return bar;} set(String w) {bar = w;} #property with code
</code></pre></p>

<p>He then goes on to talk about how to access a properties value. Here I part ways with Remi for a bit. I still think the "." accessor is the best choice. Thus:
<pre><code>
    obj.foo = "Hello";
    String s = obj.foo;
</code></pre></p>

<p>One argument that has been made against the use of the "." notation is that it may have unintended side effects for the person making the call. Yes, it may. But then again, <code>obj.setFoo("Hello")</code> may have unintended side effects. If properties receive special attention in the javadoc (as I'm sure they would), then I see the unintended-side-effect argument to be much weaker. Want to know if there is a side effect? Read the docs! When you read the source code or docs for the class that declares the property, it is very clear what is going on.</p>

<p>Remi, Stephen Colebourne, Evan, and others have talked about a Property Literals (aka Property References, etc) which I think is a really, really great thing to be thinking about. Here is my minor tweak to Remi's proposal: use "#" as the operator instead of the ".". We already use # in the javadocs, so it would be a natural and consistent use. For example:
<pre><code>
class Person {
    public property surname;
    public property givenName;
    
    /**
      * @return the #surname and #givenName, formatted
      */
    public String formatName(String msgFormatPattern) { ... }
}

...

String s = person.surname; //yields the value of the surname property
Property p = person#surname; //returns the Property object for the surname property
p = Person#surname; //also returns the Property object for the surname property
Method m = Person#formatName(String); //holy toledo! Returns a Method object!
</code></pre></p>

<p>As you can see, there are some benefits to introducing a new operator for this task. # to me, makes a lot of sense.</p>

<p>That's it for now. I hope to be able to chew on this problem a bit more. </p>]]>

</content>
</entry>
<entry>
<title>Properties in Java? Hoorah!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/01/properties_in_j.html" />
<modified>2007-01-08T22:09:46Z</modified>
<issued>2007-01-08T22:09:41Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.6283</id>
<created>2007-01-08T22:09:41Z</created>
<summary type="text/plain">Properties in Java? Awesome! As with any new language feature, there has been a lot of debate over whether this is an improvement to the language, or a detriment. And of course, every language-designer-wannabe (myself included!) is pounding the pulpit, declaring the One True Way to Property bliss. Well, sit back and enjoy as I pound the pulpit. Because seriously, I really do have the right solution! I promise!</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>Properties in Java? Awesome! As with any new language feature, there has been a lot of debate over whether this is an improvement to the language, or a detriment. And of course, every language-designer-wannabe (myself included!) is pounding the pulpit, declaring the One True Way to Property bliss. Well, sit back and enjoy as I pound the pulpit. Because seriously, I really do have the right solution! I promise!</p>

<h2>A Brief Overview of JavaBeans</h2>
<p>The JavaBeans spec has been with us for quite a while. Virtually everybody knows about the JavaBeans POJO pattern:

<pre><code>
public class Person {
    private String surname;
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
}
</code></pre></p>

<p>Before throwing any monkey wrenches into the works, I'm going to explain a bit about some of the darker corners of the JavaBeans spec. At least, darker to the majority of developers out there.</p>

<p>Many of you are probably familiar with the Reflection APIs. For example, given the class above, I could call the "getSurname()" method using Reflection like so:
<pre><code>
    Method m = Person.class.getMethod("getSurname");
    String surname = (String)m.invoke(personInstance);
</code></pre></p>

<p>Built above these core APIs is the JavaBeans Introspector, BeanInfo, PropertyDescriptor, and associated classes. These classes inspect an Object for methods that follow the JavaBean pattern, and create various descriptors automatically representing these "properties". You can even write your own PropertyDescriptors, or specify your own BeanInfos, if you don't want them to be automatically generated. Here's an example which get's all the properties for a bean and prints the name of the property and its value to System.out:
<pre><code>
    BeanInfo info = Introspector.getBeanInfo(Person.class);
    for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
        String name = pd.getName();
        Method m = pd.getReadMethod();
        if (m != null) {
            System.out.println(name + "=" + m.invoke(personInstance));
        }
    }
</code></pre></p>

<p>The java.beans package is <strong>widely</strong> used by frameworks and GUI builders. Swing is a huge user of the Bean APIs and patterns. JSR 295 (beans binding) is based on these APIs as well.</p>]]>
<![CDATA[<p>There are a couple other important things to note. First, the class could be defined like this:
<pre><code>
public class Person {
    public String getSurname() {
        return "<Unnamed>";
    }
}
</code></pre></p>

<p>and it is <em>still</em> a valid JavaBean. The "surname" property still exists (it is just read only), and the Introspector still finds it. Even though there is no instance variable (aka field) called "surname". The JavaBeans pattern is <strong>not</strong> about breaking the encapsulation of the Person object. It is about exposing configurable state. JSR 273 will (if nothing major changes) introduce the ability to configure beans that are immutable (ie: only have getter methods, and accept all state in the constructor). So I repeat, the JavaBeans pattern is not about breaking encapsulation.</p>

<p>This is important for a couple of reasons. First, for the purists out there, you can stop wringing your hands. Second, there is a big difference between a property, and a field. A Property is a concept, a field is an implementation. When discussing language level property support, don't confuse the two!</p>

<h2>Ground Rules</h2>
<p>Any discussion centered around Property support has to first establish the ground rules: what are the requirements. Here are my requirements (pounding the pulpit as I say them):
<ol>
    <li>Any proposal <strong>must</strong> be backwards compatible with the existing JavaBeans spec!</li>
    <li>Leverage existing APIs and existing patterns where possible</li>
    <li>Introduce as little as possible to get the job done</li>
</ol></p>

<p>The rest is all personal taste and other such nonsense :-).</p>

<h2>The One True Way</h2>
<p>Both <a href="http://weblogs.java.net/blog/forax/archive/2007/01/a_property_prop_1.html">Remi Forax</a> and <a href="http://weblogs.java.net/blog/cayhorstmann/archive/2007/01/arrows_in_the_b.html">Cay Horstmann</a> and <a href="http://www.javalobby.org/java/forums/t88090.html?start=0">Mikael Grev</a> are on the right track. Each of those blogs has interesting ideas, and even more interesting commentary. Be sure to check those out.</p>

<p>The One True Way is not necessarily the way I'd do it if I were starting from a clean slate, but it is the best solution for Java. All design requires trade offs.Without further ado...</p>

<h3>Getter/Setter == Accessor/Mutator</h3>

<p>The first key design decision is to continue to support getter/setters as the way to customize the accessor/mutator for the property. C# uses a closure-like syntax for defining the accessor/mutator, but this would be the wrong decision for Java because it doesn't add anything truly useful beyond what the getter/setter already provide. Plus, as Remi points out, it limits your ability to use covariant return types or to override the argument to the setter.</p>

<p>Obviously, we can't ignore the last 10 years of Java code. Getter/Setter has to be supported.</p>

<h3>PropertyDescriptor == Property Meta Data</h3>

<p>The JavaBeans spec defines the PropertyDescriptor as the metadata for a Property. <a href="http://www.jroller.com/page/scolebourne/20070108">Stephen Colebourne</a> has an interesting idea regarding exposing Property meta information easily. He has some interesting points, but it is critical that we leverage the existing APIs and the existing body of work that uses PropertyDescriptor. However, we really, really, should make it easier to get a PropertyDescriptor.</p>

<p>For example, Stephen suggests the "->" notation (which has been suggested for other uses with regards to properties, so don't get confused!). Basically, <code>foo.bar</code> would return the value of the bar property, while <code>foo->bar</code> would yield the PropertyDescriptor. I'm not fond of the use of the "->" operator for this task, but something along these lines may be the best choice.</p>

<h3>Observable Properties</h3>

<p>The JavaBeans specification mentions "bound properties", or in other words, observable properties. Whenever a "bound" property changes, a PropertyChangeEvent is fired to all registered PropertyChangeListeners. They may then take the correct action.</p>

<p>This is a huge deal for JSR 295 (bean binding). Using my previous code example, imagine if I bound the Person.surname property to a JLabel. Whenever the surname property changes, I want to update the label. If the surname property is not observable, then the JLabel will not be automatically notified when the property changes. Which means you'd have to be sure to manually refresh the JLabel whenever the surname changes. Lame!</p>

<p>Writing a setter method to fire a PropertyChangeEvent isn't too hard, but it is trickier than you might think! Here's a broken example:
<pre><code>
    public void setSurname(String surname) {
        if (surname == null) surname = "";
        String old = this.surname;
        this.surname = surname;
        firePropertyChange("surname", old, surname);
    }
    public String getSurname() {
        return surname;
    }

    ...

    final Person p = ...;
    p.setSurname("Bair");
    p.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            assert p.getSurname().equals(evt.getNewValue());
        }
     }
</code></pre></p>

<p>What is wrong with this example? Will the assert always succeed? Answer, no. It may fail. How? Simple: because getSurname() is not final, it is possible for a subclass to be written such that it always returns a single value, essentially becoming read only. That is:
<pre><code>
    public class SmithPerson extends Person {
        public String getSurname() { return "Smith"; }
    }

    ...

    final Person p = new SmithPerson();
    p.setSurname("Bair"); // set surname sets the field to be "Bair", fires a PCE
    p.addPropertyChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            //evt.getNewValue() returns "Bair", but p.getSurname() returns "Smith"!
            assert p.getSurname().equals(evt.getNewValue());
        }
     }
</code></pre></p>

<p>A more correct version of the setSurname() method would be
<pre><code>
    public void setSurname(String surname) {
        if (surname == null) surname = "";
        String old = getSurname(); // note: calling the getter!
        this.surname = surname;
        firePropertyChange("surname", old, getSurname()); // still calling the getter!
    }
</code></pre></p>

<p>Or, just make the getter final.</p>

<p>The point is, writing an observable setter has some gotchas. It's boring. It's a bunch of boilerplate. It is necessary for really slick (and useful and powerful) data binding. This has to be easier to do! Any talk about including properties in the language <strong>must</strong> include a provision for dealing with observable properties.</p>

<p>Note that the JavaBeans spec also discusses vetoable property change events, but those are, in my estimation, less critical to handle at this level. At least, whatever mechanism is introduced for observable properties should be capable of extension towards vetoable properties.</p>

<h3>Code Generation Rules</h3>

<p>Actually, I have reservations on this point, but they are outweighed by practicality. That is, however a property is defined it must actually generate the getter/setter method in the end, so as to be compatible with the JavaBeans spec. However, this is kinda weird. I mean, you define a property, and then call a method "getSurname()". Where was that method defined? "Oh, the compiler creates it for you". I mean, that's just plain freaky.</p>

<p>However, it is the most practical choice at the moment, in my estimation.</p>

<p>Code generation is the means by which we ensure that properties work with existing frameworks and code. A piece of code calling <code>Introspector.getBeanInfo</code> should work exactly the same whether it is introspecting a class defined pre 1.7 or a class defined with properties.</p>

<h2>Things To Postpone</h2>

<p>One really intriguing idea is to also introduce a way to chain accessors, such that if a null occurs anywhere in the chain, the result is a null. For example, <code>a.getB().getC()</code> would return <code>null</code> instead of throwing a NullPointerException if a.getB() returned null. Some syntax changes have been suggested (such as using a # instead of . to access the property). Very interesting idea, could save a lot of boilerplate, but this is orthogonal to the properties discussion. At least, I hope it is. The death of many a great idea has come about due to too many great ideas being lumped together.</p>

<h2>The End of Today's Blog</h2>

<p>So, I haven't actually proposed any syntax of any kind. Rather, I'm trying to focus on, and nail down, the core requirements for language level properties, from my perspective. In this discussion, I'm not acting as the official Sun representative for Properties in the language. I'm just an interested bystander. So look to other blogs for official feedback, direction, etc etc.</p>]]>
</content>
</entry>
<entry>
<title>Five Little Things</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2007/01/five_little_thi.html" />
<modified>2007-01-03T01:09:57Z</modified>
<issued>2007-01-03T01:09:53Z</issued>
<id>tag:weblogs.java.net,2007:/blog/rbair/231.6240</id>
<created>2007-01-03T01:09:53Z</created>
<summary type="text/plain">Romain Guy tagged me. Now I have to share 5 little known facts about myself.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>I was just catching up with my emails, and all those blogs, and noticed that <a href="http://www.jroller.com/page/gfx?entry=five_little_things">my friend Romain Guy</a> tagged me. Now I gotta share 5 little know facts about myself. With no attempt at cleverness:</p>

<ul>
    <li>I dated my wife for 6 weeks before we got engaged. 1 month later we were married. 1 month later we were expecting our first :-)</li>
    <li>I spent 2 years in Atlanta Georgia (and thereabouts) as a missionary, including 6 months in the inner city. Living and working in the inner city was a really great experience</li>
    <li>The scar on my face has been with me since I was 10 months old. I fell on broken glass. I had been walking since I was 8 months old. Must have scared my mom to death</li>
    <li>(American) football is my favorite sport. I love the strategy, the athletics, and the sheer willpower needed to succeed. Too bad the college season has (almost) come to a close. Hoorah for Boise State! Hoorah for all the underdogs!</li>
    <li>When I was about 8 I was run over by a <a href="http://www.cat.com/cda/layout?m=37840&x=7&location=drop">caterpillar tractor</a>. Luckily, it only got my leg. Even more luckily, it didn't even break my leg. Hurray for soft dirt!</li>
</ul>

<p>Well, I'm going to go ahead and tag <a href="http://weblogs.java.net/blog/campbell/">Chris Campbell</a>, <a href="http://weblogs.java.net/blog/javaben/">Ben Galbraith</a>, and <a href="http://weblogs.java.net/blog/enicholas/">Ethan Nichols</a>. No tagbacks!</p>]]>

</content>
</entry>
<entry>
<title>SSL and Self Signed Certs</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/10/ssl_and_self_si_1.html" />
<modified>2006-10-24T22:37:08Z</modified>
<issued>2006-10-24T22:37:01Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5785</id>
<created>2006-10-24T22:37:01Z</created>
<summary type="text/plain">Connecting to web servers over https that have self signed certificates has always been a hassle in Swing applications. Hopefully, with some recently added code and API in the SwingX-WS project this is no longer the case. I don&apos;t know...</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>Connecting to web servers over https that have self signed certificates has always been a hassle in Swing applications. Hopefully, with some recently added code and API in the <a href="http://swingx-ws.dev.java.net">SwingX-WS</a> project this is no longer the case.</p>

<p>I don't know about you, but I don't have the $$ to shell out for a real certificate for my own home-run webserver. That, or I'm too lazy to do it, I'm not sure which. But in either case, test servers are often setup that don't have a real SSL certificate, such as Verisign or Thawte might sell. Instead, they have self-signed certificates. Glassfish, for instance, has such a certificate. It is easy enough to enable SSL in Glassfish, but expensive to use a real certificate.</p>

<p>Web browsers typically don't have a problem connecting to web servers that have self-signed certs. At least, Safari doesn't complain. It simply shows a dialog indicating that the domain the browser is connecting to has a self signed cert, and asks the user whether they want to continue. Nice.</p>

<p>Java, on the other hand, by default won't deal with self-signed certs. Period. You also get a very unfriendly error:
<pre>
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed
</pre></p>

<p>It turns out, you need to write your own X509TrustManager, and this is well documented. Just such a pain that I suspect most folks simply use http and hope they don't get into trouble (or just use http since they are on internal networks).</p>

<p>SwingX-WS uses HttpClient behind the scenes for all work with HTTP, and as it turns out, HttpClient has support for installing new secure socket factories -- which is a good thing because I'm gonna need one of those guys in order to use my X509TrustManager. [note: An X509TrustManager can be made the default VM-wide, but you need security rights. The other approach is to install the X509TrustManager on each HttpConnection, which does not require any extra priviledges. I use this approach so I don't have problems with webstart].</p>

<p>Enough theory, here's the practice.:
<pre><code>
    Session s = new Session();
    Response r = s.get("https://myselfsigneddomain.com");
</code></pre></p>

<p>This code sample works exactly like Safari (and I assume the other browsers). It encounters a valid self signed cert and instead of bombing with an esoteric error message, it prompts the user. Cool!</p>

<p>Session now sports a couple new properties that help in this process:
<ul>
    <li>sslSecurityLevel: Can be one of SecurityLevel.High, SecurityLevel.Medium, or SecurityLevel.Low. High security will act the same as Java has always acted -- simply fail if a valid certificate doesn't exist (self-signed won't work here!). Medium security is the default, and this level will prompt the user. Low security won't prompt the user if it encounters a self-signed cert, it will simply accept it. <strong>Do not use the Low security level in production applications. You will expose yourself to security vulnerabilities!</strong></li>
    <li>mediumSecurityHandler: Allows you to specify a SecurityHandler. SecurityHandler is an interface with one method: <code>public boolean isServerSecure(String host, X509Certificate cert);</code>. This allows you to customize the way you ask the user whether a self-signed cert should be accepted or not.</li>
</ul></p>

<p>And that's it. So, go to and write a bunch of web-oriented secure Swing applications!</p>

<p>PS: Hopefully this all actually works :-). I've tested it, but sure has some bugs. Among which include internationalization. If anybody wants to submit patches, let me know!</p>]]>

</content>
</entry>
<entry>
<title>XMLHttpRequest and Swing</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/08/xmlhttprequest_1.html" />
<modified>2007-01-04T19:08:53Z</modified>
<issued>2006-09-01T01:01:38Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5472</id>
<created>2006-09-01T01:01:38Z</created>
<summary type="text/plain">Say that again? XMLHttpRequest and Swing? Yep, you heard me right. Yesterday and today I&apos;ve been experimenting with implementing a version of the esteemed XMLHttpRequest (from the Ajax world, of course!) for use with Swing apps. Actually, today&apos;s blog goes a lot futher that simply XMLHttpRequest. It also traverses the little-explored corner of the country known as JSONandSwingland. Wow, it is a good thing I brought my hiking boots. And some spare water.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>For a while now (since well before we started the <a href="http://swingx-ws.dev.java.net">SwingX-WS</a> project) I've been interested in making Swing accessible to the hordes of web authors out there. This demographic is being actively persued by Adobe(Flex) and Microsoft. Web folks are doing more and more to enhance their web applications via AJAX in order to get closer to a rich client experience. At some point it makes sense to use a rich client toolkit -- and each of us (Flex/Flash, Avalon/XAML/WPF, and Swing) want to be the toolkit used. This space (called Rich Internet Application or Smart Clients) is, I believe, a real growth area.</p>

<p>Our job, on the Swing team, is to ensure that when a development team hits that inflection point and wants to write a rich client app, they can do so in Java with Swing with the minimum amount of fuss. It is in this vein that XMLHttpRequest -- the Java implementation -- came to be.</p>

<p>In SwingLabs and on the Swing team we've long been aware of the difficulties people face when trying to write responsive GUI apps due to the inherent difficulties in writing threaded apps. In the past I've blogged about <a href="http://swingworker.dev.java.net">SwingWorker</a> and <a href="http://weblogs.java.net/blog/rbair/archive/2006/06/swing_and_non_b.html">BackgroundWorker</a> -- two different approaches to this problem. Both of these are reasonable ways to simplify threading issues. The XMLHttpRequest code I'm introducing today also deals with threading issues -- but isn't as general purpose as SwingWorker or BackgroundWorker.</p>

<p>In this installment (I'm getting to the point, I promise!) I introduce the XMLHttpRequest and JSONHttpRequest beans, both part of the <a href="http://swingx-ws.dev.java.net">SwingX-WS</a> project. I based the design and implementation on the <a href="http://www.w3.org/TR/XMLHttpRequest/">W3C Working Draft Specification</a> for XMLHttpRequest. So the good news is, for those of you familiar with XHR, you have essentially the same API available now for your Swing apps.</p>

<p><strong>NOTE: The classes mentioned in this blog have been refactored into the org.jdesktop.http.async package of SwingX-WS. Also, the class HttpRequest has been renamed AsyncHttpRequest.</strong></p>

<p>Before I get into the mechanics of making the call (if you care, just scroll down to the examples below), I want to take a few bytes of bandwidth and describe the kind of applications that would care about XMLHttpRequest. If you have an application that makes calls to REST web services (either structured or ad hoc), you'd probably care. If you are writing a fairly lightweight application -- heavy on graphics and light on data objects -- that uses, say, <a href="http://aerith.dev.java.net">online photos</a>, you'd care. If you were an AJAX saavy developer who wanted to try your hand at a little Swing -- you'd care.</p>

<p>At the heart of the API is a class called <a href="https://swingx-ws.dev.java.net/source/browse/swingx-ws/src/java/org/jdesktop/swingx/html/HttpRequest.java?rev=1.2&view=markup">HttpRequest</a>. This little fella is really where all the fun is. It implements almost all of the API (all, in fact, except for getResponseXML) defined in the aforementioned W3C specification. <code>HttpRequest</code> is a concrete implementation, which can be used directly.</p>

<p>The general concepts are pretty simple to grasp. Here's a basic code sample:
<pre><code>
        final HttpRequest req = new HttpRequest();
        req.addOnReadyStateChangedListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getNewValue() == ReadyState.LOADED) {
                    String response = req.getResponseText();
                    //do what you like with the response here
                    //for example, if the XML was XMLDecoder
                    //compatible:
                    java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(
                        new ByteArrayInputStream(response.getBytes()));
                    Customer c = (Customer)decoder.readObject();
                    decoder.close();
                }
            }
        });
        try {
            req.open(HttpMethod.GET, new URL("http://MyCompany.com/someService?customer=\"A2342DAD\"/"));
            req.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
</code></pre></p>

<p>Those familiar with XMLHttpRequest will find this code to be really straitforward. In fact, the course grained API calls are all exactly the same:
<ol>
  <li>Create the HttpRequest object</li>
  <li>Attach an onreadystatechanged event listener</li>
  <li>Call "open", passing in the http method and URL</li>
  <li>Call "send"</li>
  <li>In the onReadyStateChanged event listener, listen for the ready state of LOADED.</li>
  <li>Do the stuff</li>
</ol></p>

<p>This basic mechanism could be used rather cleanly for all kinds of scenarios. In this example I use it as a mechanism for deserializing some Customer java bean. I could also have passed the <code>responseText</code> to a SAX/STAX/DOM parser. Or maybe the text is HTML and I wanted to display it in an <a href="https://xhtmlrenderer.dev.java.net/">XHTML renderer</a>. Maybe it was <a href="http://www.jaxxframework.org/wiki/Main_Page">JAXX</a> XML document, and represented some Swing widgets that should be created. Maybe it is some JavaScript code which, when used with JDK 6 and the scripting APIs could modify the Swing UI in some way. Perhaps it is JSON. Perhaps it is Java2D drawing code. Perhaps a serialized set of <a href="http://weblogs.java.net/blog/joshy/archive/2006/08/painter_trailer.html">Painters</a>. You get the drift.</p>

<p>In addition to getting data, <code>HttpRequest</code> can also be used to send data. Here is some simple code to do so:
<pre><code>
        req.open(HttpMethod.POST, new URL("http://MyCompany.com/submit?Customer=\"A2342DAD\""));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        java.beans.XMLEncoder e = new java.beans.XMLEncoder(out);
        e.writeObject(customer);
        e.flush();
        req.send(out.toString());
        out.close();
</code></pre></p>

<p>This example reverses the last -- it constructs XML representing this customer bean and, using HTTP POST, sends this data to the web server.</p>

<p>For convenience, I extended <code>HttpRequest</code> with <a href="https://swingx-ws.dev.java.net/source/browse/swingx-ws/src/java/org/jdesktop/swingx/html/XmlHttpRequest.java?rev=1.3&view=markup">XMLHttpRequest</a> and <a href="https://swingx-ws.dev.java.net/source/browse/swingx-ws/src/java/org/jdesktop/swingx/html/JsonHttpRequest.java?rev=1.1&view=markup">JSONHttpRequest</a>. <code>XMLHttpRequest simply adds the <code>getResponseXML</code> method to finish the XMLHttpRequest spec. This method returns a DOM object. Not always the most useful API to work with from within Java, but sometimes quite powerful when combined with XPath. A silly example:
<pre><code>
     Document dom = req.getResponseXML();
     XPath xpath = XPathFactory.newInstance().newXPath();
     try {
         XPathExpression exp = xpath.compile("//p");
         NodeList nodes = (NodeList)exp.evaluate(dom, XPathConstants.NODESET);
         for (int i=0; i&lt;nodes.getLength(); i++) { 
             System.out.println(nodes.item(i).getTextContent());
         }
     } catch (Exception e) {
         e.printStackTrace();
     }
</code></pre></p>

<p><a href="http://json.org">JSON</a> is another alternative. Not as expressive or structured as XML but much faster to parse and easy to work with loosey-goosey. <code>JSONHttpRequest</code> supplies two new methods: <code>getResponseJSON</code> which returns a JSONObject, and <code>getResponseMap</code> returning a Map<String,Object> -- essentially what JSON boils down too. Ok, one more example and I'm calling it quites for today:
<pre><code>
    public static void main(String[] args) {
        final JsonHttpRequest req = new JsonHttpRequest();
        req.addOnReadyStateChangedListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getNewValue() == ReadyState.LOADED) {
                    //extracting the data using JSON Java library
                    JSONObject json = req.getResponseJSON();
                    json = json.optJSONObject("ResultSet");
                    System.out.println("Total Results Avail.: " + json.optString("totalResultsAvailable"));
                    System.out.println("Results: ");
                    JSONArray results = json.optJSONArray("Result");
                    for (int i=0; i&lt;results.length(); i++) {
                        System.out.println("\tTitle: " + results.optJSONObject(i).optString("Title"));
                    }
                    
                    //extracting the data just using maps & arrays
                    Map map = (Map)req.getResponseMap().get("ResultSet");
                    System.out.println("Total Results Avail.: " + map.get("totalResultsAvailable"));
                    System.out.println("Results: ");
                    Object[] results2 = (Object[])map.get("Result");
                    for (int i=0; i&lt;results2.length; i++) {
                        Map m = (Map)results2[i];
                        System.out.println("\tTitle: " + m.get("Title"));
                    }
                }
            }
        });
        try {
            req.open(HttpMethod.GET, new URL("http://api.search.yahoo.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=JavaOne&output=json"));
            req.send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
</code></pre></p>

<p>I hope you found this interesting. Hopefully in a future installment I'll get to showing a real live Swing demo doing something useful, besides printing junk out to System.out. Romain? Come on buddy, give a brother a hand!</p>]]>

</content>
</entry>
<entry>
<title>Varargs Puzzler</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/08/varargs_puzzler.html" />
<modified>2006-08-11T18:24:02Z</modified>
<issued>2006-08-10T22:28:34Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5325</id>
<created>2006-08-10T22:28:34Z</created>
<summary type="text/plain">This probably isn&apos;t up to Click &apos;n&apos; Clack&apos;s standards, but here&apos;s a fun little Java 5 puzzler for a Thursday afternoon.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>J2SE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>This probably isn't up to Click 'n' Hack's standards, but here's a fun little Java 5 puzzler for a Thursday afternoon.</p>

<p><em><b>NOTE:</b> For those in the dark, Click and Hack are really Neal Gafter and Joshua Bloch. They have a little skit they do at conferences where they present java code puzzlers.</em></p>

<p>Alright, we've had Java 5 for a while now and have had a good chance to get up to date with our new language features. In this puzzler I've written a method that takes a vararg of Objects, counts them up, and returns how many elements there were. Here's the code:
<pre><code>
   private static int elementCount(Object... elements) {
     return elements == null ? 0 : elements.length;
   }

   public static void main(String... args) {
     System.out.println("null length array: " + elementCount(null));
     System.out.println("[a,b,c] length array: " + elementCount("a", "b", "c"));
   }
</code></pre></p>

<p>Pretty straight to the point. I have a method called <code>elementCount</code>, and it simply returns the length of the elements array, or 0 if the param is null. So what's wrong with it?</p>

<pre>
  a) Nothing at all! It works as expected!
  b) There is a compiler warning
  c) It fails to compile
  d) Both (a) and (b)
</pre>

<p>Ok, I'll give you a few minutes to look it over, read the Java Language Specification, try it out in your favorite <a href="http://netbeans.org">IDE</a>, etc. Done?</p>

<p>And the answer is..... d! In fact, there is a compiler warning on this line: <pre><code>
    //line of code
    System.out.println("null length array: " + elementCount(null));

    //compiler warning
    warning: non-varargs call of varargs method with inexact argument type for last parameter;
</code></pre></p>

<p>Besides this warning, though, the code executes properly. But since I don't really like compiler warnings, I go ahead and make the change. Here's the new code.
<pre><code>
   private static int elementCount(Object... elements) {
     return elements == null ? 0 : elements.length;
   }

   public static void main(String... args) {
     System.out.println("null length array: " + elementCount((Object)null));
     System.out.println("[a,b,c] length array: " + elementCount("a", "b", "c"));
   }
</code></pre></p>

<p>Alright, that took care of the warning! So what's wrong with it? Anything? Come on, no cheating, think about it!</p>

<pre>
  a) It runs, but prints out "[a,b,c] length array: 0"
  b) There is a compiler warning
  c) Perfecto!
  d) It runs, but prints out "null length array: 1"
</pre></p>

<p>Alright, you've had your chance. What is it?</p>
<br>
<br>
<br>
<p>That's right, "d" again. It turns out the problem is this statement: <code>elementCount((Object)null)</code>. The problem is that (Object)null tells the compiler to include a one element Object array where the first element is null. Instead, what we wanted to do was this <code>(Object[])null</code>! This is why we get the compiler warning, the compiler doesn't know if we want <code>null</code> to be an element in the vararg array or whether we want it to be the vararg array itself.</p>

<p>Tripped me up for a few minutes today, hope you enjoyed it.<p>

<p><em>Note: Updated to refer to "Click and Hack" instead of "Click and Clack" -- also fixed a typo in the description. Thanks for pointing these things out!</em></p>]]>

</content>
</entry>
<entry>
<title>A (Barely) Better Looking Yahoo! News Demo</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/07/a_barely_better.html" />
<modified>2006-07-11T02:27:59Z</modified>
<issued>2006-07-11T02:27:54Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5169</id>
<created>2006-07-11T02:27:54Z</created>
<summary type="text/plain">I was greeted this afternoon by a retching Hans Muller who begged me to upload a better looking demo for the Yahoo! News web service I posted about last time. He likened last week&apos;s entry to a fat man in a speedo. Yikes. Here&apos;s a barely better demo (pun intended).</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>I was greeted this afternoon by a retching Hans Muller who begged me to upload a better looking demo for the Yahoo! News web service I posted about last time. He likened last week's entry to a fat man in a speedo. Yikes. Here's a barely better demo (pun intended).</p>

<p>(Note: This one also uses Mustang. Get it <a href="http://mustang.dev.java.net">here!</a>).</p>

<p><a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo2/yahoo_news_demo2.jnlp">
<img border="0" src="http://java.sun.com/products/jfc/tsc/sightings/images/webstart.small.jpg" width="88" height="23"></a></p>

<p>As before, you can download<a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo2/YahooNewsDemo.java"> YahooNewsDemo.java</a>, as well as the <a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo2/demo.zip">source files and libs</a>.

<p>For the impatient:<br />
<img src="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo2/yahoo-demo.png" /><br />
and the relevant source code:
<pre><code>
    public YahooNewsDemo() {
        initComponents();
        results.setHighlighters(new HighlighterPipeline(new Highlighter[] {AlternateRowHighlighter.beige}));
    }

    ...

    private void workerProcess(org.jdesktop.swingx.event.BackgroundEvent evt) {                               
        results.setModel(new RssListModel((SyndFeed)evt.getData()[0]));
    }                              
    

    private static final class RssListModel extends AbstractListModel {
        private SyndFeed feed;
        private List entries;
        
        public RssListModel(SyndFeed feed) {
            this.feed = feed;
            entries = feed.getEntries();
        }

        public int getSize() {
            return entries.size();
        }

        public Object getElementAt(int i) {
            SyndEntry entry = (SyndEntry)entries.get(i);
            return entry.getTitle() + " (" + entry.getPublishedDate() + ")";
        }
    }
</code></pre>]]>

</content>
</entry>
<entry>
<title>Simple Yahoo! News Reader</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/06/simple_yahoo_ne_1.html" />
<modified>2006-06-30T23:52:25Z</modified>
<issued>2006-06-30T23:52:21Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5136</id>
<created>2006-06-30T23:52:21Z</created>
<summary type="text/plain">My last few blogs have been on using web services in Swing. This time I&apos;ve created a simple Yahoo! News RSS reader JavaBean you can use in your own apps. And yes, this time I went all the way and wrote a JNLP.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>My last few blogs have been on using web services in Swing. This time I've created a simple Yahoo! News RSS reader JavaBean you can use in your own apps. And yes, this time I went all the way and wrote a JNLP. But beware, it is only running on 1.6 for now. I didn't even know I was developing on 1.6 until I tested the deploy, and now I'm headed out on vacation.</p>

<p>Here's a screenshot, for those you can't or won't run the demo:<br />
<img src="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo/yahoo-demo.png" /></p>

<p>It is a very ugly demo. Again, vacation and all that. But, here's basically what it does. You enter the name of the feed you'd like to see in the combo box on the top. Or you can pick one of the predefined ones, its up to you. Then click the "Refresh" button. On a background thread (there ya go, vtech!) I get the feed results, parse them, and then back on the UI thread I load them into the JTextArea. The results are raw output from the ROME RSS reader which I use to do all the heavy lifting.</p>

<p><a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo/yahoo_news_demo.jnlp">
<img border="0" src="http://java.sun.com/products/jfc/tsc/sightings/images/webstart.small.jpg" width="88" height="23"></a></p>

<p>The point here isn't to show off some slick looking application -- its the work that went into creating it. Or the lack thereof. <a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo/YahooNewsDemo.java">Read the source code yourself.</a> You can also <a href="http://download.java.net/javadesktop/blogs/rbair/yahoo_news_demo/demo.zip">download the sources</a> and rebuild the project (but good luck getting it to load up in NetBeans. Sorry no time to make it pretty, vacation calls).</p>

<p>For the impatient, here's the source code boiled down. First, I created a YahooNews bean (well, after creating the UI). I then created a BackgroundWorker bean called "worker". I then filled in the BackgroundWorker's event handlers, and wrote an action listener for the "Refresh" button. Here's all the magic:
<pre><code>
    private void workerStarted(org.jdesktop.swingx.event.BackgroundEvent evt) {                               
        executeButton.setEnabled(false);
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    }                              

    private void workerProcess(org.jdesktop.swingx.event.BackgroundEvent evt) {                               
        textArea.setText("" + evt.getData()[0]);
    }                              

    private void workerDone(org.jdesktop.swingx.event.BackgroundEvent evt) {                            
        executeButton.setEnabled(true);
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }                           

    private void workerDoInBackground(org.jdesktop.swingx.event.BackgroundEvent evt) {                                      
        try {
            evt.getWorker().publish(yahooNews.readFeed());
        } catch (Exception e) {
            JOptionPane.showInternalMessageDialog(this, e, "Failed to show feed", JOptionPane.ERROR_MESSAGE);
        }
    }                                     

    private void executeButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
        yahooNews.setFeedName("" + feedNameBox.getSelectedItem());
        worker.execute();
    }                                             
</pre></code></p>]]>

</content>
</entry>
<entry>
<title>Aerith is free!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/06/aerith_is_free.html" />
<modified>2006-06-28T22:23:09Z</modified>
<issued>2006-06-28T22:00:23Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5117</id>
<created>2006-06-28T22:00:23Z</created>
<summary type="text/plain">The Aerith source code has been uploaded to aerith.dev.java.net. Check it!</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>The Aerith source code has just been released to the <a href="http://aerith.dev.java.net">aerith.dev.java.net project</a>. With this milestone I thought I'd just blog a bit about the backstory that went into Aerith. Hopefully, by the time you're done reading this, you won't stone us for some pretty hacked up code.</p>

<p>Aerith was a really fun project to work on. We sort of had an idea for what we wanted to do for JavaOne. We had a lot of fun doing the Joplin music player the year before and really wanted to get back up on stage this year with something even cooler. Romain had a lot of demos lying around. The client group had this sweet intro screen idea and Romain had already mocked up a UI that would form the basis of the Aerith look.</p>

<p>Every year James Gosling holds a kind of "tryouts" for keynote demos. We didn't know when those tryouts would be held, so we sent a few emails to find out. What we found was that we had about a week to get the demo finished before the tryouts. I was at home at the time and had to say goodbye to the wife and kid for the next few days.</p>

<p>Romain, Josh and I setup a war room in one of the conference rooms here on campus. As all good war rooms, ours was stocked with food, liquid nourishment (water for me, on a diet :-)), and pizza (so much for the diet). Oh, and chocolate cake. No "Romain" war room is complete without chocolate cake.</p>

<p>In three days of intense coding (Thursday, Friday, and Saturday. Usually about 18 hours+ each day) we wrote the entire map viewer and editor, and part of the applet. The original applet contained only the 3d "twinkle" code. (For those familiar with Romain's blog, Twinkle is one of the projects he released that we reused for this demo). With that, the demo was more or less feature complete. Later that week I added what we called the "Indiana Jones" viewer in the applet.  Otherwise, bugfixes occupied our time. And endless tweaks to get things up to Romains standards.</p>

<p>It was also a lot of fun to tryout for James' keynote and finally make it into Jeff Jackson's keynote on Tuesday morning. I always have a blast at JavaOne, and love getting up on stage. Even if I am boring to watch :-).</p>

<p>The moral of this story (if there is one, besides diet's and war rooms not getting along so well) is that a sizeable portion of the Aerith code is very, very raw. It wasn't written as a "best practices" application, or to be maintained. It has a lot of bugs, is difficult to setup, needs a better build script, and nobody knows how the 3d stuff works besides Romain.</p>

<p>It was written to show off what is possible with Swing/Java. It was written to demo well. And it was written because it was fun to do. I think in all three respects it was a home run. Especially the last one: it was a lot of fun.</p>

<p>I think there is a great deal of potential in Aerith as a consumer application. We're looking for individuals who want to move Aerith to the next level. I'd be stoked to see it deployed and working with real people's data in real world situations. That'd really make my day.</p>

<p>So, this makes 3 blogs in 3 days. If I keep this up, I'll have my yearly quota down by the end of the week!</p>]]>

</content>
</entry>
<entry>
<title>Swing and Non Blocking JAX-WS</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/06/swing_and_non_b.html" />
<modified>2006-06-28T00:13:12Z</modified>
<issued>2006-06-28T00:12:45Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5103</id>
<created>2006-06-28T00:12:45Z</created>
<summary type="text/plain">This is a follow up on yesterday&apos;s blog about using JAX-WS and Swing. Yesterday I was a bad, bad, boy. I was making a web service call from the Event Dispatch Thread. Doh! Today, I introduce BackgroundWorker, a SwingWorker like JavaBean and repent of my old EDT-blocking ways.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p><a href="http://weblogs.java.net/blog/rbair/archive/2006/06/swing_jaxws_and.html">Yesterday I blogged about JAX-WS</a> and how to use it with Swing. I tried to sneak by with a simple example that <i>happened</i> to block the EDT during the web service invocation (bad Richard! bad). Since I was called out on it, I took the opportunity to create a new JavaBean for working with background tasks and update my example to use it.</p>

<p>The problem with yesterday's example was this method:
<pre><code>
    private void generateButtonActionPerformed(java.awt.event.ActionEvent evt) {                                         
        randomNumbersWS.setCount((Integer)countSpinner.getValue());
        final List<Integer> results = randomNumbersWS.generateRandomNumbers();
        resultsList.setModel(new AbstractListModel() {
            public Object getElementAt(int index) {
                return results.get(index);
            }
            public int getSize() {
                return results.size();
            }
        });        
    }                                        
</code></pre></p>

<p>In this method I contact the webservice (a potentially lengthy process) while in the Event Dispatch Thread. In other words, while trying to contact the web service the entire GUI was frozen. Solid. Today we'll fix the problem by using a background thread.</p>

<p>For this task I created a new non visual JavaBean called BackgroundWorker. For those familiar with .NET, you'll notice the name. BackgroundWorker is a helper class that handles a lot of the threading work for you. BackgroundWorker is intended to be used in your GUI builder environment. To use it, you:
<ul>
    <li>simply drag and drop a BackgroundWorker from the development palette</li>
    <li>go to the property sheet and select the doInBackground event</li>
    <li>write the code for your background task. Call "process" on the
        BackgroundWorker to publish whatever data you want to in the GUI</li>
    <li>go to the property sheet and select the "publish" event</li>
    <li>display the data in the gui (the data is part of the BackgroundEvent)</li>
</ul></p>

<p>Those who've written multithreaded Swing code in the past have probably used SwingWorker. SwingWorker is an excellent piece of code, and handles a lot of the really sticky details for multithreading. BackgroundWorker, in fact, delegates to SwingWorker to do the actual multi-threading work. Why write BackroundWorker then? Well, when using a GUI builder, using a non visual component like BackgroundWorker can <i>really</i> be nice. I've found it much easier to "view" code visually in a GUI builder than to read and mentally visualize code.</p>

<p>Here's the new code, using a JXStatusBar and the BackgroundWorker. Oh, and by the way, I also implement the "started" and "done" events to make sure my GUI is properly disabled and re-enabled during this long process.
<pre><code>
    private void getNumbersWorkerPublish(org.jdesktop.swingx.event.BackgroundEvent evt) {                                         
        final List<Integer> results = (List<Integer>)evt.getData();
        resultsList.setModel(new AbstractListModel() {
            public Object getElementAt(int index) {
                return results.get(index);
            }
            public int getSize() {
                return results.size();
            }
        });        
    }                                        

    private void getNumbersWorkerDoInBackground(org.jdesktop.swingx.event.BackgroundEvent evt) {                                                
        //ok, go and get the numbers. Call process when done fetching the numbers
        randomNumbersWS.setCount((Integer)countSpinner.getValue());
        final List<Integer> results = randomNumbersWS.generateRandomNumbers();
        getNumbersWorker.process(results);
    }                                               

    private void getNumbersWorkerFinished(org.jdesktop.swingx.event.BackgroundEvent evt) {                                          
        //enable the button, update the status bar
        generateButton.setEnabled(true);
        statusLabel.setText("Ready");
    }                                         

    private void getNumbersWorkerStarted(org.jdesktop.swingx.event.BackgroundEvent evt) {                                         
        //disable the button, update the status bar
        generateButton.setEnabled(false);
        statusLabel.setText("Loading numbers from remote server...");
    }                                        

    private void generateButtonActionPerformed(java.awt.event.ActionEvent evt) {                                               
        getNumbersWorker.execute();
    }                                              
</code></pre></p>

<p>And here's the code for BackgroundWorker (I've omitted the event classes because they're boring :-). If there is enough interest, I'll push this code into SwingX).</p>

<p><pre><code>
/*
 * BackgroundWorker.java
 *
 * Created on June 27, 2006, 9:02 AM
 */

package org.jdesktop.swingx;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import org.jdesktop.swingx.event.BackgroundEvent;
import org.jdesktop.swingx.event.BackgroundListener;
import org.jdesktop.swingx.util.SwingWorker;

/**
 *
 * @author rbair
 */
public class BackgroundWorker extends JavaBean {
    private List<BackgroundListener> listeners = new ArrayList<BackgroundListener>();
    private SwingWorker delegate;
    
    /** Creates a new instance of BackgroundWorker */
    public BackgroundWorker() {
    }

    public void execute() {
        //if another task is already executing, fire and IllegalStateException
        if (delegate != null) {
            throw new IllegalStateException("A background task is already in progress");
        }
        
        //create a new delegate
        synchronized(this) {
            delegate = new DelegateWorker();
            fireStartedEvent();
            delegate.execute();
        }
    }
    
    public void process(Object... chunks) {
        for (Object data : chunks) {
            firePublishEvent(data);
        }
    }
    
    public void addBackgroundListener(BackgroundListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }
    
    public void removeBackgroundListener(BackgroundListener listener) {
        listeners.remove(listener);
    }
    
    public BackgroundListener[] getBackgroundListeners() {
        return listeners.toArray(new BackgroundListener[0]);
    }
    
    private void cleanup() {
        delegate = null;
    }
    
    private void fireStartedEvent() {
        BackgroundEvent evt = new BackgroundEvent(this);
        for (BackgroundListener listener : listeners) {
            listener.started(evt);
        }
    }
    
    private void fireDoneEvent() {
        BackgroundEvent evt = new BackgroundEvent(this);
        for (BackgroundListener listener : listeners) {
            listener.finished(evt);
        }
    }
    
    private void fireDoInBackgroundEvent() {
        BackgroundEvent evt = new BackgroundEvent(this);
        for (BackgroundListener listener : listeners) {
            listener.doInBackground(evt);
        }
    }
    
    private void firePublishEvent(Object data) {
        BackgroundEvent evt = new BackgroundEvent(BackgroundWorker.this, data);
        for (BackgroundListener listener : listeners) {
            listener.publish(evt);
        }
    }
    
    private final class DelegateWorker extends SwingWorker {
        protected Object doInBackground() throws Exception {
            fireDoInBackgroundEvent();
            return null;
        }

        protected void done() {
            cleanup();
            fireDoneEvent();
        }
    }
}
</code></pre></p>]]>

</content>
</entry>
<entry>
<title>Swing, JAX-WS, and JavaBeans</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/06/swing_jaxws_and.html" />
<modified>2006-06-27T01:10:20Z</modified>
<issued>2006-06-26T21:29:22Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.5100</id>
<created>2006-06-26T21:29:22Z</created>
<summary type="text/plain">JAX-WS can be a bit daunting, especially for the desktop developer. In this blog I show a simple web service, simple form, and how to use JavaBeans to tie it all together.</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>
<dc:subject>Community: JavaDesktop</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>On the <a href="http://forums.java.net/jive/thread.jspa?threadID=16377&tstart=0">SwingLabs Forums</a> we have been discussing Web Services and Swing. In particular, I want to start/retrofit a project on java.net where we can build both visual (like the <a href="http://download.java.net/javadesktop/blogs/rbair/swing_jaxws_javabeans/images/aerith_map.png">Aerith map viewer</a>) and non visual components. Some examples of non visual JavaBean components could include a Flickr bean, YahooSearch bean, YahooWeather bean, and so on.</p>

<p>During the discussion, Adam expressed some concern about focusing on potentially gimicky web services like Flickr at the expense of more mainstream services such as those that would be developed in house at your local enterprise.</p>

<p>I decided to take a shot at that situation and see what the development landscape looked like from the enterprise angle, especially when using the latest JEE 5 features. What I found was surprisingly easy, and very... uh... addicting.</p>

<p>There's no webstart demo, because I don't have a webserver ready to handle the server side tasks. I guess you'll just have to trust me that it works. Or better yet, try it yourself :-)</p>

<h2>Setup</h2>
<p>JAX-WS can be daunting. The most difficult aspect of it is the setup and configuation of the build environment. This will become a bit more clear as we go along. I've chosen to sidestep the whole issue and just try <a href="http://www.netbeans.info/downloads/download.php?type=5.5b">NetBeans 5.5 with the Enterprise development pack</a> This really made the setup process a lot easier for a lowly desktop guy like myself.</p>

<p>I went to the <a href="http://www.netbeans.info/downloads/download.php?type=5.5b">NetBeans 5.5 download area</a> and downloaded both the <b>NetBeans IDE 5.5 Beta Installer</b> and the <b>NetBeans Enterprise Pack 5.5 EA Installer</b>. I then downloaded and installed NetBeans 5.5, followed by the Enterprise Pack. I chose to install the SJAS 9 application server as part of the Enterprise Pack install. This was to make sure I had a Java EE 5 compatible server handy to test the new featuers. Note, I'm running on an Intel Mac with Mustang, and was surprised that everything *almost* worked. The only thing I had to do special was configure my netbeans.conf file to point to the JDK. This may have been because I've been messing with my JDK settings on MacOSX to get Mustang running.</p>

<p>Finally, after installing everything and starting NetBeans, I had to enter the Server Manager and configure SJAS 9 as a web server. This is important, because later when we create our web application a Java EE 5 compatible server needs to be available.</p>

<p>Now that I had everything installed and configured, I created two projects: Swing-WS-Website and Swing-WS. Swing-WS-Website is a normal NetBeans Web Application project type. The only special requirement was to make sure SJAS 9 was selected as the target server, and that JEE 5 is selected as the target.</p>

<p>The Swing-WS project was just a normal Java Application project type. Nothing special.</p>

<h2>Creating the Web Service</h2>
I chose a really simple and pointless web service as an example -- a random number generator. In NetBeans, I created a new Web Service. I altered the code to look like this:
<pre><code>
package org.jdesktop.swingws.services;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

/**
 *
 * @author rbair
 */
@WebService()
public class RandomNumbers {
    @WebMethod
    public List<Integer> generateRandomNumbers(Integer count) {
        Random rand = new Random(System.currentTimeMillis());
        List<Integer> results = new ArrayList<Integer>();
        for (int i=0; i&lt;count; i++) {
            results.add(rand.nextInt());
        }
        return results;
    }
}
</code></pre></p>

<p>There really isn't much to this code. I simply marked the RandomNumbers class with the @WebService annotation, and then marked the generateRandomNumbers method with the @WebMethod annotation. By creating this class with the NetBeans wizard, it made sure that the appropriate build configuration was done so that at this point, all I have to do is deploy.</p>

<p>In SJAS 9 I can test my web service by going to the admin site. By default this is installed at http://localhost:4848. I won't go into any more detail on this product. I've found it very easy to use, and you can find info on the net for it.</p>

<h2>Writing the Client</h2>
<p>Now that I knew my service was deployed and working, I was ready to write the client. First, I had to make the client project aware of the web service. When doing this by hand, this is where the nasty part is.</p>

<p>All SOAP web services (which is what NetBeans created and deployed for me) have a WSDL file. This file describes the service in a language neutral manner. The same WSDL can be used by .NET clients or Java clients, for instance. In Java EE 5, the wsimport command line program reads WSDL files and generates java source files. You can then call these Java classes from within your client.</p>

<p>I've tried doing all this by hand in the past and found it to be a huge pain.  Tool support makes this experience much, much better. In NetBeans, I opened the New File wizard and selected Web Service Client. I then pointed it at my RandomNumbers web service (note: in the IDE I didn't even have to deal with the WSDL directly, NB hid all this mess from me). NetBeans automatically called wsimport and created the source files for the web service for me.</p>

<p>The only problem I had was that I never saw these source files. Even though I'd specified a source package. As it turns out, NB 5.5 puts the source files in the "build" directory (which normally just contains class files). I guess they're trying to be clever and hide the sources from your source tree (no point cluttering it up). I'd have preferred that they generated a jar file and put it on my classpath, or at least told me what was going on. It took a while to figure out what was happening. Now that I know, it isn't so bad.</p>

<p>Once the web service was imported into the project, I wrote a quick main method to test it out:
<pre><code>
    public static void main(String[] args) {
        try {
            RandomNumbersService rns = new RandomNumbersService();
            System.out.println(rns.getRandomNumbersPort().generateRandomNumbers(250));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
</code></pre></p>

<p>Before running the sample I opened the SJAS admin webapp in my browser to check the logs and see what happened when the webservice was called. I then ran the client. Bingo. Worked perfectly.</p>

<p>So that's cool, but now how do I write a Swing application with this knowledge? Here's what I'd like it to look like (please Romain, don't laugh ;-))<br />
<img src="http://download.java.net/javadesktop/blogs/rbair/swing_jaxws_javabeans/images/client.png" /></p>

<p>&lt;SIDETRACK&gt;<br />Those familiar with me know that I'm <a href="http://weblogs.java.net/blog/rbair/archive/2006/05/the_unknown_jav.html">into JavaBeans</a>. For this exercise, imagine that you are the desktop guy tasked with writing applications as fast as your hot little hands can type. Wouldn't it be nice if the gal who wrote the webservice also provided a fancy little JavaBean you could use in the UI? The story goes something like this:</p>

<p>Sally is a server side super-engineer. She dreams in XML. Not just any XML, but we're talking namespace-declared, Schema-validated, fully robust XML. She's written a few web services to make available to the masses within her company. To help facilitate their work, she bundles the generated client stubs (generated by wsimport) along with a set of simple JavaBeans.</p>

<p>Clint is a client side desktop kind of guy. He has more work to do than time to do it. All departments in the company want him to write their apps because he gets them done fast, and they work pretty well. Clint needs to access Sally's web services. No problem. He gets her web service bundle (including the client side stubs and JavaBeans) and adds them to his project. He takes the JavaBeans and adds them to his Visual editor's palette. He then creates a new form, adds the WS JavaBeans to the palette, configures them (and the rest of the UI) in his editor, compiles, tests, and deploys. All as fast as his little hands can type... er, click, since he uses the visual designer as much as possible to simplify his life.</p>

<p>Funny enough, Wally the Web App guru also needs to write some clients. He also takes advantage of Sally's hard work and imports the JavaBeans into his JSF visual environment. Since I don't know enough about writing webapps, I'll stop the story here. Except to say that there is no fundemental difference between writing desktop and web applications when it comes to these simple JavaBeans.</p>

<p>Ok, enough of the somewhat silly story, but perhaps you can see a bit of the vision. So, how do we write these JavaBeans? For this example, it is really quite simple. Basically, my RandomNumbersWS bean needs to allow the developer to specify the count -- the number of random numbers to return. In a real example it may take your Yahoo application id and search params. But that's another blog. Here's the code:
<pre><code>
package org.jdesktop.swingws.beans;

import java.util.List;
import org.jdesktop.swingws.client.RandomNumbers;
import org.jdesktop.swingws.client.RandomNumbersService;
import org.jdesktop.swingx.JavaBean;

/**
 *
 * @author rbair
 */
public class RandomNumbersWS extends JavaBean {
    private int count = 10;
    private RandomNumbers port = null;
    
    /** Creates a new instance of RandomNumbersWS */
    public RandomNumbersWS() {
    }
    
    public void setCount(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("Count must be 0 or a positive whole number");
        }
        int old = getCount();
        this.count = count;
        firePropertyChange("count", old, getCount());
    }
    
    public int getCount() {
        return count;
    }
    
    public List<Integer> generateRandomNumbers() {
        if (port == null) {
            port = new RandomNumbersService().getRandomNumbersPort();
        }
        return port.generateRandomNumbers(count);
    }
}
</code></pre></p>

<p>JavaBean is a convenience class in SwingX that I can extend. It makes writing these non visual beans a lot easier because it handles the infrastructure for a lot of the property change notification. You'll notice that this bean isn't doing much: it's simply a wrapper for the RandomNumbers client side proxy (called a "port" in JAX-WS). Now, let's see how to use it.<br />&lt;/SIDETRACK&gt;</p>

<p>I created my Swing GUI with Matisse -- took a minute, maybe two (Note for Scott: I didn't get any baseline support for JSpinner). I then wrote this code in the actionPerformed event handler for the generate button:
<pre><code>
    private void generateButtonActionPerformed(java.awt.event.ActionEvent evt) {                                               
        randomNumbersWS.setCount((Integer)countSpinner.getValue());
        final List<Integer> results = randomNumbersWS.generateRandomNumbers();
        resultsList.setModel(new AbstractListModel() {
            public Object getElementAt(int index) {
                return results.get(index);
            }
            public int getSize() {
                return results.size();
            }
        });
    }                                              
</code></pre></p>

<p>If <a href="http://www.jcp.org/en/jsr/detail?id=295">bean binding</a> was ready to go, this would have been even simpler. But as it is, this is just normal Swing code. I set the count on the ws bean, then asked it for the random numbers. I then put the resulting List into the JList component.</p>

<p>Ok, so why bother with the bean? Seems like extra overhead here. Yes, this is a trivial example and it doesn't show off the point to a Bean very well. However, if I were using <a href="http://www.jcp.org/en/jsr/detail?id=295">JSR 295: Bean Binding</a> then having a Bean to bind to would have been really useful. Further, more complicated web services may benefit more from the beans approach.</p>

<p>There is another subtle benefit to using the JavaBean in this case. It insulates the UI developer from the web service implementation. Both Clint and Wally won't have to change anything is Sally decides to switch to XML-RPC instead of SOAP and redistributes a new bean. From the UI perspective, they are dealing with the Web Service on the semantic level, rather than the level of the implementation.</p>

<p>Once I learned how to use NB to execute web services from the client, it was a very easy process to get these calls into the UI. Those paying close attention will notice that the call blocks, though, so I have some more work to go before this is a genuinely <i>rich</i> rich client application. Gotta get rid of those blocking calls!</p>]]>

</content>
</entry>
<entry>
<title>The Unknown JavaBean</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/rbair/archive/2006/05/the_unknown_jav.html" />
<modified>2006-06-09T00:45:50Z</modified>
<issued>2006-06-01T02:19:19Z</issued>
<id>tag:weblogs.java.net,2006:/blog/rbair/231.4942</id>
<created>2006-06-01T02:19:19Z</created>
<summary type="text/plain">What is a JavaBean? What is the JavaBean design pattern? If I asked that question in a room of a hundred people, I suspect fewer than 10 would really get it right. For the majority of Java developers, the JavaBean...</summary>
<author>
<name>rbair</name>

<email>Richard.Bair@Sun.COM</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/rbair/">
<![CDATA[<p>What is a JavaBean? What is the JavaBean design pattern? If I asked that question in a room of a hundred people, I suspect fewer than 10 would really get it right.</p>

<p>For the majority of Java developers, the JavaBean pattern is simply a naming convention for accessors/mutators (getters/setters) for a property. For example:
<pre><code>
  public class Supplier {
    private String name;
    
    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }
  }
</code></pre></p>

<p>This example highlights the predominate usage of a "JavaBean". There is a property called "name". By convention, the accessor method is "get[Name of Property]" and the mutator method is "set[Name of Property]". If the property happens to be a boolean, the accessor could also be named "is[Name of Property]". For example, "isEnabled()". The other thing that most people get right is that a JavaBean has a default constructor. Why <a href="http://www.jfree.org/jfreechart/api/gjdoc/index.html">JFreeChart's ChartPanel</a> doesn't have a default constructor is beyond me, and actually the irritation that caused this blog. I just wanna put a chart into my Matisse form. Is that too much to ask?</p>

<p>In any case, accessors and mutators are all well and good, but this doesn't  make our class a JavaBean. Well, not a <i>real</i> JavaBean. JavaBeans are intended to be the component model for Java. You know, the equivilent of all those fancy components you can use in the .NET world. The idea being that there would be some standard component model, and then a component market would sprout up so that developers just go into the marketplace, pay a few hundred dollars for the charting component library they need, and wire it all together in the IDE. This approach has worked for other development environments (Visual Basic being the predominant example, Delphi being another), but has never been quite the same for the Java market.</p>

<p>I'm sure there are reasons for that, and I could write a very long blog on the subject and stir, I'm sure, some controversy in the process, but that isn't the point here. First, let's all get on the same page as to what a JavaBean really is.</p>

<p>A JavaBean does much more than provide accessor/mutator methods for internal state that follows some naming convention. To be properly understood, you have to think of things in terms of <em>components</em>. Internal state is internal state and should never be exposed in the API. What is exposed is that state that can be fiddled with. You know, background color, name, address, preference factory... that sort of stuff. Think of the bean as a black box, reveal those switches and properties to the outside world that they should be aware of. Whatever happens inside the box, stays inside the box.</p>

<p>JavaBeans are also <em>observable</em>. When one of the public properties of the bean changes, notification has to be sent so that everybody knows that the bean has had a property change. In the JavaBeans world, these are PropertyChange events. Every real JavaBean allows you to register PropertyChangeListeners with the bean, and observe PropertyChangeEvents as they occur. This is a critical component to using a real component model -- and very handy for utility applications as well (such as databinding systems).</p>

<p>The standard way to support these property change events is to use PropertyChangeSupport, which is a class in the java.beans package. This is normally the kind of code you'd write to do this:
<pre><code>
  public class MyBean {
    /**
     * Helper class that manages all the property change notification machinery.
     * PropertyChangeSupport can not be extended directly because it requires
     * a bean in the constructor, and the "this" argument is not valid until
     * after super construction. Hence, delegation instead of extension
     */
    private PropertyChangeSupport pcs;
    
    /** Creates a new instance of MyBean */
    public MyBean() {
      pcs = new PropertyChangeSupport(this);
    }
    /**
     * This method shows what all the methods really do -- delegate to
     * the PropertyChangeSupport. The other methods have been trimmed for
     * space efficiency. This is just a blog, after all
     */
    public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcs.addPropertyChangeListener(listener);
    }
    public void removePropertyChangeListener(PropertyChangeListener listener) {...}
    public PropertyChangeListener[] getPropertyChangeListeners() {...}
    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {...}
    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {...}
    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {...}
    public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {...}
    public void firePropertyChange(String propertyName, int oldValue, int newValue) {...}
    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {...}
    public void firePropertyChange(PropertyChangeEvent evt) {...}
    public void fireIndexedPropertyChange(String propertyName, int index,
					  Object oldValue, Object newValue) {...}
    public void fireIndexedPropertyChange(String propertyName, int index,
					  int oldValue, int newValue) {...}
    public void fireIndexedPropertyChange(String propertyName, int index,
					  boolean oldValue, boolean newValue) {...}
    public boolean hasListeners(String propertyName) {...}
}
</code></pre></p>

<p>Kind of a pain, huh? Fortunately, if you are writing a visual component, all this nonsense is handled for you in java.awt.Component. All you have to do is remember to fire the property change notification in your setter method. Like so:
<pre><code>
  public void setFoo(String newFoo) {
    String old = getFoo();
    this.foo = newFoo;
    firePropertyChange("foo", old, getFoo());
  }
</code></pre></p>

<p>Ok, that's a lot better. But JavaBeans and PropertyChange notification is very important for the nonvisual component as well as the visual component. Why do you want nonvisual components? .NET has a useful one: Timer. Its a simple component with a few properties like "delay", and a single event that is fired when the timer has expired. This means that in your GUI builder of choice, you simply pick the "Timer" component from the palette, add it to the form, change the properties in the property sheet, fill out an event handler (all through the GUI builder, mind you) and you're done. All you hand-gui-code-gurus out there are probably laughing right now, but I'm not talking to you. I'll try to convince you of the error of your hand-gui-coding ways some other time.</p>

<p>To ease development of non visual JavaBean components, there is a base class in the <a href="http://swingx.dev.java.net">SwingX</a> project that simplifies this problem called <a href="http://">JavaBean</a>. It makes it as trivial to fire event notification and write a true JavaBean as it is for a subclass of Component. The only hitch is, you have to extend JavaBean. That shouldn't be that big a deal. Take your most root objects (those that extend Object) and instead extend JavaBean. Done.</p>

<p>So what does this look like? Well, taking our original example:
<pre><code>
  public class Supplier extends JavaBean {
    private String name;
    
    public String getName() {
      return name;
    }

    public void setName(String name) {
      String old = getName();
      this.name = name;
      firePropertyChange("name", old, getName());
    }
  }
</code></pre></p>

<p>Bam. Two lines of new code, and bingo. I've got a real JavaBean. And this class is really valuable for a lot more than just GUI builders. There are several really interesting frameworks that could use this class and others like it, such as databinding. I'll leave other framework examples as an exercise to the reader. Hint: check the slides for the Data Access Strategies talk from this past JavaOne.</p>

<p>There is a lot more that can go into writing a full fledged JavaBean, such as BeanInfo's, EventSetDescriptors, and the like. But this is enough for one blog. Now, back to trying to make ChartPanel a friggin' JavaBean...</p>]]>

</content>
</entry>

</feed>