Why Swing? Why not JavaFX?

Published at 22:53 on 30 January 2020

I recently decided to finally take a serious crack at developing a GUI application.

My first choice was to make it a native Mac application, and write it in Swift. I soon was reminded, by fresh personal experience, of what I had discovered the last time I tried to code a native Mac application: that Macs are approximately as programmer hostile as they are user friendly. Documentation was patchy and incomplete. Interfaces were bizarre and counter-intuitive. Worse of all, things change radically from release to release of the OS, to the point that most of the documentation out there is basically useless, because it is for MacOS releases prior to Catalina.

I could have persevered, but it was clear that MacOS app development is a dark art that takes a lengthy and painful initiation process to cultivate. No thanks; I just want to get my app coded and finished. Would have been nice to have a native app that dovetailed as nicely as possible with the rest of the system, but being able to finish it in a timely manner takes priority.

I had in the past year ran across Kotlin, which struck me as a well-designed effort to modernize Java (or, alternately, Scala done right: a more modern language for the JVM that avoids the pitfall of creeping featurism that led Scala to be excessively complex). Java has long supported portable GUI application development, and since Kotlin is a JVM language, you can easily call any of the Java libraries from Kotlin. So Kotlin it was.

It didn’t take that much research to determine that the new and supposedly preferred way to code graphical user interfaces in Java was JavaFX. So I went to the JavaFX web site, downloaded JavaFX, and typed in the “Hello, World” example listed on that site.

It didn’t work. After double- and then triple-checking what I had done, I could see zero discrepancies between what I was doing and what the tutorial was telling me to do.

Noticing that the current release of JavaFX hadn’t been out all that long, I tried regressing to the previous version now on long-term support status. The code still didn’t work.

I tried posting a query on Reddit as to what I was doing wrong. Nobody had any idea.

I reported the bug via the project’s GitHub page. That prompted a curt, incomprehensible, acronym-laded response to file the bug report some other way (and my bug report on GitHub was perfunctorily closed).

Eventually, I got the example code to produce the output it should, by regressing to the version of JavaFX that was distributed with JDK 8. Then I started investigating how I’d code my program in JavaFX.

It quickly became apparent that one of the things I needed to do would probably involve a lot of work in JavaFX, but that there was a Swing UI component that did basically all I wanted, and that it was easy enough to embed Swing components in a JavaFX application. While doing that, I ran across yet another bug in JavaFX.

But why? I had already established that JavaFX is full of bugs, insufficiently documented, and has a development team whose attitude about quality is lacking. Now I learn I can’t even code it all the “new way” even if I desire to, because JavaFX is lacking in basic features as well.

Moreover, it didn’t take much research to uncover that Oracle (the single most important player in the Java development process) makes massive internal use of Swing, and has no plans to remove support for Swing anytime soon. In other words, Swing is definitely here to say; rumors of its deprecation have been greatly exaggerated.

So that’s what I used. Maybe, in a few years, if I have occasion to write another graphical user interface, I will investigate if JavaFX is any closer to being ready for the prime time than it currently it is.

I can tell that some of what JavaFX is trying to accomplish would be a real improvement. It’s a pity that the current state of that project is evidently so lacking in features and quality control, but there you have it.

So Many HTML Parsers Suck

Published at 11:42 on 24 December 2019

Why? They ram a document tree down your throat, that’s why. So you’re stuck writing code that:

  • Consumes more memory, since you must load the entire document in memory at once, and
  • Makes modifying the content tricky, since traversing a document tree you are modifying is a potential minefield. (The alternative is to create an entire new document tree from the old one, which doubles the already sometimes obscene memory footprint.), and
  • Consumes more processor time, because multiple tree traversals are typically necessary.

Slow, bloated, error-prone: In a word, document trees just plain suck. Yes, sometimes they are necessary. That just means they should be a necessary alternative. They should never be the only way you can parse HTML.

Yet, with all too many HTML parsers, they are the only way. And that’s why so many HTML parsers suck.

Why Do My Pictures Show up Sideways (And How Do I Fix Them)?

Published at 11:09 on 12 December 2019

