<?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>Tim Boudreau&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/" />
<modified>2008-06-25T03:52:45Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, timboudreau</copyright>
<entry>
<title>Manila; Moderation done right;  Breadcrumbs for NetBeans</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/06/manila_moderati.html" />
<modified>2008-06-25T03:52:45Z</modified>
<issued>2008-06-25T03:41:58Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.10022</id>
<created>2008-06-25T03:41:58Z</created>
<summary type="text/plain">Geertjan and I just finished a week doing NetBeans Certified Training in Manila - great, minus the typhoon;  my friend Karel figured out the right way to handle forum moderation 9 years ago and the world still hasn&apos;t caught on;  there&apos;s a cool new module for NetBens on the plugin portal</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[Here's three blogs in one (I know, I know, you're not supposed to do that):
<p/>
My friend <a href="http://blogs.sun.com/geertjan/">Geertjan</a> and I just did NetBeans Day Manila, in the Philippines, followed by two days of plugin-writing training at the University of the Philippines.  The students were wonderful and bright and motivated and it's always a joy to teach to people who are really interested in what you have to say.
<p/>
There's a conversation going on on the mailing list for bloggers on this site - there's been a big issue with people posting comments that consist of 500 porn URLs and such.  Back when we were little-bitty NetBeans-the-tiny-Czech-startup we had this solved on our mailing lists - 100% spam-free - a lot better than I can say for how things were after we joined Sun.  The system was incredibly simple.  My friend, and later, roommate for two years <a href="http://www.linkedin.com/in/karelzatloukal">Karel Zatloukal</a>, came up with this brilliant and blindingly obvious system - his becoming a manager was a huge loss to hackers everywhere.  It's dead-simple:
<ul>
<li>Any incoming message is delayed for 30 minutes</li>
<li>There is a &quot;hot-list&quot; who get messages un-delayed</li>
<li>Any &quot;hot-list&quot; member can bounce a message they deem to be spam</li>
</ul>
The result is, you geographically distribute the responsibility for moderation among members of the community who care about that community.  And the general public (non &quot;hot-list&quot; members) never, ever, ever, get spammed.
<p/>
This seems like such an obvious solution.  There <i>are</i> legitimate objections to this approach for mailing lists, although it worked well for us - the immediacy of conversation is reduced, because any incoming message will reach its recipients only a half-hour after it was sent.  But for blog comments?  It seems pretty ideal.
<p/>
Anyway, I wanted to share that approach so that it would not be lost to history.  It worked really, really well, and I highly recommend it.  In our case it was a copy of <code>majordomo</code> hacked within an inch of its life, but the model is simple and easily repeated on any similar system.  I feel like most moderation systems for mailing lists and blog posts are still stuck in the stone-age, and I've experienced vastly better almost ten years ago.
<p/>
Lastly, at the booth in Manila last week, someone commented to me about a new &quot;breadcrumb&quot; feature in IDEA or Eclipse that they wished NetBeans had.  I thought, gee, that would take about 20 minutes to implement, and set about doing it.  Well, 20 minutes to get the rough draft.  Another few hours to really make it useful.  <a href="http://blogs.sun.com/geertjan/">Geertjan</a> already blogged about it (do a text search for &quot;breadcrumb&quot;).  It's now available for NetBeans 6.0 and 6.1 on the <a href="http://plugins.netbeans.org">plugin portal</a> at <a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=10704">this URL</a> and should be available in the 6.0 and 6.1 built-in plugin managers soon.
<br>
<center><img alt="jesus And The Cal lCenter" src="http://weblogs.java.net/blog/timboudreau/archive/jesusAndTheCallCenter.jpg" width="640" height="426" />
</center>]]>

</content>
</entry>
<entry>
<title>Nursing a baby whale with Jonathan Schwartz&apos;s tears</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/06/nursing_a_baby_1.html" />
<modified>2008-06-03T19:06:58Z</modified>
<issued>2008-06-03T18:12:40Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9921</id>
<created>2008-06-03T18:12:40Z</created>
<summary type="text/plain">My colleague Judith Lilienfeld did the MC honors at this year&apos;s NetBeans Day in San Francisco.  I&apos;m amazed that this went by and did not get blogged about, so I&apos;ll have to do the ungainly honors...</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>JavaOne</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[My colleague Judith Lilienfeld did the MC honors at this year's NetBeans Day in San Francisco.  I'm amazed that this went by and did not get blogged about, so I'll have to do the ungainly honors...
<p/>
The demo of the morning was using JasperReports iReport plug-in to create a report with pie charts based on a database, without writing any code.  The Saturday before NetBeans Day, my colleague Brian Leonard sent out an urgent request for line-items for said database.  I dutifully replied with my standard "turn up the bus noise on the brain and see what pops out" approach.  What amazes me is that nobody sitting in the audience found it the least bit odd that one NetBeans evangelist's achievement of the month was "Nursed a baby whale on Jonathan Schwartz's tears" or "Fed the NetBeans Aardvark"...
<p/>
So here I am tooting our own cleverness.
<p/>
Meanwhile, back at the ranch, I would like to reply to an article <a href="http://javabyexample.wisdomplug.com/java-concepts/34-core-java/59-tips-and-tricks-for-jtree-jlist-and-jcombobox-part-i.html">here</a> which borrows some continuation tooltip code I wrote for NetBeans back in '05, which is generally useful.  However, whatever kind of CAPTCHA system that site is using demands that I "input" the text contained in an image, without actually supplying a place to put said information (tried it in both Safari and Firefox - it's not a browser bug).  So, with apologies, here's my reply, and please fix your web site:
<blockquote>
<i>
Happy to see you found my popup tricks useful.  I agree, they ought to be built into JTree and JList and just automatic, though I'm sure that would present a backward compatibility problem of some sort for anybody who has already dealt with them on their own (popup wars, anyone?).
<p/>
Combo boxen are their own special problem - Apple gets this fairly right by sizing the popup to the maximum preferred size of the contents;  everybody else gets it semi-wrong by preferring the size of the control to the necessary size for the contents - it just ain't pretty.  The only viable alternative is to write your own UI delegate and screw cross-platform appearance.  I describe how to do something like that <a href="http://lists.apple.com/archives/java-dev/2004/Apr/msg00074.html">here</a>.
</i>
</blockquote>]]>

