I just finished coding Version 1.0! Today, I’m going to package it up as a .JAR and leave it well alone for a few days. It’s been a whirlwind of coding these last couple of weeks – expect a meaty update soon!
Lots of work to do, of course, but I’m finally confident that this is going to come together. What a feeling!
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.
There are certain conversations I feel like it’s almost impossible to avoid having if you possess a certain interest. Take photo, for example; I can’t count how many times I’ve had to explain my motivation for shooting film in today’s digital age. And in the world of avid computer users, what of this PC / Mac divide that’s been so carefully constructed as a question of personal identity? As an art-loving writer with a modernist sofa, I might seem like a natural Mac. Growing up, I was. Then OSX came along, my hand-me-down Bondi Blue iMac became obsolete, and I found myself face-to-face with my dad’s old work computer, a ponderous Toshiba laptop running Windows 2000. I was in 8th grade, and I was happy to have a computer that was portable, if only so I could use it on my bed.
Since then, I’ve been a PC. I’ve never much liked the PC / Mac conversation, simply because I feel that the comparison is unhelpful and without much meaning. PCs offer more features at a lower cost, but lack the user-friendliness of software and hardware not only designed together but also specifically designed to be intuitive. Windows, it seems to me, has always been more utilitarian. Take the Windows key, which, as far as I’m concerned, is a stroke of true genius. Whoever thought of it should get a raise. Hold it down and press the arrow keys, and – bam! – pure magic, your windows are hopping from one side of the screen to another, minimizing and maximizing, and you haven’t touched the mouse. The Windows “Start” menu, too, especially with its newer search features, is a much easier launchpad than Launchpad. But Macs sure are beautiful. Ultimately, the operating systems (and, in the case of Mac, hardware) represent different visions of what computing can or should be.
Today, I became a PCMac. They’ve always emphasized in my CS classes how important it is to develop in the OS your program will be tested (or in the real world, run) on, so I thought I should double-check with my advisor that it would be okay for me to develop on my trusty ol’ 2009 Windows 7 laptop even though the program will be used on Mac. It turns out that it isn’t, which, upon reflection, makes a lot of sense. For file reads and writes, I’m going to have to worry about things like end-of-line characters, which are encoded differently across different operating systems. The solution was obvious: buy a Mac. So that’s what I did. I was lucky enough to have a family member loan me the money until I have a full time job, and I’m now the proud owner (well, eventual owner) of a 128gb 13″ MacBook Air. It is beautiful, and it confuses me. I have faith that one of these days, I’ll stop hitting FN every time I mean to hit CMD.
I’ve created and defined my database, with a few schema tweaks here and there from what I had planned, and I’m currently hard at work implementing the main data storage classes of my program, Client, Purchase, and Item. In CS108 lectures, I’ve been introduced to the great beauty that is the Eclipse getter/setter generator, and I’ve already put my new knowledge to good use. It’s also interesting and downright empowering to see how easy it is for me to get these classes up and running. I’m almost embarrassed to say so, but this is the first time I’ve ever written a program from scratch, without any starter code. Nevertheless, I have the overwhelming sense that I know just what I need to do, that I know how to do it, and that I know what to Google when my skills fall short. The real challenge has been learning new tools like Git and getting used to developing with both the terminal and graphical desktop applications. I’m accustomed to such polar ends; Eclipse or Vim, but never both at once. There’s such a utility to it, though. There are certain things that are so much easier to edit in the terminal, things that don’t really make sense to edit in Eclipse, like my SQL CREATE TABLE statements. I’m beginning to feel a confidence that has everything to do with the intuition I’ve developed over the last 15 months as I’ve stumbled, fumbled, powered, and occasionally sauntered my way through programming.
I was proud of myself for solving one of those silly but utterly perplexing problems a couple days ago. I could not, for the life of me, seem to get SQLite to stop telling me that I had syntax errors in my table definitions. I was so sure I didn’t, and I’d checked numerous times. Then I realized that I’d named my table “Transaction,” which is a reserved word! “Transaction” may be most accurate, but I opted for “Purchase” to keep things bug-free. I also learned a new reserved Java word that is now my favorite: “finally.”
I’ve been programming for over a year now, but today marks the first time I’ve ever written a technical spec. Since my work has all been within the context of programming classes, the applications and programs I’ve written have all had stringent functional requirements, and many had equally strict aesthetic guidelines. What’s more, most have laid out a suggested development path, often with obvious hints as to what data structures and algorithms to use. I had my first meeting with my project advisor Prof. Steve Cooper last Monday, and he tasked me with my first assignment: plan my project. The guidelines? Hardly the 3000-word descriptions (seriously) that I’m used to. Instead I got, “Write something that will enable you to create your program.”
So I’ve found myself in that wonderful but daunting place of having near-total freedom to shape something in which I’m heavily invested. Steve told me that I could draw pictures in my notebook for all he cared, but I was pretty sure I’d end up with some gloriously formatted, highly detailed, neatly illustrated document. I did not disappoint myself, but I may well have created several hours’ extra work for myself. A little Googling led me to this quick-and-dirty guide to planning a piece of software, which was a lot more helpful than the idiosyncratically divided, UML-extolling templates I found. Ultimately, this isn’t for anyone but me, so company style and universal readability aren’t priorities.
Since I had a good idea of what I wanted the UI to be like as well as what features I need, I decided to start with a wireframe and then move on to the written portion of the events, updating my wireframe as necessary. I found an online diagramming tool called Gliffy, and I can testify to its utter beastliness. It’s right on that sweet spot of nothing you don’t need and almost everything you do. I’d love the ability to lock and see a list of layers, but working around that wasn’t too hard. Here’s my first hack at a main transaction interface, heavily inspired by restaurant point-of-sale software like Aloha.
Sure beats the kind of result I could achieve using PowerPoint, huh?
The further along I got in my spec, the more I realized how much I learned in my databases class. To be honest, I found several sections of it tedious (especially the section on Boyce-Codd Normal Form and Multivalued Dependencies, which I find much easier to understand intuitively and through real-world examples than through codified formulas and toy data), but I’ve come out of it with a confident grasp on designing databases and writing powerful queries.
I’ve also got a lot of questions about the relationships between backend databases and runtime data structures. It seems inefficient or silly to query a very small database many times to get the information I need, which suggests that loading the database contents into a Java object would be prudent, but I wonder if that’s redundant. Or what about objects on the frontend that could – but possibly shouldn’t – include data. For example, my instinct is to have the product buttons store only the product’s unique ID and get the price information from a product database object, but I might just as easily store the price in the button object, too. The good news is that I’m surrounded by people who can teach me about best design practices and help me make these decisions.
Tomorrow morning, I’m going to try to set a timeline for my project and practice using Git on Windows. Until then, however, I have meetings to attend and Whitman, Mills, and Mailer to read! (And sleep to get, naturally.)