The Root Cause

The root cause of the problem is that there’s a (relatively) new feature in image files from digital cameras which not all software supports. So an image can look just fine when you preview it (because that program supports the feature), yet when you upload it to the Web, suddenly it appears sideways (because many web browsers don’t)!

The Details

Modern cameras contain sensors that tell their on-board computers which way the camera is being held. When it captures an image, the camera records which way it was oriented (portrait or landscape) in the resulting file, but it always writes the image data itself in landscape (larger dimension horizontal) format.

It is considered the responsibility of any program that displays images to read the orientation information and use it to display the image properly, by rotating things if needed. Unfortunately, many web browsers in particular don’t read the orientation information; they simply assume that the horizontal dimension will always be horizontal (because, prior to the new feature, it was).

The Workaround

The workaround is to rotate the file if needed, so that the horizontal dimension of the image data is always the dimension that should display horizontally.

To do this, I use the free image-manipulation program GIMP. It can read the orientation information, and if it encounters a portrait-mode file, will always ask on reading it if it should be automatically rotated. Always answer no to this question! (This automatic rotation is the feature you want to get the image to display properly with without, after all.)

The result will, of course, be a file that displays sideways. Use the rotation options under the Image… Transform menu to fix the orientation. Then use File… Export As to re-save the result as a new file. The result will be a file that always displays correctly.

Kotlin Looks Nice, But…

Published at 18:54 on 17 July 2019

I’m planning on developing an Android app, and to that end I recently downloaded Android Studio. I notice it offers a second option for the programming language of a project, in addition to the expected Java: something called Kotlin.

That prompted me to take a closer look at this language. I’ve worked about halfway through the Kotlin Koans tutorial for the language, and I must say that so far I am quite impressed.

The world needs a more modern alternative to Java. Once I was hoping that C# could serve in this regard, but alas:

  • It falls victim to bigotry (anything that got its start at Microsoft is going to be sneered at in the open source/Unix/Linux world, no matter its merits, no matter that there’s an excellent open-source implementation of it).
  • It runs in its own environment, not the JVM, meaning that switching from Java to C# implies burning bridges. You can’t easily cut over by developing new modules in C# that interoperate with legacy Java ones.

I looked at Scala, which seemed to offer real promise. Then I experimented with it and ran into Scala’s complexity. I was eternally doing battle with the type system, which seemed to frustrate my every attempt to use the language’s powerful features in clever ways.

When I looked at other people’s Scala code for ideas, I was often perplexed, because it was shot through with special features I had not learned yet. Beyond a certain point, it becomes impossible to remember a language’s core feature set. When that happens, readability of code will suffer, because developers will tend to drift apart from each other, each opting to use their own personal idiosyncratic subset of the language’s features.

There is a real cost to programming language complexity, and it is clear to me that Scala is well past the point of diminishing returns when it comes to feature set size.

That brings us back to the subject of this post. Kotlin really seems to be “Scala done right,” addressing the worst of Java’s deficiencies without falling victim to excessive complexity.

Android was Kotlin’s foot in the door, because many Android devices run truly ancient versions of the JVM, versions so old that many of the newer features in Java (without which the language becomes truly dated and obsolete) are absent. The Kotlin compiler can target those old JVM byte codes, allowing one to use modern features even on legacy platforms.

So I’m going to give Kotlin a whirl on my Android app. I will let you know what my impressions of the language are after I’ve had some practice actually coding something meaningful in it.

The pity is that once one does things other than Android software development in Kotlin, the rough edges in its ecosystem quickly become all too apparent. Just out of curiosity I’ve been playing with the Ktor server-side framework. The documentation ranges from flat-out obsolete (and thus incorrect) to simply nonexistent. The result is that even simple things take hours of tedious experimentation to determine how to do.

I’m hoping that Android development goes better, but unless those rough edges get smoothed out, and soon, Kotlin may well end up being stereotyped as an Android-only thing.

And Another Age Discriminator Passes Me Over

Published at 16:55 on 30 May 2019

