Tuesday, September 18, 2007

At Work

It's purest trivia, but Margaret Bamberger sent a few photos of me at work, shooting panoramas on the ranch. It's not a perspective I've ever had before, not least because, like anyone without prehensile eyes, I can't see the back of my own head, which may be its best side.

The panorama being shot above was a complete failure, due to a wind that just would not stay gone long enough to let me shoot the whole thing before it resumed waving the near-field trees back and forth. And I waited hours. I did, however, manage to shoot that scene successfully months later: Bamberger Ranch, Jacob's Ladder Tank, David's Overlook. If you've seen the book Water from Stone, that's the scene David and his dog would have seen from their location in the sketch on page 46. Except that those bloody trees hadn't grown large enough to be in the way, back then. It must have been a much better view without them.

The panorama I was on my way to shoot in the photo above, "Bamberger Ranch, West Slope Middle Grassland, no. 2", turned out very well, I think, and after only two takes. I had to be careful to walk out into the hip-high grass in such a way that my trail would not be visible in the pano, so I moved along the fence first, then zig-zagged my way into the scene.

That panorama will be one of the four that I'll have on display (and on sale) at the Lady Bird Johnson Wildflower Center, from October 6th to November 11th. I wish I'd been able to show more than four, but those 60" X 18" archival-grade canvas prints are expensive, and four was about all I could manage. If they sell well, I'll be able to print additional works for future shows. If not, ouch ... but the walls of my house have never looked better. By the way, all of Margaret's sketches from Water from Stone, and then some, will also be on display/sale, including the aforementioned item on page 46.

Friday, September 14, 2007

Exhibition goes Bamberger-free

I've just learned that our exhibition of Bamberger Ranch-related drawings and photographs, which opens October 6th, at the LBJ Widlflower Center, will be a Bamberger-free zone on opening day, even though the core of the show is Margaret Bamberger's drawings. Unfortunately, more pressing business, in the form of Margaret's cancer treatments, has undone our best laid plans.


(And good luck, Margaret.)

That misfortune notwithstanding, all of the planned works, Margaret's included, will be on display on day one (and available for purchase, by the way). so the show will go on.

Thursday, September 13, 2007

Country Lifestyle article

I received my complementary copies of the October issue of Country Lifestyle magazine this afternoon. The article on the Bamberger Ranch uses eight of my photos, including five panoramas. Several of the panos are used as page background, so you can't get a good look at them, but they're there.

For the record, the pictures that include people (the Bambergers, specifically) are not mine. Those were taken by the article's author, Susan M. Sander. So, the credit should actually read something more like "most photos by Chris Johnson". That's not ideal, but it is a big improvement over the magazine's web site, which initially gave credit for the article to someone named "Beverly Burmeier" and credit for the photos to a "Scott Vallance".

Anyway, it's a nice article, and the folks at the magazine did a good job with the layout, so I'm pleased with the result. The curious among you can find the magazine at some of the larger book stores like Barnes & Noble. However, the distribution may be regional, so this may not apply to folks outside the general vicinity of Texas.

Wednesday, September 12, 2007

That's Java internationalization? Really?

In an effort to knock-off one last, major item from Qwicap's "to do" list before version 1.4 is released, I've begun trying to internationalize it. As I currently conceive the problem, this mostly involves removing from the code the error messages that Qwicap automatically adds to a web application's XHTML pages. For example, there's the message that the various numeric input retrieval methods (Qwicap.getInt, Qwicap.getDouble, etc.) add to pages when input is outside of the application-defined valid range of values: "The number must be in the range 0 to 100 (inclusive). The number '900' is not in that range." Complicating matters a bit is a standard feature of Qwicap that automatically replaces phrases like "The number" in such messages with the label of the relevant form control, as found in the web page, if there is such a label in the page.