</content>
</entry>
<entry>
<title>Egads!  An actual Swing Tree-Table!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/06/egads_an_actual.html" />
<modified>2008-06-03T12:07:51Z</modified>
<issued>2008-06-03T11:36:58Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9918</id>
<created>2008-06-03T11:36:58Z</created>
<summary type="text/plain">Four years ago, I went on a hunt for best practices for doing tree table components in Swing.  We had a tree-table component in NetBeans, whose maintenance was my never-ending nightmare and the biggest source of bugs on my bug list.  Now there is a real Swing Tree Table component available in NetBeans and for any programmer who wants to use it.</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[Four years ago, I went on a hunt for best practices for doing tree table components in Swing.  We had a tree-table component in NetBeans, whose maintenance was my never-ending nightmare and the <a href="http://www.netbeans.org/issues/show_bug.cgi?id=33281">biggest source of bugs on my bug list.</a>  It had been written, with the best of intentions, based on Scott Violet's <a href="http://java.sun.com/products/jfc/tsc/articles/treetable2/index.html">Swing Connection article</a> about how to quickly hack up a tree-table component in Swing (Scott's article was also written with the best of intentions, and I have no intention to ding him here - what he wrote does work for simple use-cases - a debugger is not a simple use-case).
<p/>
When I canvassed folks who had done Swing tree-tables on our mailing lists, most of them were based on that article, as ours was.  What I heard back varied between groans of pain and mad rabid howls of pain.  There are a few things in that original tree table design that just don't work - not reliably, anyway.  Sending events to an offscreen component as if it were on-screen and expecting it to behave sanely is just a really bad idea that happens to work if the look and feel is a subclass of BasicLookAndFeel, and other look and feel implementations have been tormented into supporting this abuse by all the evil Tree-Table implementations in the wild.  But the bottom line is, a look-and-feel author would have to be slightly insane to code their TreeUI to behave as if it were a live component when it has no parent and obviously is not one.  In other words, the fact that the JTree-as-cell-renderer design works at all is just an accident of how BasicLookAndFeel's TreeUI implementation was designed, which other look and feels inherited.  Never mind trying to use said JTree as a cell renderer in a table (I once made a 400% performance improvement in our tired, tortured, hacked-up TreeTable just by having it translate the graphics context instead of repositioning - and thus causing a re-layout) is seriously abusing the component.  Now try convincing said offscreen JTree that it has keyboard focus in order to get it to paint appropriately in its role as a cell renderer for another component.  On all look and feels.  On all platforms.  Everywhere.
<p/>
You see what I mean.
<p/>
After doing that canvassing back in '04, it was obvious that Swing needed a <i>real</i> tree-table component.  So I started to write one (and the layout cache classes JTree uses were very, very helpful - thanks, Scott!).
<p/>
I started on it, got the basics working, and then moved back to the U.S., changed jobs and ended up travelling the world full-time teaching other people to write NetBeans modules - but it didn't leave time to finish up the Tree Table work.  Thankfully, my former office-mate, David Strupl, picked up where I left off when he left Sun to work on <a href="http://www.netbeans.org/community/articles/nokia-netact.html">Nokia's NetBeans RCP app for managing cellular telephone networks</a>.
<p/>
The <i>really, really great news</i> is:  This week, <a href="http://blogs.sun.com/stan/">Standa Aubrecht</a> - who took over a bunch of the stuff when I left full-time development of NetBeans in '04 and amazed me with how quickly he was able to get going in a complex codebase - <a href="http://hg.netbeans.org/main/rev/5ca2a45fd6a1">committed it into the main line of NetBeans sources</a> yesterday.  So anybody who gets a dev build of NetBeans as of today has a perfectly working Swing Tree Table component they can use (the class name is <code>Outline</code> - I borrowed the name from Apple's Cocoa library - it's a little less clunky than &quot;tree table&quot; but gets the point across).  The JAR file is <code>org.netbeans.swing.outline.jar</code>.  Usage is incredibly easy - you just provide a standard Swing TreeModel of whatever sort you like, and an additional RowModel that can be queried for the other columns contents, editability and so forth.  And you never have to worry about cells painted half one color and half another because the tree-cell part got repainted after focus went to a popup menu.  It actually works!
<p/>
The real credit here goes to David and Standa for getting this thing production-worthy - I just was pissed-off enough at having a gargantuan list of unfixable bugs (well, fix it on one platform, break it on another, or leave it unfixed everywhere, or semi-fixed some places - pure evil if you hold the illusion that what we do is computer <i>science</i>) four years ago to get the ball rolling.  They're the guys who delivered it.
<p/>
I'm incredibly happy to see this finally be real and available not just to people writing NetBeans modules, but anybody doing GUI apps in Java.  There has been a need for a real, reliable tree table component for Swing programmers for a long, long, long time.  All hail David and Standa!


]]>

</content>
</entry>
<entry>
<title>What technology evangelists really do for a living</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/04/what_evangelist.html" />
<modified>2008-04-11T16:30:38Z</modified>
<issued>2008-04-11T16:21:02Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9516</id>
<created>2008-04-11T16:21:02Z</created>
<summary type="text/plain">We shot some video on our recent whirlwind tour of South America.  This fun video shows one of our adventures.</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[We shot some video on our recent whirlwind tour of South America.  This fun video shows one of our adventures.  What do technology evangelists really do for a living?  Ride in taxis and buses, of course!
<p/>
<object width="425" height="350"> <param name="movie" value="http://www.youtube.com/v/dYQUMICS5tg"> </param> <embed src="http://www.youtube.com/v/dYQUMICS5tg" type="application/x-shockwave-flash" width="425" height="350"> </embed> </object>
<p/>
BTW, the video editing and post-production was done by my good friend and music buddy Doug Finn (douglas dot finn at gmail).  He is a supremely talented video editor, actor, director and musician.  If you're looking for something like this, I highly recommend him.
<p/>
A couple of other videos from this trip (less slickly edited, since it was me doing them not Doug) are visible at the bottom of <a href="http://www.netbeans.tv/on-the-road/">this page on netbeans.tv</a>.
<p/>
The person I really feel for in the above video is Juan Daniel Perez, whose reward for helping organize our event in Cordoba was that five guys piled into his hotel room at 6:30 in the morning to use his shower :-)]]>

