One of the trials and tribulations and also one of the fun challenges of my job is that I get vague bug reports on something the QA person sees sometimes and not others. Our QA people don’t do a very good job of tracking exactly what they did and what they did differently between the ones that work and the ones that don’t. Ok, sometimes that’s our fault as developers for not logging enough, but it would be nice if they could tell you, for example, that the one that didn’t work used to be on the schedule before it was removed from the schedule while the one that does work has never appeared on the schedule.
Today I get a bug report “I’m not getting a tooltip on the content table”. The last two columns in the JTable have simple checkboxes that give you some basic data, but if you hover the cursor over, you’re supposed to get one of those little popups (called a ToolTip in Java). Ok, I know I’m getting tooltips, and I don’t remember any recent changes in that code, so I phone up the QA person to ask what she’s doing different from before. And she informs me that she’s not seeing the problem any more, so she’s marking the problem as intermittent. I ask what changed in between when it worked and when it didn’t, and she has no idea.
So I put that bug report aside and start to work on another one. For this other one, I need to get rid of all my content and just load the ones I’m interested in. And suddenly, my tooltips go away. But I’m still getting tooltips in other JTables, just not in this one. Hmmmm. A bit of investigation shows that sure enough, when I’ve got lots and lots of content, I get tooltips, and when I’ve only got 4 items I don’t. At first I wondered if the difference was that when I have lots of items in the table, the JScrollPane that the JTable lives in doesn’t have a visible scroll bar, but that doesn’t make sense because other JTables have tooltips whether or not they have visible scroll bars.
Thus it was time to attach to the app with Eclipse’s remote debugger. And for some strange reason, my breakpoint in getToolTipText(MouseEvent evt) wasn’t breaking. Which baffled the hell out of me. After some more metaphorical tearing out of my hair, I finally decided to recompile the jar in question with the “-g” option, and lo and behold now my breakpoint actually breaks. And then it hit me like a smack in the face.
public String getToolTipText(MouseEvent evt)
{
Point point = evt.getPoint();
int row = sorter.modelIndex(rowAtPoint(point));
int column = columnAtPoint(point);
if (column < 0 || column > data.size())
return null;
You Java programmers in the audience probably spotted it right away. I evidently saw this code dozens of times and never noticed it. That last comparison there? I’m checking the current column, and checking to see if it’s greater than the number of rows. Real smart. If you had fewer rows in the table than the number of columns, you don’t get tooltips.
I changed that check to compare the current row to the number of rows, and things work much, much better.
Shouldn’t rows and columns (indices, counts) be different types to prevent just that sort of error?
“Strong typing is for programmers with weak memories.”
Talk to the Swing designers. rowAtPoint and columnAtPoint are methods in JTable, not in my code.
I’m impressed at the intuitiveness in the name of the data.size() whatevertheycallamethodinjava. Seeing a wetcamij called size() and realizing it’s a rowcount is not the sort of thing that would leap out at me as an obvious bug, except in the original naming of the wetcamij.
Well, “data.size()” isn’t the normal way of getting how many rows. To be strictly OO-ish, I’d make a TableModel and call the method getRowCount(). But I didn’t need all the capability of a TableModel so I just have a simple ArrayList called “data”.