I knew that there were internationalization features somewhere in Java (I'm using Java 1.5, by the way), but that's almost all that I knew. (I haven't made a serious effort to internationalize anything since my Macintosh programming days.) So, I worked my way through my colleagues until I found one who knew more than me on this subject, and doing some follow-on Google searches and related reading, I learned that the basic facility in Java for abstracting language-specific text from one's code is the ResourceBundle, and, typically, the PropertyResourceBundle subclass, which loads language/nation-specific text from a hierarchy of "properties" files.

So I now understood that, for a start, I needed to setup a properly named and formatted "properties" file for PropertyResourceBundle to discover and load. And the documentation for the PropertyResourceBundle class promptly referred me to the Properties class for information about character encoding issues. The main issue, it turns-out, is that the Properties class only supports one character set, ISO-8859-1. Therefore, if you need to represent any non-Latin characters, a cumbersome Unicode escape sequence must be used for each and every one of them. I find an internationalization "feature" designed without direct support for non-Latin characters tough to take seriously, and in a language like Java, which uses Unicode natively, such a design beggars belief. Of course, we all having things in our past that we wish we could go back and do differently. Maybe this is one such thing for the Java platform.

Fortunately, Java 1.5 added to the Properties class a method for loading "properties" from XML files, and XML can be represented in any character set, since the XML declaration (for example: <?xml version="1.0" encoding="UTF-8"?>) can tell an XML parser how its characters were encoded. It appeared that the problem was solved.

Of course, the problem wasn't really solved, because it turns-out that the PropertyResourceBundle class does not support XML "properties" files. The solution to that problem seemed to be creating a subclass of ResourceBundle that does support them. And creating that subclass looked straightforward at first glance - just create appropriate implementations of the abstract methods handleGetObject and getKeys, then declare victory. Unfortunately, doing so is nearly useless, because the static ResourceBundle.getBundle methods that implement the hierarchical search for language- and/or nation-specific resource bundles, and which then instantiate the list of appropriate ResourceBundle subclasses that are necessary to represent the hierarchy of potentially applicable resource bundles, have their choice of subclasses hard-coded into them. So, they can instantiate the built-in ListResourceBundle and PropertyResourceBundle classes, and nothing else.

Having come that far, I couldn't admit defeat, however, so I took the time to completely re-implement the ResourceBundle.getBundle(String, Locale, ClassLoader) method in my subclass. I thought that that would finally do the trick, but, I was wrong again, because I'd forgotten that static methods can't be overridden, they can only be hidden. Which meant that the lesser implementations of ResourceBundle.getBundle (getBundle(String) and getBundle(String, Locale)) were still invoking the original implementation of getBundle(String, Locale, ClassLoader), rather than mine. That left me feeling dumb, but creating my own implementations of those lesser getBundle methods would be a piece of a cake, and, with all of the original implementations hidden, I would finally have a subclass of ResourceBundle that looked and acted just like a normal ResourceBundle, but which supported XML "properties" files. So that's what I did (mistaking the light that was drawing ever nearer for the daylight at the end of the tunnel).

At this point, it should go without saying that that didn't work, which it didn't. My IDE almost immediately pointed-out something that I hadn't noticed in the API documenation: the two lesser getBundle methods are marked final, and therefore can't even be hidden by the methods of a subclass. For some reason the primary getBundle method isn't final, but the two little convenience methods that front-end for it, are final. Like so many other aspects of my day's dalliance with internationalization, that seems utterly pointless to me, but there it is.

The only good news at that stage was that hiding those two methods didn't really matter, since I was only going to use my subclass of ResourceBundle internally, and I know to use my implementation of the getBundle method when instantiating it. In fact, having already re-written all of the hard parts of the ResourceBundle class well enough for my purposes, I didn't even need to subclass ResourceBundle anymore; I could pretty much just remove the "extends ResourceBundle" phrase from my class' declaration and be done with it.

On the other hand, the main reasons for not implementing my own resource scheme from scratch at the beginning were (1) the belief that by using the familiar mechanism represented by the ResourceBundle class, other developers would have an easier time understanding my code, if the need ever arose, and (2) the hope that somewhere under all that rubbish lay a core of undiscovered, but wonderful, internationalization functionality, from which my code would benefit. There's some sense to the former concern, but the latter appears to be utterly groundless; if there is anything wonderful below, I haven't found it, and I don't see anywhere left for it to hide.

The niftiest feature associated with using "properties" files for internationalization that I'm aware of, is that the internationalized text can contain MessageFormat patterns. However, that feature is orthogonal to the Properties and ResourceBundle classes, which make no use of MessageFormat, and therefore leave it as an exercise to the developer to make his/her MessageFormat patterns do anything.

By the way, the documentation for the Properties class says of its loadFromXML method and the XML files that it loads: "the system URI (http://java.sun.com/dtd/properties.dtd) is not accessed when exporting or importing properties; it merely serves as a string to uniquely identify the DTD". This turns out to be somewhere between "misleading" and "wrong"; either that DTD really is accessed, or a local copy of it is used instead, because the rules in that DTD are enforced when loadFromXML reads XML. Which makes the XML support in the Properties class useless for my purpose, because the strings that Qwicap needs to make internationalizable frequently contain elements of XHTML markup. Those XHTML elements are well-formed (in the simple sense that any start tags are matched by corresponding end tags), so they would pose no problems for an XML parser that wasn't trying to enforce the rules in a DTD, but, sadly, that is not the case here.

Qwicap's XML engine made implementing my own support for XML "properties" files a trivial matter, but the end result of doing so was that, of the three Java classes that appear to be the cornerstones of Java of internationalization (ResourceBundle, Properties, and MessageFormat), I had to re-implement two of them to get an internationalization capability that was useful to my application.

Maybe my requirements are unusual, but they boil down to nothing more than supporting encodings other than the obviously limited ISO-8859-1 for my application's internationalized text, and needing to include XML (specifically XHTML) elements within some of that text. Neither requirement strikes me as remarkable individually, or in combination.

I'm new to Java internationalization, so it's easy to believe I'm missing something. Please set me straight if I am. If I'm not, put me down as lightly stunned by the substantially roll-your-own character of the Java platform's internationalization "solution".

Friday, September 7, 2007

Shooting Perseids in Armadillo Central

I went out to the Bamberger Ranch to do a bit of Perseid watching—and, with luck, photography—shortly after midnight on August 12th. Unfortunately, the peak of the shower was a day later, but on the plus side, the conditions were perfect when I went out, and the conditions for the peak were forecast to be partly cloudy.

Wanting a picturesque old windmill to include in the photos, and reasoning that the highest point on the ranch had to be a good vantage point, I headed-up to the area of the ranch known as the "red pens". As I bumped along the gravel road leading up there, I was surprised to be delayed by traffic. It was dark, squat, short, and moving at about one mile per hour. I could only see its back end. As it walked, there were flashes of light alternating right and left as the headlights reflected off of the light-colored pads of its feet. I couldn't figure-out what it was, but it plainly didn't consider pickup trucks to be among its natural enemies, and deference was due, since I was the one trespassing on its home (the approvals for my visit from the ranch staff, notwithstanding). Our encounter lasted several minutes before the critter veered off onto a trail through the several-foot-tall grass alongside the road. As it turned and vanished into the grass, I finally realized what I'd encountered: a porcupine. Somewhere in the back of my head I knew that they lived in these parts, but this was the first time I'd ever seen one.

Once the traffic let-up, I completed my journey to the windmill and began setting up my gear: camera, cable release, tripod, and a cheap, folding lounge chair that I'd acquired earlier in the day. I'd chosen a spot out in the grass that silhouetted the windmill against a slightly illuminated patch of sky, just to make sure that it showed-up clearly in the photos. With an f1.8, 20mm lens focused on infinity, and the camera set for 30 second, ISO 400 exposures, I locked-down the shutter release button on my cable release, and let the camera take back-to-back raw exposures for the next three hours, when the battery finally gave-out.

During that time, I laid out flat on the cheap lounge chair, relaxed, and did my best to watch the whole sky for meteors. The night was splendidly quiet, in a way that is still a little surprising to this city boy. But I hadn't picked that spot for its quiet, I had picked that spot (leaving aside the windmill for a moment) in the hope that the population of rio grande leopard frogs living in the circular concrete watering trough nearby would sing while I counted meteors. As I occasionally walked back to my truck for one thing or another, I could see them piled-up on the rebar cage that protects the float valve which is the center of their world, both literally and figuratively. I could also see them scattered here and there on the concrete lip of the trough, and floating at the surface of the water. I worried at first that I might frighten them all back into the water, but most of them just went about their regular business of sitting very still and staring at things. That regular business should also have included mating, and the prelude to that should have been singing, but apart from one tentative grunt, they were a complete disappointment. Maybe that bunch of frogs never does much singing; when your world is only about six feet in diameter, you may not need to sing in order to find a mate; you may not need to do anything at all.

One of those Rio Grande Leopard Frogs from a previous visit to the windmill

Though the frogs were a let-down, something out in the thick grass around me was making sounds from time to time, and it wasn't the crickets. No, this was something that made a sort of muted snort from time to time, a bit like something clearing its nose. The snorts always came from different locations, yet there was no sound of movement through the grass in-between snorts. It was a pleasant little mystery as I counted meteors and the camera clicked away the hours. In time, however, there was a snort from only about three feet away to one side, near where my camera bag sat, and the tripod was setup. That, I thought, ought to be something I can investigate, and ought to investigate before it blunders into the camera equipment. With a red-light flashlight, I illuminated the grass over on that side and saw nothing, but I soon noticed that at the foot of my lounge chair, there was a large armadillo nosing its way through the thick grass. Amazingly, to me, its progress through the grass was silent. Apart from the occasional snorts that I'd been listening to all night, it didn't make a sound. My armored acquaintance gave my chair a quick sniff, decided it was neither friend, nor foe, nor dinner, and continued on its way, seemingly completely indifferent to my presence. Apart from wishing that I'd had the foresight to stop at the grocery store and pickup a box of armadillo treats before heading out to the ranch, I was enormously pleased to have not just seen, but more-or-less met an armadillo – a species that most of my fellow Texans and I encounter exclusively as road kill.

It must be armadillo central up there, because variations on that encounter continued. In one case, I found an armadillo working the grass under the lounge chair I was laying on; in the red light of my flashlight, I saw it through the cheap, transparent vinyl of the chair. It looked up, gave the vinyl a sniff, then silently sauntered away into the grass. Before I gave up meteor watching that night, there were a total of four armadillo visitations.

But what of the meteors? I counted about 80 in the three plus hours before the camera's battery finally gave-out. I was dead tired by that time, but might have changed the battery and continued, had I not found that the lens had completely fogged-up with dew over the course of the previous hours. Fortunately, it turned out that the dew only ruined the last hour of photos, and I did catch a few meteors in the preceding time. I have yet to take my definitive meteor picture, but I did add one more photo to my tiny collection of almost-acceptable meteor shots, as you can see below. Click to see the larger version of the image; theses almost-acceptable meteors don't put on enough of a show to look good in thumbnails.