</content>
</entry>
<entry>
<title>See Java code the way javac sees it</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/02/see_java_code_t.html" />
<modified>2008-04-01T00:18:53Z</modified>
<issued>2008-02-28T23:50:03Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9289</id>
<created>2008-02-28T23:50:03Z</created>
<summary type="text/plain">I wrote a small Swing app to browse javac&apos;s abstract syntax trees of source code.  If you&apos;ve ever wanted to write a tool that analyzes Java source code, it is a big help for understanding the Javac tree API.  The JAR file is attached to this blog.</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[I wrote a small Swing app to browse javac's abstract syntax trees (ASTs) of source code.  If you've ever wanted to write a tool that analyzes Java source code, it is a big help for understanding the Javac tree API.  
<p/>
Last spring I set about learning <a href="http://www.artima.com/lejava/articles/compiler_api.html">javac's Tree API (JSR 199)</a> - NetBeans uses it internally as its parser for Java source code.  It has a bit of a learning curve, and contains lots of this-tree and that-tree interfaces for different types of structures in Java source code.  So to help me develop an intuitive understanding of what all of these classes map to, I wrote a tool - a standalone Swing app that lets you open a Java source file and then browse its AST.
<br/>
<center>
<img alt="syntaxtreebrowser.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/syntaxtreebrowser.jpg" width="550" height="283" />
</center>
<br/>
The tree on the left lets you drill through the syntax tree itself.  The middle pane shows you the object that is selected, and a tree of all of its fields and methods via introspection, which you can drill as deeply as you want through.  The right pane is sensitive to selection in whichever of the other two panes has focus.  The top half shows you the list of all types the selected object implements (and boldfaces those that are part of the official API), and the bottom half shows you the value of <code>toString()</code> for the selected object (if it's part of the syntax tree, it will be the source code text).
<p/>
I found it very useful, and still use it to figure out just how to hunt down a particular thing I want to find in source code.  Hopefully it will inspire some others to play with javac as well.  It requires JDK 6.  You can <a href="https://syntaxtreebrowser.dev.java.net/SyntaxTreeBrowser.jar">download the JAR file here</a> and just run it with <code>java -jar</code>.
<p/>
<strike>The source code is available in NetBeans <i>CVS</i> under <code>contrib/SyntaxTreeNavigator</code> (everything was reorganized for the recent migration to Mercurial, and I haven't figured out where it is in the new source structure yet).</strike><b>Update (3/31/08):</b> I've set up a java.net project for the source code, <a href="http://syntaxtreebrowser.dev.java.net">syntaxtreebrowser.dev.java.net</a>.  It is pending approval but it should be publicly visible in a few days.
<p/>
<b>Caveats:</b> <i>(updated 2/29/07)</i> <ol><li>To use the application, you will need javac on your classpath.  If you are running Apple's JDK 1.6 it already is.  For other platforms you may need to run with <code>-Xbootclasspath/p:/PATH/TO/javac.jar</code> (may be in tools.jar).</li><li>This application uses the <code>com.sun.source.tree</code> API from javac.  If you are not running Sun's javac, this package will probably not be there.</li></ol>
<p>
I have updated the JAR file to produce better diagnostic information, and added a <a href="http://weblogs.java.net/blog/timboudreau/archive/SyntaxTreeBrowser.zip">source zip file</a>.]]>

</content>
</entry>
<entry>
<title>Class visualization module for NetBeans</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/02/last_week_i_wro.html" />
<modified>2008-02-28T22:13:52Z</modified>
<issued>2008-02-28T22:13:44Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9287</id>
<created>2008-02-28T22:13:44Z</created>
<summary type="text/plain">I wrote a little module for NetBeans which lets you get a graphical view of a Java class&apos;s contents and the realtionships between methods and fields.  It&apos;s available on the NetBeans alpha update center (dev builds only).</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[<p>Last week I wrote a little module that uses the <a href="http://graph.netbeans.org">NetBeans Visual Library</a> and the <a href="http://www.artima.com/lejava/articles/compiler_api.html">Javac Tree API</a> to create a graph of the contents of a Java file, showing dependencies between class members.  It's now available on the NetBeans daily build update center - if you're running a daily build of NetBeans, just go to Tools | Plugins and download Graphical Class Viewer.</p><p>My question is, would anybody actually find this useful?  It was mostly an experiment to get more fluent with a couple of APIs I need to know well - but it seems like it could be handy if you're going to edit a class you didn't write and want to see where the action is - or if you've got a bunch of encapsulated fields and want to quickly see if anything is not using the getters and setters.</p>What it does:<ul><li>Shows a graph (see screenshot below)</li><li>If you hover the mouse over, say, a method, then the path to things that method calls/uses will be shown in red, and things that call that method are shown in blue</li><li>You can click the arrow button on the widget for any class member and see its source code</li></ul><p><img src="http://netbeans.dzone.com/sites/all/files/gcv1.jpg" width="499" height="312" /> </p><p>Feel free to try it out and let me know if you think it's something worth putting more work into.</p><p>Also, if anyone knows of any speedy and good hub-and-spoke or other layout algorithms for the case where you have <span class="Apple-style-span" style="font-style: italic">n</span> nodes each of which can have up to <span class="Apple-style-span" style="font-style: italic">n-1</span> connections to other nodes, feel free to let me know - what it does now is less than optimal.  At some point I may think through the geometry to do it nicely, but I'm not sure when.</p>
<p/>
The sources are in <a href="http://hg.netbeans.org/main/contrib/">NetBeans contrib mercurial repository</a>.
<p/>
Comments?  Reply on the <a href="http://netbeans.dzone.com/announcements/new-class-visualization-module">NetBeans DZone thread</a> about it.]]>

</content>
</entry>
<entry>
<title>What if we built Java code with...Java?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2008/01/what_if_we_buil.html" />
<modified>2008-01-30T21:50:49Z</modified>
<issued>2008-01-30T21:36:52Z</issued>
<id>tag:weblogs.java.net,2008:/blog/timboudreau/181.9097</id>
<created>2008-01-30T21:36:52Z</created>
<summary type="text/plain">My friend Jon had an interesting insight:  Both Ant and Maven rely on lots of XML.  XML is good for describing data and terrible for describing behavior.  A build is mostly behavior.  What if, instead of tormenting Ant into iterating on a bunch of subprojects of subprojects, if we just used an actual programming language to write build scripts.  Like, oh, say...Java, for instance?</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: Java Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[My friend <a href="http://www.jroller.com/JonathanLocke/">Jon</a> had an interesting insight:  Both Ant and Maven rely on lots of XML.  XML is good for describing data and terrible for describing behavior.  A build is mostly behavior.  What if, instead of tormenting Ant into iterating on a bunch of subprojects of subprojects, if we just used an actual <i>programming language</i> to write build scripts.  Like, oh, say...Java, for instance?
<p/>
So he created the <a href="http://gosling.dev.java.net">Gosling</a> project.  It's pretty embryonic - and I think some of the file and resource classes could be replaced by straight usage of things like <code>javax.tools.FileObject</code>, but it has a nice simplicity.  Here's the constructor for Gosling's own build to build itself.  It has a similar feel to what Jon did in designing <a href="http://wicket.apache.org">Wicket's APIs</a>:
<pre>
    public GoslingProject() {
        final Folder root = new Folder("/Projects/gosling/workspace/gosling");
        final Folder source = root.folder("src");
        final Folder lib = root.folder("lib");
        final Folder target = root.folder("target");
        add(new JavaApplicationBuilder() {
            @Override
            protected Set<ResourceDescriptor> getDependencies() {
                final ResourceDescriptorSet dependencies = new ResourceDescriptorSet();
                dependencies.add(Apache.apache.wicket.core.development.resources());
                dependencies.add(Apache.apache.wicket.extensions.development.resources());
                return dependencies;
            }

            @Override
            protected Set<Jar> getJars() {
                return lib.nestedJars();
            }

            @Override
            protected Folder getSourceFolder() {
                return source;
            }

            @Override
            protected Folder getTargetFolder() {
                return target;
            }
        });
}
</pre>
<img align="right" alt="Brazilian Salt Shakers" src="http://weblogs.java.net/blog/timboudreau/archive/table.JPG" width="320" height="426" />

I spent last night wrestling with writing an Ant script to build, test and build Javadoc for an ad-hoc collection of projects, where a bunch of custom information needs to be gathered from the projects and embedded elsewhere, and I just found myself thinking <i>this is so not the way to build software!</i>.
<p/>
I mean, the appeal of things like Ant is that many things are built in a pretty similar way;  Maven is even more &quot;my way or the highway&quot; in that regard.  I use (and sometimes like) both of them.  And in theory an Ant XML script (<i>xml script</i> - now there's an oxymoron) is human readable - although I challenge anyone to make heads or tails of <a href="http://deadlock.netbeans.org/fisheye/browse/netbeans/nbbuild/build.xml?r=MAIN">this</a> in ten minutes.  It certainly beats Make and tab vs. space madness.  There's an argument that it's <i>toolable</i> - that a tool can analyze an Ant script.  This seems to me to be a red-herring if you do a design like <a href="http://wicket.apache.org">Wicket</a> or <a href="http://gosling.dev.java.net">Gosling</a> use - where you <i>know</i> that the entire state you need to analyze is going to be set up in the constructor of a known class of a known type.  The Javac Tree API may not be for the faint of heart, but analyzing the closure of a constructor is perfectly doable.
<p/>
My point is that Ant doesn't really deliver the clarity it promised except in the most trivial of cases.  You could have at least as much clarity with plain-old Java code - you just need to start from a good design so the code can speak for itself.  And a design where all targets will be added to the build in the constructor is pretty darned clear.  Isn't one of the things the agile crowd talks about a lot letting code speak for itself?
<p/>
Not to mention that running javac in-process ought to be blazingly fast.  And that such a project could import and call existing Ant tasks to do things with a thin adapter layer - so anybody's custom tasks or missing functionality could be handled leveraging stuff that's already out there.
<p/>
It seems like a pretty nice idea to me.]]>