It’s 17:00 on a Thursday a full ten days from when I interviewed for a job, and not a peep out of them, despite my sending a followup message. So you know what that means: they’re pursuing someone else but haven’t quite finalized things yet. But rest assured the odds are so insignificant they can safely be disregarded: at this stage, I have about as much chance as being hit by a stray meteor.

It’s not really a surprise or anything, but it is annoying, given how good a match the job in question was for my skills, and how well I solved one of the programming problems on the whiteboard. But there’s only so much you can do when not having any gray in your hair is one of the prime qualifications for the job.

And I’m certain the experience is equally frustrating for anyone who’s female, or who’s not White or Asian.  Just keep this all in mind the next time you hear some stuffed shirt from the technology sector whining about a lack of qualified talent.

Apple Mail Searching: Still Broken

Published at 20:13 on 10 April 2019

It’s pretty pathetic. It was back in 2013 that I gave up on Apple Mail, in part because its searching function had gotten more and more broken as the years passed.

The other day I had a chance to use Apple Mail, mainly because while searching works OK in Thunderbird, printing is broken. Well, it works fine if you think it’s acceptable to waste a page of paper printing every damn header in your message in a ridiculously small font.

Really, now: just what’s their problem? It’s a trivial operation to filter out all but the most significant headers before printing. Do most people care about seeing every relay hop the message went through, and its antispam heuristics? No, of course not; most of us just want the message body and a few of the most important headers (time stamp, subject, origination address, and destination address, primarily). Make that the default and have the option of also printing with full headers. Is that so hard?

But I digress. I wanted to print a message without all that extra header crap so decided to print it from Apple Mail. Of course, that meant finding it. No problem: it contained some pretty unique keywords; searching should uncover it in a snap. No dice.

Again: Just what’s their problem? It’s not as if searching for a substring in a file is that difficult a problem to code. Is there some “intelligent” indexing at work? Is there a “smart” search heuristic deciding that my keyword isn’t “important” enough to merit reporting as a match? Who knows, but it’s enough to keep me away from Apple Mail for another five years.

I’ll point out that even Thunderbird is somewhat broken when it comes to searching. The default search function is one of those useless “smart” searches that is always hiding messages because it decides they are not “relevant” enough to match (even though they do). Thankfully, Thunderbird has a Quick Filter option that has a good old-fashioned plain vanilla search. No stupid indexing or “smart” heuristic to get in the way.

Really, if I can remember an unusual keyword or two, I should be able to use it to find a message. Anything that gets in the way of this is a huge step backwards. Come the revolution, software developers who make “smart” searches the only possible option get the guillotine.  They will not be missed.

New Software Won’t Fix the 737 Max

Published at 07:18 on 4 April 2019

Disclaimer: I am not an aircraft engineer. But I am a software engineer, one who looks at my own field with a critical enough eye to see how software is often used inappropriately, and I see the signs of the latter all over the place in this latest story.

The original software didn’t fix its fundamental unairworthiness, so why should new software be able to? The problem with the 737 Max isn’t that it has buggy software, it’s that it should never have been built in the first place. Its safety should come from its airframe being compatible with its engines. It can’t come from a software-and-sensor kludge that tries to compensate for an unsafe physical design.

In an article in today’s Washington Post:

Boeing said it would take about an hour for technicians to load a software update for the planes. The company’s software fixes will change the way the MCAS receives information, requiring feeds from both outside “angle of attack” sensors, rather than one, before it is triggered.

The system will also have more limits on how often it will engage, and Boeing will make changes that prevent the anti-stall feature from angling the plane’s nose too far downward in its attempts to correct for a possible stall.

Let’s take the fix of requiring both sensors to concur. We know the angle of attack sensors are unreliable, because they sometimes falsely indicate an excessive angle of attack. Being unreliable, it seems reasonable to presume that they also sometimes fail to indicate an excessive angle of attack. So this “fix” will actually fix nothing. It will merely trade one form of unsafe behavior for another.

The second fix is in fundamentally the same category as the first: like the former, it makes the system more conservative in deciding when to engage. That system was put there for a reason: the attempt to compensate for an unairworthy plane, whose airframe mismatches its engine size and placement. The physical plane will remain as unairworthy as before, only with less software compensation for it. Again, one problem is merely being traded for another.

