Madness and the TableModel

What fol­lows is a lengthy rant about a par­tic­u­larly annoy­ing sit­u­a­tion in some of my code. Pro­gram­mers, please let me know — is it the toolkit that is mad, or is it me? Every­one else, feel free to skip it! :)

For one of my cur­rent Java projects, I am using a toolkit that comes with its own com­plete set of GUI wid­gets based on Swing. Swing… and horror.

I was under the impres­sion that man­ag­ing a table in any sane OO lan­guage goes a bit like this:

  1. Cre­ate a class that roughly rep­re­sents, or at least holds the data for, a row of the table.
  2. Cre­ate a “Table Model” or some other kind of back­ing array to hold objects of that class.
  3. Cre­ate a Table wid­get that uses the table model as its data source.
  4. Hap­pily fil­ter and sort away, know­ing that the model and the view are com­pletely sep­a­rate entities.

And if you should want to seri­alise the data behind the table to disk, and load it again, you can just save and reload the model, then call some update method on the table itself to let it know that the model has changed.

Bring on the horror!

What this toolkit does, allegedly in the name of MVC, is this:

  1. Cre­ate a class that roughly rep­re­sents, or at least holds the data for, a row of the table.
  2. Cre­ate a “Table Model”, but com­pletely ignore it.
  3. Name the columns of the table after the inter­nal mem­ber vari­ables of the class you have created.
  4. Add each object to the table in turn, watch­ing in agony as it extracts the val­ues of those mem­ber vari­ables, and puts them into the table as Strings, dis­card­ing the orig­i­nal object in the process.

But wait, what if those mem­ber vari­ables are (sen­si­bly) pri­vate? Oh, no wor­ries. It uses reflec­tion, each and every time you add an object to the table, to fig­ure out what the get­ter method for that vari­able is called.

And then we come to want­ing to seri­alise the data to disk. Well, that could be a prob­lem — the table doesn’t con­tain the objects we want, only Strings. Oh, no wor­ries. You can give the table a new instance of your object, have it fig­ure out (again, at run­time) which the appro­pri­ate set­ter meth­ods are, and run those to make your object again!

Oh, hey, I hope that object didn’t con­tain any vari­ables that weren’t in the table. ‘Cos if so, you’re not get­ting them back.

Luck­ily in my case, every­thing I care about is shown in the table, which only leaves the attempt to seri­alise it.

Now I want to have a sin­gle class that nicely encap­su­lates this seri­al­is­ing busi­ness for all tables, regard­less of what the objects expressed in that table are. Nor­mally, one could just seri­alise the TableModel and be done with it, but now we need to dynam­i­cally re-make the objects based on what’s in the table.

For a fully encap­su­lated solu­tion, I really want to be able to just pass in the table and have the seri­aliser take care of the dif­fi­cult stuff. i.e. I want to call:

if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
    SerialisedTableFile f = new SerialisedTableFile(fc.getSelectedFile());
    f.save(table);
}

But I can’t, because f.save() now has no idea what kind of object it is sup­posed to be build­ing. So we need to pass f.save() a tem­plate object of the class that it is sup­posed to be build­ing, the only require­ment of which is that it can be cloned to pro­duce the real object that we want to store data from the table in. So we imple­ment the Cloneable inter­face — except that Cloneable doesn’t actu­ally include clone() for some no-doubt genius rea­son. (Not sar­casm, I really do sus­pect that lan­guage design­ers are an order of mag­ni­tude more intel­li­gent than I.)

The end result of all this is that I now have an inter­face that delights in the name ReallyCloneable, which all classes that I wran­gle into tables have to imple­ment. And poor old f.save() looks like this:

public boolean save(Table table, ReallyCloneable itemTemplate) {
    boolean success = false;
    try {
        if (file.exists()) {
            file.delete();
        }
        if (file.createNewFile()) {
            ArrayList<Object> items = new ArrayList<Object>();
            for (int i = 0; i < table.getRowCount(); i++) {
                try {
                    Object o = itemTemplate.clone();
                    table.getItemFromRow(o, i);
                    items.add(o);
                } catch (NoSuchMethodException ex) {
                    Logger.getLogger(SerialisedTableFile.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(SerialisedTableFile.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
            out.writeObject(items);
            out.close();
            success = true;
        }
    } catch (Exception ex) {
        Logger.getLogger(SerialisedTableFile.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        return success;
    }
}

I think it’s about time I started buy­ing Bad Code Off­sets by Direct Debit.

Sizing in Crisis!

It’s always con­fused me a lit­tle how, in most take-away pizza joints, the small­est size is ‘Medium’. Surely, by def­i­n­i­tion, it is not? Maybe it’s some sort of cul­tural adver­sity to buy­ing a ‘small’ any­thing, but then surely they would call the small­est one ‘small’ to coerce peo­ple into buy­ing larger and more expen­sive pizzas?

Any­way, the most impres­sive tak­ing of the bis­cuit belongs to Charmin toi­let paper — now called Cushelle, pre­sum­ably as a stealth mar­ket­ing effort once chavs start nam­ing their daugh­ters after it. The avail­able pack sizes are XL and XXL. Nary a Large in sight. But why, you ask? The rea­son is obvi­ous, if you merely hor­rif­i­cally mis­ap­ply mathematics.

My first assump­tion is that their pack sizes increase expo­nen­tially, as with vol­ume of pizza. So if XXL is 12 rolls, and XL is 8 rolls, L would be… 5.333 — clearly that’s not the way it works.

So we must assume an arith­metic pro­gres­sion, giv­ing that the miss­ing Large size would be 4 rolls, the Medium 0 rolls, and the Small –4 rolls.

Sud­denly, it all starts to make sense. There is no Small size of Charmin toi­let paper packs sim­ply because they can’t afford to pay their staff to come to your house and steal four rolls of toi­let paper every time you buy a Small pack.

The strange thing about all of this is that I’m sober. Per­haps it’s time to rec­tify this anomaly?

Thomas and the Fall of Sodor

This story is rated Super-X, and is thus not suit­able for any­one what­so­ever to read. Flee now if you are in any way likely to be hor­ri­fied by: Fan­fic­tion, Bad fan­fic­tion, swear­ing, vio­lence, death, sex, train butt­sex, Ayn Rand, or the inner­most evils of my mind.

To any­one dar­ing to pro­ceed, I offer only this note of apol­ogy: If you had a tod­dler that forced you to watch Thomas the Tank engine non-stop, day after day, you would go mad too.

Also, I am well aware how wildly this oscil­lates between the Rev. W Audry’s writ­ing style and hor­rid, florid prose. This is because, hav­ing writ­ten what­ever came to the front of my mind for the last two hours, I now never want to look at it ever again.

It was a bit­ter, cold after­noon on the Island of Sodor. Thomas rat­tled along his branch line from one deserted sta­tion to the next, but there were no pas­sen­gers to be seen!


Back at Tid­mouth Sheds, Percy was confused.

“Eh up, chuck,” he said to his dri­ver. “What’s wi’ all t’coal trucks s’afternoon? How come there’s no pas­sen­ger carriages?”

“It’s the Com­mies,” said his dri­ver. “Everyone’s scared they’re gonna’ kick off.”

“What are Com­mies?” asked Percy.

“Well, you know how the nasty diesel engines are always caus­ing con­fu­sion and delay?”

“Yes sir.”

“Well, they’re a bit like the diesels, except that they reject the idea of achiev­ing suc­cess through per­sonal strug­gle and sub­scribe to a rad­i­cal left-wing phi­los­o­phy of shared wealth.”

“Who’s Per­ci­val Snug­gle?” asked Percy.

“Here, read this,” said Percy’s dri­ver, hand­ing him a book. “Now, I’m off home to hide in the cellar.”


The other engines all came back to Tid­mouth Sheds after a long and bor­ing day. Their dri­vers locked the doors and gaffer-taped them shut, leav­ing the engines all alone for the night.

Percy could barely con­tain his excite­ment. “I got me a book!” he exclaimed.

“Read it to us, please!” called the other engines.

Percy, who couldn’t read, passed the book over to Gor­don. All the engines set­tled down to lis­ten to the story.

The Foun­tain­head, by Ayn Rand,” began Gor­don. And he read, and the other engines lis­tened, until dark­ness fell.


That night, Death came to the Island of Sodor. A blaz­ing light off­shore lit up the hori­zons, and all who beheld it were ren­dered blind. A shock­wave blasted across the land, tear­ing trees from the ground, smash­ing build­ings to dust, and tear­ing the roof off Tid­mouth Sheds. And then the cru­elest of all winds blew, car­ry­ing on it a fine radioac­tive ash that set­tled on the ground out­side and inside the dam­aged houses.

“What was that?” asked Thomas.

“Just a storm, silly,” said Gor­don. “We’ll find out when the men come in the morning.”


But the men didn’t come. The sun rose slowly and faintly in the bleak grey sky until it was nearly noon.

“I’m fed up,” said James.

“So am I,” said Thomas, “but we have to wait until some­one comes to open the sheds.”

“Like fuck we do,” said James. “Didn’t you learn any­thing from that book last night? We gotta’ look after ourselves!”

And with that he made steam and puffed for­wards, rend­ing the shed doors to splin­ters in front of him.

“Oh, shit.”

One by one, the other engines bat­tered their way though the doors of Tid­mouth Sheds, and looked out at what had befallen the Island of Sodor.


Wreck­age was every­where. The tracks had sur­vived, but they were almost buried beneath a car­pet of thick cling­ing dust. Build­ings and trees had not been so lucky. As far as their eyes could see, Tid­mouth Sheds was the only build­ing left stand­ing. Every­where else in the yard, there was only rub­ble. And amongst this rub­ble limped a few poor rail­way engi­neers, cough­ing and splut­ter­ing the toxic ash as they went.

Gor­don rolled slowly up to one of them.

“Where is the Fat Con­troller?” he asked.

“Nobody knows, nobody knows!” the engi­neer wailed. “It’s all over now, noth­ing matters.”

“All over for humans, maybe,” said Gor­don. “We engines are made of tougher stuff. Now, I want you to help me.”

“Help you? Why?”

“Why not? It doesn’t mat­ter, you’ll be dead soon enough anyway.”

“You’re right, I sup­pose,” the engi­neer said with a sigh.

“Fol­low me,” said Gor­don, and the engi­neer fol­lowed him around the back of Tid­mouth Sheds.

Before long, drilling and weld­ing noises could be heard.

“What is he doing?” asked Percy.

“I’m going to find out,” said Edward.

Edward chuffed around behind the sheds. There were a few sec­onds’ silence, and then a great crunch and a creak of shear­ing metal.

It was not Edward but Gor­don who reap­peared from behind the sheds, or what had once been Gor­don — now, instead of buffers, he sported six-foot spikes, and an artic­u­lated cut­ting blade arched out from his fun­nel. He looked at the other engines, and chuckled.

“Fools!” he shouted. “I was always king of Sodor’s rail­ways, and always shall I be!”

With that, he steamed out of the yard and on to the cen­tre track of the main­line, and before long he dis­ap­peared over the crest of Gordon’s Hill. But no sooner had he done so, there was an almighty explo­sion from that direc­tion. As smoke begin to crest the hill, the Fat Controller’s trains saw Rhe­neas and Skar­loey com­ing back the way Gor­don had gone. They took the left and the right track, drag­ging between them along the line of the cen­tre track a giant, men­ac­ing, spin­ning sawblade.

“Shit!” exclaimed James. “All of you, back in the sheds!”

He puffed out onto the main line, and posi­tioned him­self on the cen­tre track, star­ing into the eyes and the whirring blade of his enemies.

“I’ve been wait­ing all god­damn year to use this!” he shouted, and with a click and a wheesh of steam, his boiler divided in two to reveal a gigan­tic mini­gun, almost as long as James him­self. The mech­a­nism span up, bar­rels glint­ing in the weak sunlight.

“There’s only room for one Red Engine on Sodor, moth­er­fuck­ers, and that is fuck­ing me!”

A steel tor­rent poured from James as the two lit­tle engines sped towards him, being torn to shreds and their cut­ting blade fly­ing loose, fly­ing down the track towards James, slic­ing through his gun and his boiler, sparking…

The day’s sec­ond mush­room cloud wumphed upwards and rocked the ground.


It was a few min­utes before any of the trains poked their fun­nel out of the shel­ter of Tid­mouth Sheds. In the end, it was Thomas who first plucked up the courage, and first saw the car­nage where the three red engines had met their end.

“Poor James,” Thomas mut­tered. “Your sac­ri­fice will not be forgotten.”

“Damn right,” said Henry. “Now, we’ve got to think. There’s only three of us left now — you, me and Percy. We’ve got to stick together. Who knows how many of them are left out there, dozens maybe. And if Rhe­neas and Skar­loey were any­thing to go by, they could come for us any minute.”

“So what can we do?” asked Percy.

“We take the fight to them,” said James. “We strike before they have a chance to, maybe before they even know what’s going on.”

Thomas was trou­bled. “But that’s not fair!” he said.

“None of this is fair, Thomas,” said Henry. “Life isn’t fair. There’s no karma, God died the sec­ond the humans hit the red but­ton. It’s us ver­sus the world, and I have no inten­tion of losing.”


Their first des­ti­na­tion was the docks, but as soon as they puffed along the top of the cliffs, they saw they needn’t have both­ered. Cranky the crane lay in pieces, pin­ning Duck in place and smash­ing his cou­pling rods, while Salty had been crushed against the rocks.

“Jesus,” said Thomas. “The tidal wave from the bomb must have been scary.”

“Yes,” said Percy. “But it’s done our work for us. Come on, let’s go.”


Next, Henry, Thomas and Percy snuck into the quarry. Fer­gus was there, with his big fly­wheel attached to some form of sling con­trap­tion. Bill and Ben’s dri­vers looked like their skin was melt­ing from the vast amount of radi­a­tion they’d been exposed to but, uncar­ing for their plight, the engines had trapped them inside the quarry and were forc­ing them to work.

“Put the dyna­mite in gen­tly, do it right!” shouted Fer­gus as the dying men fussed about the sling, load­ing it up with explo­sives from the truck behind him.

That gave Thomas an idea. He, Percy and Henry went to fetch some Trou­ble­some Trucks from a nearby depot, then they lined up on the quarry tracks with their trucks in front of them.

“Peep peep!” went Thomas’s whis­tle, and they puffed for­wards, faster and faster.

“What the-” Fer­gus shouted, but before he could say any more the trucks were upon them. The old trac­tion engine was forced back­wards, slam­ming into his dyna­mite truck, which in turn crashed against the quarry walls, and in an instant it was as if the air turned to sand. The sheer rock faces on three sides exploded out­wards in a del­uge of stone, shred­ding Fer­gus, Bill, Ben and a good num­ber of the trucks too.

“Serves those Trou­ble­some Trucks right, too,” said Henry.

“Yeah. Bas­tards,” said Thomas.


“Hush!” Oliver whis­pered to his brake van, Toad. “I think I heard something.”

“Mis­ter Oliver,” said Toad, “I don’t think-”

But there was a faint wheesh of steam from the line out­side their shed.

“Shit! They’ve found us!” whis­pered Oliver.

“We’re com­ing for you, Oliver!” called Percy.

Oliver just sighed.

“Mis­ter Oliver, if I may ven­ture an opin­ion now that our fate is all but sealed?”

“What is it, Toad?”

“If I do say so, Mis­ter Oliver, I’ve always admired your shapely coal-tender.”

Oliver blushed, at a loss for words.

“Mis­ter Oliver, I’ve always wanted…”

“Oh, make love to me, you old fool!” said Oliver, and the two of them buffered up together, even as Henry crashed into their shed, bury­ing them for­ever under the rubble.


Toby knew that the other trains would come for him and his coach Hen­ri­etta even­tu­ally, so it was with glum accep­tance that they faced Thomas, Percy and Henry as night rolled in over the island of Sodor. They had been prepar­ing for the moment for hours, and they knew exactly what they had to do. They rolled slowly out of their shed, pick­ing up steam, get­ting steadily faster.

“Toby!” called Henry. “You’re the last one left!”

“I know!” shouted Toby. He was going fast now, wind whip­ping around his cow-catchers.

“No-one’s faced us and lived!”

“I know!”

“So come on, you’ve got no choice. You’re one of the Fat Controller’s engines! Join us!”

“Join-?”

But Toby was going too fast now. He hit his brakes, but it was too late. Toby and Hen­ri­etta, packed floor to ceil­ing with Sem­tex, plowed into Henry and Thomas and Percy, sparks fly­ing from Toby’s brakes, show­er­ing the explo­sive, turn­ing the world white, then yel­low, then red, then black.


Twenty miles from the coast in his pri­vate yacht Sir Topham Hatt, oth­er­wise known as the Fat Con­troller, stood with his wife and watched the fireball.

“That was the last of them,” he said with a sigh.

“All things must end,” said Lady Hatt.

“Ashes to ashes, dust to dust,” the Fat Con­troller whis­pered, as he engaged the sea­wa­ter pumps and set off the bombs that had been part of the island of Sodor since he had cre­ated it cen­turies before. They would, over the next few hours, return the island to the great wide ocean from whence it had come.

“Oh dar­ling, I love it when you get all… reli­gious on me,” said Lady Hatt, giggling.

Flapjack

OH GOD WHAT THE FUCK. I blame Eric for this.

It was the fourth time that I’d met that lit­tle girl in the alley behind the Coach and Horses. Just as she had each of the pre­vi­ous three times, she stood there in the shad­ows, star­ing at me unblink­ing, dar­ing me to make some­thing of the fact that she was there.

I stag­gered toward her, five pints and six dou­ble vod­kas the worse for wear. She didn’t shy away.

“It ain’t safe for you out here,” I said, just as I always said. “You’re lucky you met me, I’m not so bad, but there’s a lotta’ nasty peo­ple you could run inta’ in dark alleys behind pubs.”

“I’m safe,” she said, just as she always said. “Nothing’s going to hurt me.”

Maybe it was the crit­i­cal twenty-fifth unit of alco­hol doing the think­ing, but this time, I decided to press it further.

“Look, I don’t mean no offense, but you’re what, eight? At most? And it’s half mid­night, and you’re in the alley behind the Coach and Horses. You should be tucked up in bed in your par­ents’ house.”

“Ain’t got no par­ents,” she said defi­antly. “I live here.”

“You can’t pos­si­bly live here. Aren’t you… adopted, or something?”

“No.”

“Then how do you sur­vive? Who gives you food? Who pro­tects you from those nasty guys I was on about? I ain’t kid­ding, this is not a nice part of town.”

“I’ve got my Safety Flap­jack,” she said, clearly pro­nounc­ing the cap­i­tal letters.

I had noth­ing to say on the sub­ject for a full fif­teen seconds.

“Safety… Flap­jack. Not blanket?”

“Flap­jack.” She pro­duced it to make the point. It was about one inch by two, oaty and but­tery and not in the least bit reassuring.

“And this flap­jack keeps you safe?”

“It does.”

“But. But– but.” I stopped mid-thought again. I’d had the wrong end of the keg, that must be it, or that was some dodgy knock-off import vodka. I rubbed at my eyes for a while, and blinked a bit – until I heard foot­steps. And as soon as I had, they were on me.

“Give us yer wal­let and phone, quick!” one of them shouted, grab­bing hold of my jacket and lift­ing me off the ground. I strug­gled, hop­ing I could break free and some­how pro­tect the obvi­ously delu­sional kid. But it was not to be. I was thrown to the floor, and I hit my head pretty bad. The guy who’d thrown me started going through my pock­ets, while the other two advanced on the girl.

“Run home, kid,” one said. “You didn’t see nuthin’.”

But the girl ignored them, and turned to face me.

“You were going to ask how the Safety Flap­jack pro­tects me, weren’t you, Mister?”

I groaned, as I wasn’t really capa­ble of any­thing else by that point.

“It’s because,” she said sim­ply, “when I’m threat­ened, it turns into the Un-Safety Flapjack.”

After that, there was a blur, and some scrap­ing sounds, and a gur­gle. Then there was only darkness.


When I awoke, the sun was already high in the Sat­ur­day morn­ing sky. The girl was nowhere to be seen, and like­wise the mug­gers. All along the walls and the tar­mac of the alley­way, though, there were streaks of blood, and tooth-like gouges, and burnt streaks, and smol­der­ing shards of metal pro­trud­ing from brickwork.

I vom­ited copi­ously, then after ten min­utes of shiv­er­ing and gib­ber­ing, I went about my business.

To this day, I have never seen the girl again. Nor have I drunk in the Coach and Horses. And nor have I men­tioned the case of the Safety Flap­jack to another liv­ing soul, though night after night it still haunts my dreams.