</content>
</entry>
<entry>
<title>NetBeans Editor Demo video</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/12/netbeans_editor.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-12-22T00:24:59Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8887</id>
<created>2007-12-22T00:24:59Z</created>
<summary type="text/plain">Someone who attended my talk in Florianopolis, Brazil put this video YouTube.  The sound isn&apos;t great, but you do get to see some of the cool NetBeans 6 editor features.</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[Someone who attended my talk in Florianopolis, Brazil put <a href="http://www.youtube.com/profile?user=gujavasc">this video</a> on YouTube.  The sound isn't great, but you do get to see some of the cool NetBeans 6 editor features.
<p/>
To the person who posted it - if you can send me a .wav file of the audio, I'd be happy to clean out the ambient noise and make the soundtrack much easier to understand - I was a sound engineer in a former life...

]]>

</content>
</entry>
<entry>
<title>A Little Persistence Framework for Wicket</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/11/a_little_persis.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-11-29T19:13:42Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8732</id>
<created>2007-11-29T19:13:42Z</created>
<summary type="text/plain">I&apos;ve contributed a little persistence framework to WicketStuff.  Here&apos;s what it is and how it works...</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Web Applications</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[I've contributed a little persistence framework to <a href="http://wicketstuff.org">WicketStuff</a>.
<p/>
Basically, over the summer I needed to write a couple of web applications.  My friend <a href="http://www.jroller.com/JonathanLocke/">Jon</a> suggested I try out <a href="db4o.com">db4o</a>, an object database.
<p/>
One of the things I like about <a href="http://wicket.apache.org">Wicket</a> is its simplicity - no XML config files, straightforward HTML that maps to components, and every component has a <a href="http://wicket.sourceforge.net/apidocs/wicket/model/IModel.html">Model</a> that represents one object.  One of the painful things in Swing is that, if you decide you want a Tree, not a List, you have to rewrite your models because every different flavor of component comes with its own flavor of model.  In this, Wicket gets right a thing that Swing got dead-wrong.  Also very nice is the fact that wicket components can automagically look up properties on an object - once you have the concept that every component has a model, and any model represents exactly one object, there are a lot of very useful things you can do.  So if I want to show the Date property of a <a href="http://en.wikipedia.org/wiki/POJO">POJO</a>, it is as simple as:
<pre>
class MyPanel extends Panel {
    MyPanel (String id) {
       super (id);
       setModel (new Model (lookUpThePojo()));
       Label dateLabel = new Label ("date");
       add (dateLabel);
    }
}
</pre>
and no special glue is needed - if the ID matches a bean property on the POJO, I'm done (if I don't like the overhead of reflection, of course I can also write a custom model).
<p/>
<i>Hey!  Wait a second!  What does that <code>lookUpThePojo()</code> method do?!  Isn't that where the magic happens?</i>  Yes.  That is the precisely the problem I am setting out to solve...
<p/>
As the application evolved, I found myself really wanting a similar simplicity for database access - I was ending up with far too much code dotted all over the application, which contained fairly similar code for looking up POJOs for Users, Events, Presentations, etc. - the app was a tool that allows Java Users Groups to vote on what we should talk about at NetBeans Day events.
<p/>
Wicket also has a concept of <i>detachable</i> models - a model which looks up an object, but can dispose of it when it is not needed any more.  This is particularly important because Wicket uses serialization to (really completely!) solve the back-button problem.  Particularly in a clustered environment, you don't want to serialize an entire object graph for some POJO and send it over the wire  to the rest of the cluster - you want to just save, say, a unique ID for the POJO and look it up again when something actually needs to call the POJO.
<p/>
<img alt="Canary (?) in Foz do Iguacu, Brazil" align="right" src="http://weblogs.java.net/blog/timboudreau/archive/bird.jpg" width="640" height="425" />
</p>
So the problem really was - how can I transparently and easily create <code>IModels</code> for POJOs on demand, keep the database lookup code in one place, and keep session size small.  So a framework for doing this started to evolve out of this application.  It comes as three libraries:
<ul>
<li>A <i>persistence facade</i> API - a persistence facade is just an object which manages a POJO's lifecycle.  Under the hood, a persistence facade has one of a number of possible <i>lookup strategies</i> - for example, if the object is modified but unsaved, then it will be cached;  on the other hand, if it is unmodified, then the lookup strategy used will probably revert to just holding an ID for the object when nothing is interested in it.  The persistence facade piece has an SPI (Service Provider Interface) that can be implemented over any database (probably simpler for db4o but certainly doable over hibernate or even using straight JDBC) - the db4o implementation is completely separate.  It's basically a matter of implementing two (admittedly complex) interfaces.
</li>
<li>An implementation of the persistence facade SPI over db4o</i>
<li>An API that allows you to create Wicket models from a various types of queries, and model classes for modelling a single object or a collection of objects, that do the same kind of property lookup magic, but manage object lifecycle so that the persistence facade ends up in a minimum-size state when it is not actively in use by Wicket components
</li>
</ul>
To be clear, the goal was not to create something with magical dynamic proxies or POJOs that transparently get persisted or anything like that;  the persistence facade library simply attempts to cleanly express the problem of managing the lifecycle of a persisted object.  No magic, it's just a thing you can then build some magic on top of.
<p/>
The result is simple to use (I would be interested in feedback on how to make it even simpler).  You write some POJOs (they should be serializable and implement <code>equals()</code> and <code>hashCode()</code> correctly).  You get a <code>ModelBuilder</code> for a particular type of query.  Say I already have a POJO and I want a model for it:
<pre>
Person person = new Person ("Henry", "Story");
QueryBuilder<Person> builder = Queries.EXISTING_OBJECTS.builder(Person.class);
PojoModel<Person> model = builder.single(getDatabase());
</pre>
or say that I want a collection of models for all instances of Person that are persisted:
<pre>
QueryBuilder<Person> builder = Queries.OF_TYPE.builder(Person.class);
PojoCollectionModel<Person> polyModel = builder.multi(getDatabase());
</pre>
You could also do a prototype-based query (not sure if this should actually stay in the API or not - with db4o it's easy;  with other databases perhaps not since it involves some magic):
<pre>
Person prototype = new Person();
prototype.setName("Henry");
QueryBuilder<Person> builder = Queries.PROTOTYPE.builder(Person.class);
builder.setObject (prototype);
<font color="gray">//find all the Henry's in the database</font>
PojoCollectionModel<Person> model = builder.multi(getDatabase());
</pre>
or if I want all of the Henry's who live in France, I can do a complex query based on persisted fields of objects:
<pre>
FieldQueryElement nameQuery = new FieldQueryElement ("firstname", String.class, "Henry", false);
FieldQueryElement franceQuery = new FieldQueryElement ("address.country", String.class, "FR", false);
QueryElement theQuery = nameQuery.and(franceQuery);
QueryBuilder<Person> builder = Queries.COMPLEX.builder(Person.class);
builder.setObject (theQuery);
PojoCollectionModel<Person> model = builder.multi(getDatabase());
</pre>
(If you're wondering what the getDatabase() method is, an instance of <code>Db</code> is owned by the Application object, and I included a couple of handy <code>Panel</code> and <code>Application</code> subclasses to look it up - it is the equivalent of <code>((DbApplication) Application.get()).getDb()</code>).
<p/>
You may have noticed above that I specified a field as <code>&quot;address.country&quot;</code> - yes, you can drill through the object graph this way - so you're not limited to only looking at fields directly on a persisted object.  Also, you are not restricted to exact matches - you can use a <code>RangeValue</code> for a range of numbers, or <code>StringContainsValue, StringEndsWithValue</code> or <code>StringStartsWithValue</code>.
<p/>
Application code is not terribly tied to the database implementation, but you can directly access it if you want to.  There is a class called <code>Db</code> which takes a generic type parameter - for example, the db4o implementation produces a <code>Db&lt;com.db4o.ObjectContainer&gt;</code>; but database access does not have to be tied to that database unless it is useful to you for it to be.  You can implement <code>DbJob<ObjectContainer, Arg1Type, Arg2Type></code> and be passed the actual <code>ObjectContainer</code> instance and do what you want directly with the database, or have the only thing tied to the type of the database implementation be the thing that instantiates it.
<p/>
So what can we do with all this?
<p/>
Well, Wicket already has <i>repeater</i> components - very handy for showing a collection of data.  And we can use property lookup and just give components ids that match properties.  So, say I want to show all of the Person objects in my database:
<pre>
class PeoplePanel extends Panel {
  public PeoplePanel (String id) {
     super (id);
     PojoCollectionModel<Person> model = Queries.OF_TYPE.builder(Person.class).multi(getDatabase());
     setModel (model);
     DataView repeater = new DataView ("repeater", model.createDataProvider()) {
          public void populateItem (Item item) {
              item.add (new Label ("firstName"));
              item.add (new Label ("lastName"));
          }
     }
    add (repeater);
}
</pre>
That's it!  The process of getting the domain objects is abstracted into creating a model based on a particular query;  the UI code is no longer littered with database-related code, and is nice and simple.
<i>
<center>
<img alt="wicketDbApp.png" src="http://weblogs.java.net/blog/timboudreau/archive/wicketDbApp.png" width="535" height="580" /><br/>
A quickie diagram of what's going on
</center>
</i>
<p/>
Now, say that I want a form to add a person:
<pre>
class AddPersonForm extends Form {
   TextField firstName = new TextField ("firstName");
   TextField lastName = new TextField ("lastName");
  AddPersonForm (String id) {
     super (id);
     <font color="gray">//Will create a new instance via Class.newInstance() - or I could pass a factory</font>
     setModel (Queries.NEW_OBJECTS.builder(Person.class).single(getDatabase()));
     add (firstName);
     add (lastName);
   }

   public void onSubmit() {
       ((PojoModel<Person>) getModel()).modified(); <font color="gray">//this line will not be necessary in the future - a small thing that needs fixing :-/</font>
       ((PojoModel<Person>) getModel()).save();
   }
}
</pre> 
<p/>
Now, I'm not trying to solve world hunger here - these libraries scratch a particular itch, and will not necessarily be the right tool for every job.  And surely other minds will find places where things could be simplified and improved - thoughts and contributions are very, very welcome!
<p/>
The libraries can be built with Maven (I'm pretty new to Maven, so I'm sure some things could be improved here);  if you do a checkout of <a href="http://wicketstuff.org">WicketStuff</a>, you can find all of this, plus a demo app, in the <code>quickmodels</code> directory (thanks to Wicket maintainer <a href="http://chillenious.wordpress.com/">Eelco Hillenius</a> for suggesting the name).  Presumably we'll get continuous builds of it running sometime soon.
<p/>
The code is licensed under the Apache license, with the exception of the db4o implementation of the persistence SPI, which is dual-licensed under Apache and GPLv2 (since you get db4o either under a commercial license or under GPLv2, for license-compatibility, if you use db4o under the GPL, then you must use the code that links to db4o under GPL;  if you have a commercial license of db4o, then you can use the persistence implementation over db4o under whichever license you prefer).
<p/>
Feedback on the design, API, and whether you find this stuff useful is very welcome.]]>

</content>
</entry>
<entry>
<title>The NetBeans South American Tour Wraps Up</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/11/the_netbeans_so_1.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-11-24T12:04:16Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8702</id>
<created>2007-11-24T12:04:16Z</created>
<summary type="text/plain">After 11 cities in three weeks, we finished up the NetBeans/OpenSolaris South American University Tour last week with a huge crowd in Natal, Brazil</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[After 11 cities in three weeks, we finished up the NetBeans/OpenSolaris South American University Tour last week in Natal, Brazil.
<p/>
On Saturday, after our five hours of NetBeans talks, I was scheduled to do a talk at <a href="http://www.jeebrasil.com.br/nataljavaday/">Natal Java Day</a>, at 9:40AM.  I awoke to blazing sunlight coming through the window of my hotel room.  My mental clock that judges such things told me it looked like 9 or 10AM.  <i>Oh, crap</i>, I thought - <i>I slept through my talk!</i>  So I power up the laptop.  It says it is 5:45AM.  So I call the reception desk.  Yes, it really is 5:45AM.
Natal is in the tropics - quite close to the equator.  Sunrise happens very fast, and it is full light very early.
<p/>
We spent Sunday cruising around the dunes of Natal in a dune buggy, with a driver who offered us the options of a tour <i>with emotion</i>, or a tour <i>without emotion</i>.  We realized what <i>with emotion</i> means the first time we went down a near-vertical grade.  There were various stops to zip down ropes at high speed into a lake and other such madness.  Actually, I'd recommend this sort of tour (maybe with slightly <i>less emotion</i> when it comes to the driving) to anyone with kids - it's very kid-friendly.
<p/>
I'm taking some vacation now, which has given me time to work on one of my Friday-afternoon-projects, a persistence framework for <a href="http://wicket.apache.org">Wicket</a> that makes writing database-aware applications really trivial.  I'll be contributing it to <a href="http://wicketstuff.org/">Wicket Stuff</a> sometime in the next week or two - so a blog containing some actual Java code is coming, I promise :-)
<p/>
Meanwhile, some photos from our travels...
<center>
<i>
<img alt="Cows on the beach in Natal, Brazil" src="http://weblogs.java.net/blog/timboudreau/archive/Library - 2063.jpg" width="640" height="480" />
<br/>
Cows on the beach - who knew?
<p/>
<img alt="Fisherman in Natal, Brazil" src="http://weblogs.java.net/blog/timboudreau/archive/Library - 2067.jpg" width="640" height="480" />
<br/>
A fisherman in Natal, Brazil
<p/>
<img alt="Street vendor in Natal, Brazil" src="http://weblogs.java.net/blog/timboudreau/archive/Library - 2097.jpg" width="640" height="480" />
<br/>
Street vendor in Natal, Brazil
<p/>
<img alt="Can you find the computer programmers in this picture?" src="http://weblogs.java.net/blog/timboudreau/archive/findTheComputerProgrammers.JPG" width="640" height="480" />
<br/>
Can you find the computer programmers in this picture?
<p/>
<img alt="Florianopolis, Brazil" src="http://weblogs.java.net/blog/timboudreau/archive/florianopolis.JPG" width="640" height="480" />
<br/>
Florianopolis, Brazil - one of my favorite places on earth!
</i>
</center>]]>