Instead of tragedies caused by planes falling out of the sky because MCAS engaged in error, we will have tragedies caused by planes falling out of the sky because MCAS didn’t engage and they stalled.

I strongly suspect the only fix for these planes will be to scrap them and sell their bodies to recyclers, who will turn them into new metal stock from which fundamentally safe planes can be built. Those “fundamentally safe planes” will mostly be Airbus A320neo’s. Boeing’s attempt to get out of the corner they found themselves in the cheap and devious way is going to end up costing that company a lot.

The 737 Max Scandal

Published at 08:18 on 2 April 2019

I was going to make a long post of my own about it, but Vox just preempted me. Executive summary (I encourage you to read the Vox article):

  1. Boeing found themselves painted into a corner by decades-old design decisions whose consequences they couldn’t have foreseen.
  2. Basically, it was not possible to easily and quickly make a safe aircraft that was more fuel efficient, to compete with the new Airbus A320neo.
  3. Boeing should have sucked it up and taken the loss involved in playing catch-up with Airbus.
  4. Instead, they decided to bolt new, more efficient engines on the existing 737 airframe (even though they didn’t really fit) and christen the result the 737 Max.
  5. The new planes had kludges installed (sensors and software) in an attempt to paper over their fundamental unairworthiness.
  6. A corrupt relationship with the FAA allowed the kludged-up planes to be approved and sold.
  7. The inevitable happens.

Really, it should come as a surprise to absolutely nobody that a plane that substitutes good engineering practices based on the laws of physics operating in the real world, for software operating in cyberspace, ends up sometimes startling and surprising pilots, sometimes with tragic results. It should also come as no surprise that said software has bugs, also sometimes with tragic results.

The most important overall rule of software development is that it’s extremely difficult to get right. As someone who’s worked in that field, I know this by first-hand experience.

Setting the Screen Width and Height for BlueStacks on a Mac

Published at 09:35 on 11 November 2018

There’s no way provided to set the screen width and height for the BlueStacks Android emulator. In fact, there’s no settings menu at all.

There’s write-ups how to get around that problem on Windows, but not on the Mac. Hence this post.

  1. After installing BlueStacks, edit the file Library/Preferences/com.BlueStacks.AppPlayer.plist in your home directory. If the file isn’t there, try starting then quitting the BlueStacks.
  2. Make sure BlueStacks is not running.
  3. Open the file in your favorite text or XML editor.
  4. Locate the <key>FrameBuffer</key> element. Everything you need to change is in the dictionary below it.

The items to change are Width, Height, WindowWidth, and WindowHeight. The first two parameters control the size that the Android apps see. The second two control the size of the window displayed on your Mac.

iCloud Mail Frustrations

Published at 21:00 on 24 September 2018

Generally, I like Apple’s iCloud (formerly me.com, formerly mac.com) email service better than Gmail. Unlike Google:

  • Apple doesn’t aggressively spy on users for purposes of marketing to them,
  • iCloud doesn’t have obnoxious security that gets false positives every time I travel or do something a tiny bit out of the ordinary.

But, there is one area where Gmail outshines iCloud like a star outshines a small, rocky planet: its Web interface. iCloud’s web interface positively sucks. It’s prime design goal was apparently to value appearance over all else, and to particularly value it over functionality. It’s bloated in the extreme with fragile AJAX-using Javascript that crumbles the moment your network connection departs from rock-solid. It’s also monstrously inefficient in its use of screen space; one must stretch the browser window to comically wide proportions just to be able to read messages. It’s so painful to use that the feature might as well not be there in the first place.

Gmail, by contrast, at realizes that not the whole world wants to run bloatware in their web pages, and offers a “basic HTML” mode which is actually pretty sane.

I’m hoping to work around the problem by installing Squirrelmail and using that to access iCloud for those times where I don’t want to configure a mail client. Already ran into one roadblock with my connections from one of my servers (a shared one) being blackholed. And I really shouldn’t need to do this: Apple should offer a simple, sane, non-bloated web interface for iCloud.