It’s been a few weeks since I last updated; shoehorning blog updates into my packed schedule has presented a formidable challenge. Speaking of challenges, I’m staring down the biggest one of my project: the graphical user interface (GUI). I’ve decided to implement it using the Java Swing libraries, a fairly robust toolkit for implementing a GUI using various components like windows, buttons, text fields, etc. I’ve gathered that Java has a bit of a bad rap when it comes to GUIs. I posted a status on Facebook asking for some Java GUI framework recommendations, and my super-duper-CS-genius friend commented “Java GUI = : X.” Indeed, he was the only one to leave any feedback.
Several hours of Swing-grappling later, I can see why people say it’s a frustrating library to use. I’ve found it overwhelming – maybe it’s a bit too robust for my purposes. The libraries are so huge that they get idiosyncratic. For example, if I want to make a button that looks like plain text, I have to write,
button.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
Kinda gross, right? The good news is that I can write a method that will invoke these changes on any button object. I had the privilege of teaching a discussion section of Stanford’s introductory programming class CS106A last quarter, and decomposition was one of the things we emphasized most. Breaking a problem or task down into smaller pieces not only makes the task of solving the larger problem a whole lot easier, it makes code that’s much easier to read and to reuse. To be fair, decomposition is a central concept of programming style, but it’s still validating to have these moments where I draw directly from ideas in CS106A.
I installed a plugin called WindowBuilder into my version of Eclipse (the program that I write my code in) that allows me to graphically assemble a GUI, which is so much easier than typing this stuff from scratch. Unfortunately, the code it generates is absolutely hideous, and will definitely require a lot of renaming and reorganizing to be anything maintainable or readable. I’m trying to keep this application as well-documented and easy-to-update as I can. If it’s successful, I suspect the SHPRC will keep using it for a long time, and I want to make things as simple as I can for anyone who might need to make changes down the line. To get a sense of how WindowBuilder and Swing work, I put together a nonsensical GUI. Here’s my handiwork with a view of (and some comments on) WindowBuilder:
Click for full-size view!
At the moment, I’m trying to wrap my brain around a design paradigm called Model-View-Controller. The idea is basically that a user’s interactions with a program shouldn’t directly modify the underlying data. Instead, those changes need to be mediated by a “creamy center,” (like the frosting that holds together an Oreo cookie) called a “controller.” Sadly, I can’t take credit for that delightful Oreo metaphor, which comes from the gimmicky-but-great book Head First Design Patterns. At any rate, MVC offers several benefits, from more easily reusable code to safer data access. The hard part for me has been understanding exactly what the relationships between the model (underlying data), controller (“glue code”), and view (user interface) should be and how that maps onto my particular project. The good news is that I think I’ve finally got a grasp on it.
Oh yeah, I’ve also solved my launching-applications-on-Mac-is-awful problem. I’ve started opening everything from Terminal with the “open -a <application name>” command. A year and a half ago, who would have ever thought I’d be like this?
It was annoying, sure, but I must admit that I felt both a hint of sense of self-satisfaction for recognizing that error as a null pointer exception and the little surge of confidence in my own abilities that I always feel when I see bugs in professional code.