</content>
</entry>
<entry>
<title>The NetBeans Latin American Tour - Starting Week Three</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/11/the_netbeans_la.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-11-12T20:19:10Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8632</id>
<created>2007-11-12T20:19:10Z</created>
<summary type="text/plain">It&apos;s been a wild week of travel, to Buenos Aires and Cordoba, Argentina and now Santiago, Chile.  We&apos;ve had some adventures along the way...</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[It's been a wild week of travel, to Buenos Aires and Cordoba, Argentina and now Santiago, Chile.  We've had some adventures along the way.
<p/>
In Buenos Aires, 90% of the airline pilots were grounded for not having had sufficient vacation to comply with safety regulations.  So our flight to Cordoba was cancelled.
<p/>
The next option was to take an overnight bus.  So we went to do a little tourism shopping in the afternoon before the bus, and got back to pick up at our bags at the hotel and go the short distance to the bus station for our 6:30pm bus at 6pm (we had already bought tickets).
<p/>
Well, the thing we didn't know is that <i>it is impossible to get a taxi in Buenos Aires in less than 20 minutes at 6pm on a work-day</i>.  So we end up hauling bags and boxes of cd's and backpacks several blocks, trying to find a more major street to get a cab - and I end up begging a busboy at a Sheraton hotel to help us get a taxi <i>ahora</i> to the airport, in extremely broken and forgotten Spanish.
<p/>
(Spanish is a challenge - after three years of Russian and five and a half years speaking Czech daily, actually constructing a sentence is nearly impossible - in Fortaleza, a security guard questioned what I was doing there, and I replied &quot;Yo soy [spanish] paletrante [portuguese] na treti patro [czech]&quot;).
<p/>
So we pile into a taxi at the Sheraton, but we need more than one taxi.  And there is no other taxi.  So <a href="http://weblogs.java.net/blog/brunos/archive/2004/05/open_source_sta.html">Bruno</a> and I go ahead to the bus station, leaving <a href="http://weblogs.java.net/blog/maltron/">Mauricio</a> and Tim Jacobson to find another taxi while we try to stall the bus.  We succeed in delaying the bus, though it did not make us popular with the driver, and finally the guys arrive and off we go.
<p/>
<table>
<tr>
<td>
We get into Cordoba at about 5AM.  So we get our vast pile of boxes and bags and head for the taxi stand, and get in two taxis.  The driver tells us the address of our hotel does not exist and he's never heard of it.  So we start driving to try to find some hotel, and <a href=" http://alobbs.com/">Alvaro</a> goes into the first one we find and asks them where our real hotel is.  They tell us it is in another town 50km away.  So we drive around Cordoba with two taxi drivers, trying to find a hotel we can actually get a room at at 6 in the morning.  Eventually we make a phone call, and it's suggested we call a guy from the local users group who is helping us.  So at 6:30AM all five of us pile into his hotel room, shower, eat breakfast...and then it's off to the university for the first five hours of talks of the day.
<p/>
We had a very good crowd for the morning in Cordoba, very knowledgable about Java, so I skipped my intro to Java talk and went straight to NetBeans.  There were some oohs and aahs when demoing code templates and instant rename, and the audience was really attentive.  It's always fun to do a talk with people who are really into what you're talking about.
<p/>
Cordoba is a beautiful city, and it is spring here, so the trees are in bloom.  One of the professors from the university we talked at took us on a tour of the city the day after, which is where most of the photos in this blog came from.  It's definitely a city I would love to visit with more than 48 hours to get to know it - there's a lot here!
</td>
<td>
<center>
<img alt="Argentina - 19.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 19.jpg" width="480" height="640" />
<br/>
<i>Hallway in the oldest university in the Americas</i>
</center>
</td>
</tr>
</table>
And of course we're having a lot of <a href="http://www.youtube.com/watch?v=6eZL3EIYANA">fun with Bruno's puppets</a>, Juggy and Jack.
<p/>
I've got a bunch of ideas for NetBeans module projects percolating, that I've been thinking about on this trip.  As usual, the question is what to prioritize (like I don't have enough projects!).  What do you think:
<ul>
<li>Support for developing things to extends <a href="http://wonderland.dev.java.net">Project Wonderland</a></li>
<li>Something to make it easy for students to submit a project for a class just by right clicking a NetBeans project, with an SPI for plugging in whatever talks to the backend, so people can do what they want</li>
</ul>
<center>
<img alt="Wall of a cathedral in Cordoba, Argentina" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 57.jpg" width="480" height="640" />
<br/>
<i>Wall of a cathedral in Cordoba, Argentina</i>
<p/>
<img alt="Jack Loves OpenSolaris" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 75.jpg" width="640" height="480" />
<br/>
<i>Jack - one of Bruno's wonderful puppets, who loves <a href="http://opensolaris.org">OpenSolaris</a></i>
<p/>
<img alt="Mickey mouse butt?" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 83.jpg" width="480" height="640" />
<br/>
<i>
Now this is art!
</i>
<p/>
<img alt="Orgasmatron I" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 89.jpg" width="640" height="480" />
<br/>
<i>Not quite what it is advertised as...</i>
<p/>
<img alt="Argentina - 86.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/Argentina - 86.jpg" width="640" height="480" />
<br/>
<i>But definitely an unusual sensation, as Bruno discovered</i>
</center>]]>

</content>
</entry>
<entry>
<title>The NetBeans South America Tour, week 1.5</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/11/the_netbeans_so.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-11-08T06:46:18Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8601</id>
<created>2007-11-08T06:46:18Z</created>
<summary type="text/plain">It has been a whirlwind trip so far in South America...</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[It has been a whirlwind trip so far in South America.  Last week we did one city a day for four days - lots of arriving in airports at 3AM, sleeping for four hours and then presenting for five, then talking with JUG members and professors into the night, then getting on another plane.  But it's been a blast.  We've been shooting a lot of videos, so we should have some interesting stuff for <a href="http://netbeans.tv">netbeans.tv</a> - though Bruno was cursing me this morning for shooting everything in HD - one hour of HD video is 500Gb+, so we now have about five terabytes of video to do...something...with.  I think I'll be buying some hard drives...
<p/>
The turnout has been excellent in all of the cities we have visited, and we are having a lot of fun meeting local Java developers and users groups.  Some of the highlights:
<ul>
<li><b>Playing soccer with the Montevideo JUG members</b> - put a bunch of Brazilians, Argintines and Uruguayans at a table for lunch together, and the topic will inevitably turn to soccer.  This ended in the Uruguayans challenging the rest of us to a game of soccer that night - so we all rented a soccer court on the beach, and well, two days later walking down stairs is still a bit painful.</li>
<li><b>Three big guys in the world's smallest taxi</b> - Taxis in Montevideo are divided by a wall and very thick glass, and that wall is very close to the back seat.  Put me, Bruno Souza and Mauricio Leal in the back of one, along with bags and laptops, and, well, it's a fun ride (photo below).</li>
<li><b>Chinchulin</b> - as my friend Fernanda delicately put it, it is a cow's intestine, with its <i>natural contents</i> grilled.  You can see it in the photo with all the meat below (the puffy looking things are cow lymph glands).  What does not kill you makes you strong...</li>
<li><b>Muqueca de Camarao</b> - an incredibly delicious dish made with dende oil, which you can only get in the area around the city of Salvador in Brazil (photo below)</li>
<li><b>NetBeans wire-art</b> - we paid a jewelery-maker in a street market to bend the word NetBeans into a piece of wire (photo below)</li>
<li><b>Sumo Wrestling Robots</b> - I missed this personally, but next to our Solaris talk the other night in Montevideo was a room full of robots programmed by students to sumo-wrestle.  That's tough competition for an operating system talk, no matter how good.</li> 
</ul>
<p/>
Our makeshift translation rig is working out quite well - the announcements mention than anyone who wants simultaneous translation should bring a walkman or other FM radio.  We have a small FM transmitter, and a microphone preamplified through a laptop.  It really works.  Bruno and Mauricio are the true heros, as they both do their own talks and also translate for us gringos.  That adds up to about 10 hours of talking a day!
<p/>
We are currently in Buenos Aires, Argentina, where we did a talk at a university this morning, and the Solaris talks are happening now - I skipped out to an Italian restaurant where I could catch up on email and write this.  Tomorrow on to Cordoba, and then Santiago, Chile.  At this point we're really hitting our stride, with the talks and the timing of them tuned pretty well.  If anyone wants to hone their speaking abilities and put a fine shine on a presentation, I highly recommend doing it every day for weeks on end on 2-4 hours sleep.  I'm really not complaining - this is a great trip!
<p/>
So we are flying to Cordoba tomorrow, and we have just learned that 90% of the pilots for the Argentine airline are on forced vacation as of today, for working too many hours above safety regulations.  So most flights are cancelled, and we need to be doing a talk there at 8AM day after tomorrow.  And that is the airline we are flying tomorrow.  So tomorrow will be an interesting day - we are considering renting a car and doing an eight hour road trip across Argentina, or going by bus, or finding another airline (which surely everyone else is also trying to do).  More will be revealed...
<center><i>
<img alt="netbeansFlan.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/netbeansFlan.jpg" width="480" height="360" />
<br/>
NetBeans:  The Flan
<p/>
<img alt="meatMontevideo.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/meatMontevideo.jpg" width="480" height="360" />
<br/>
Lunch in Montevideo (the fluffy looking things are cow lymph nodes)
<p/>
<img alt="needMoreCoffee.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/needMoreCoffee.jpg" width="480" height="360" />
<br/>
I need more coffee if you want me to talk for five hours
<p/>
<img alt="taxi.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/taxi.jpg" width="480" height="360" />
<br/>
Mauricio, Bruno and 1/10 of me, in the world's smallest taxi
<p/>
<img alt="muqueca.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/muqueca.jpg" width="480" height="360" />
<br/>
Moqueca de Camaraoes - quite possibly the best food on earth
<p/>
<img alt="trashMontevideo.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/trashMontevideo.jpg" width="480" height="360" />
<br/>
Trash collection in Montevideo
</i></center>]]>

</content>
</entry>
<entry>
<title>NetBeans Goes to South America!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/10/netbeans_goes_t.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-10-30T11:14:20Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8517</id>
<created>2007-10-30T11:14:20Z</created>
<summary type="text/plain">We&apos;ve begun the South American University Tour.  This will be a break-neck schedule, whirlwind tour of universities in South America - covering 9 cities in Brazil, two in Argentina and one each in Uruguay and Chile.  If you&apos;re in any of these cities, come join us for a NetBeans and Java extravaganza...</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[We've begun the South American University Tour.  This will be a break-neck schedule, whirlwind tour of universities in South America - covering 9 cities in Brazil, two in Argentina and one each in Uruguay and Chile.
<p/>
I drove the <a target="map" href="http://netbeansday.org/RoadTrip/">NetBeans Mobile</a> to its destination last week, arrived in Massachusetts on Thursday;  unloaded it all day Friday, and flew to Brazil on Saturday.  A steady diet of vast quantities of barbecue (the death-by-meat approach to dining), tiny cups of super-sweet coffee and Guaran&aacute; soda is keeping me vertical.
<p/>
We began yesterday in São José do Rio Preto, with a crowd of 102 for five hours covering an intro to Java, Open Source and NetBeans.  It's fun doing an intro-to-Java talk - a nice change from what I'm usually doing, and some of the students have some programming experience but not necessarily Java.  So I get to go into the history of programming, languages, computer science, how programming languages have evolved, what Objects are, why there is <code>equals()</code> and <code>hashCode()</code>.  Believe it or not, it's a fun topic.
<p/>
Waiting at the airport I think I hit on a useful metaphor if you want to explain what multi-threading in programming is, to someone new to it:  You get off an airplane.  You are one thread of execution.  The folks taking your bag off the plane and loading it on the conveyer belt are another thread of execution.  Ideally they get done at the same time, and you walk up and your bag is there.  Sometimes no;  so the threading constructs in Java allow you to handle those cases.
<p/>
I like teaching through metaphor - my grandfather had my wiring up circuits when I was four years old, and he used metaphor heavily:  think of the electricity in the wire as water running through a pipe - current and voltage mapping to water pressure and how much water comes out - and a four year old can understand it (with a demonstration or two at the kitchen sink if needed).  It's necessarily imprecise, but it gives people a handle to grab onto.  So when I'm teaching or presenting, I really just try to channel my grandfather and ask myself how he would have explained things.
<p/>
As I write this, we are getting ready to land in São Paulo, to connect and fly to Brasilia.  The sheer expanse of São Paulo is astounding - I'm looking at tall buildings like twigs stretching out to the horizon.  Alas in my high-speed moving and unpacking chaos, I forgot to pack my good camera - so I'll either borrow one, or go luddite and try to find a good used SLR.
<p/>
We'll spend the afternoon doing the NetBeans road-show there, and then it's on to Fortaleza this evening.  And I hope to learn a little Portuguese this time around - with a month in Brazil there is no excuse not to.  My seven years of Spanish,  19 years neglected and buried under Russian and Czech ought to help a little if I can dredge it up!
<p/>
Our schedule for the trip:
<ul>
<li>October 29: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=S%C3%A3o+Jos%C3%A9+do+Rio+Preto,+Brazil&ie=UTF8&ll=-20.757398,-49.379425&spn=0.430191,0.977783&z=10&iwloc=addr&om=1">São José do Rio Preto, Brazil</a></b></li>
<li>October 30: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Brasilia,+Brazil&ie=UTF8&z=9&iwloc=addr&om=1">Brasilia, Brazil</a></b></li>
<li>October 31: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Fortaleza,+Brazil&ie=UTF8&z=10&iwloc=addr&om=1">Fortaleza, Brazil</a></b></li>
<li>November 1: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Salvador,+Brazil&ie=UTF8&z=10&iwloc=addr&om=1">Salvador, Brazil</a></b></li>
<li>November 5: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Montevideo,+Uruguay&sll=-12.970382,-38.512382&sspn=0.5982,1.171417&ie=UTF8&z=10&iwloc=addr&om=1">Montevideo, Uruguay</a></b></li>
<li>November 7: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Buenos+Aires,+Argentina&ie=UTF8&z=9&iwloc=addr&om=1">Buenos Aires, Argentina</a></b></li>
<li>November 9: <b>Cordoba, Argentina</b></li>
<li>November 12: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Santiago,+Chile&ie=UTF8&z=10&iwloc=addr&om=1">Santiago, Chile</a></b></li>
<li>November 14: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Florianopolis,+Brazil&ie=UTF8&z=11&iwloc=addr&om=1">Florianopolis, Brazil</a></b></li>
<li>November 16: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Natal,+Brazil&ie=UTF8&z=11&iwloc=addr&om=1">Natal, Brazil</a></b></li>
<li>November 19: <b><a target="map" href="http://maps.google.com/maps?f=q&hl=en&geocode=&time=&date=&ttype=&q=Porto+Alegre,+Brazil&ie=UTF8&z=10&iwloc=addr&om=1">Porto Alegre, Brazil</a></b></li>
</ul>
And for those not interested in Java, the morning five hours at each university cover <a href="http://opensolaris.org">OpenSolaris</a>, and we have a kernel engineer presenting - so this is the real deal!
<center>
<img alt="congonhas.jpg" src="http://weblogs.java.net/blog/timboudreau/archive/congonhas.jpg" width="640" height="480" />
<br/>
<i>The view from the restaurant in Congonhas airport - doesn't really show the scale of the city, but can give an idea of what the buildings look like</i>
</center>]]>

</content>
</entry>
<entry>
<title>The Return of the NetBeansMobile</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/10/the_return_of_t.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-10-23T20:15:49Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8479</id>
<created>2007-10-23T20:15:49Z</created>
<summary type="text/plain">Like a phoenix from the ashes, perhaps like NetBeans itself, the NetBeans Mobile is once again on the road - I just uploaded my first new photos of the white lines in the middle of the road :-)</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[Like a phoenix from the ashes, perhaps like NetBeans itself, the NetBeans Mobile is once again on the road - I just <a href="http://www.netbeansday.org/RoadTrip/rt/Home/">uploaded my first new photos</a> of the white lines in the middle of the road :-)
<p/>
I owe a huge thanks to the folks at <a href="http://www.jantzauto.com/">Jantz Auto</a> in Kenosha, Wisconsin who put a new engine in it over the last month - and were kind enough to notice that the clutch was shot and that they had new-old parts for it, and so threw in a new clutch at no charge.  She's running like a champ!
<p/>
Unfortunately I likely won't be able to do any stops along the way for this part of the trip - I need to make good time, get back to Massachusetts, drop the truck off (probably without time to unload it) and get on a plane for Brazil for a university tour we're doing there.  But I haven't forgotten the folks from the Ann Arbor and Albany JUGs - Albany is easy, since I'll be living in Northampton, MA;  and we'll figure something out for a visit to Ann Arbor down the road too.
<p/>
It's sunny and warm and a perfect day for driving, so, back to the road!]]>

</content>
</entry>
<entry>
<title>The NetBeansMobile goes on Hiatus</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/timboudreau/archive/2007/09/the_netbeansmob_2.html" />
<modified>2008-06-24T19:17:03Z</modified>
<issued>2007-09-14T17:08:28Z</issued>
<id>tag:weblogs.java.net,2007:/blog/timboudreau/181.8244</id>
<created>2007-09-14T17:08:28Z</created>
<summary type="text/plain">With a blown engine in Kenosha, Wisconsin, the NetBeans Mobile is going for a bit of TLC for a few weeks, but will be back on the road in October.</summary>
<author>
<name>timboudreau</name>

<email>tboudreau@sun.com</email>
</author>
<dc:subject>Community: NetBeans</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/timboudreau/">
<![CDATA[With a blown engine in Kenosha, Wisconsin, the NetBeans Mobile is going for a bit of TLC for a few weeks, but will be back on the road in October.  For the gory details, see <a href="http://www.javalobby.org/java/forums/t101453.html">the JavaLobby thread</a>.]]>

</content>
</entry>

</feed>