Lead, Anchor and a new ListSelectionModel bug
Today I discovered a new bug in Glazed Lists'
EventSelectionModel
. That class implements
ListSelectionModel
, which a
JTable
uses to manage the current selection. One of these duties is to manage the
lead and
anchor indices, which are used for dragging a selection with the mouse. Where the mouse started the drag is the anchor, where it is currently is the lead. Everything between them shall become selected! Now this all broke down in a fairly simple case. If the user selects an anchor and then filters the list, the
EventSelectionModel
kept that same old anchor index - even if the list shrank so much that the anchor index was out of range. When the user would select a new lead (via shift-click), the incorrect anchor was called upon and an IndexOutOfBoundsException was thrown. This is all fixed now, but it was quite a nasty little bug, and it had been in the code for a long long time.
It makes me wonder:
Had anyone else ever seen this behaviour? It had never been reported.
How many more bugs are in the code?
I'm fairly confident with our code, but it irks me to see that such an obvious bug had stayed hidden so long!
# posted by Jesse Wilson
on Friday, November 26, 2004
1 comments
post a comment
A super() Java Language Hack
I'm creating an EventList called PopularityList that will sort elements by the number of times they occur in the source EventList. I'm extending
TransformedList
, which has a single protected constructor with the signature:
protected TransformedList(EventList source);
To implement PopularityList:
First I create a UniqueList of the source EventList's elements.
Wrap that UniqueList in a SortedList, sorting by the number of duplicates in the UniqueList
But when I combined these two problems in the most natural way, I had a problem:
private UniqueList ul = null;
public PopularityList(EventList source) {
super(new SortedList(new UniqueList(source), new PopularityComparator());
...
}
The problem is that my PopularityList class needs to keep a reference to the UniqueList object created in the constructor. But the two obvious attempts fail to compile. The first solution fails due to "cannot reference ul before supertype constructor has been called":
private UniqueList ul = null;
public PopularityList(EventList source) {
super(new SortedList(ul = new UniqueList(source), new PopularityComparator());
...
}
The second solution is a very slight variation that fails due to "')' expected":
private UniqueList ul = null;
public PopularityList(EventList source) {
super(new SortedList(UniqueList temp = new UniqueList(source), new PopularityComparator());
ul = temp;
...
}
So what did I do next? I paniced! But that got boring so I came up with a clever hack. I created a private constructor that has a parameter for each object that I need to keep a reference to, then I called this()
. It works perfectly:
private UniqueList ul = null;
public PopularityList(EventList source) {
this(source, new UniqueList(source));
}
private PopularityList(EventList source, UniqueList uniqueList) {
super(new SortedList(uniqueList, new PopularityComparator()));
this.ul = uniqueList;
....
}
# posted by Jesse Wilson
on Friday, November 19, 2004
3 comments
post a comment
One Page Whitepaper
I've created a really quick
PDF that gives a fast overview of how sorting is implemented in Glazed Lists. I needed to write such a paper for some accounting stuff at work, but it's fun to post online.
The only problem is that now JDNC and everyone else can learn our secret to sorting performance! But for the time being I don't think that they are interested in our
performance advice.
# posted by Jesse Wilson
on Thursday, November 18, 2004
0 comments
post a comment
POI, hyperlinks, and 2^7
As I
mentioned earlier, I am using
Jakarta POI to create Excel files.
Earlier I warned:
don't use space characters (or commas or pretty much anything else)
limit sheet names to 31 characters
Well today I discovered another unpleasant limitation. The link label must be 127 characters or fewer. If not, POI may throw an exception or create an unreadable file.
I get the feeling that the formula support in POI is still fresh. Hopefully these limitations won't be permanent!
# posted by Jesse Wilson
on Monday, November 15, 2004
0 comments
post a comment
IOException "The handle is invalid"
The pure Java version of our program was working flawlessly. The GCJ-compiled Windows binary was not. It was throwing an IOException, "The handle is invalid". This is caused because InputStream.close() was being called multiple times. By removing a close() call, everything now works correctly.
This raises an important question: who's job is it to close an input stream? For example:
InputStream in = ...
BufferedInputStream bufferedIn = new BufferedInputStream(in);
someMethod(bufferedIn);
bufferedIn.close();
Do I still need to call in.close()?
According to the API, I should
not call in.close() because BufferedInputStream.close() does that for me.
# posted by Jesse Wilson
on Monday, November 15, 2004
0 comments
post a comment
Filter Faster
The filter classes in Glazed Lists have received a shitload of attention lately.
First, James Lemieux implemented Boyer-Moore in our TextFilterList class. His efforts led to a 20-50% performance boost. James is currently working on refactoring the TextFilterList and AbstractFilterList classes which may lead to further performance increases.
Now today Kevin finished the first phase of our new data structure which manages filtering. In a test program with 2,500 list elements, filtering was 10% faster. With 250,000 elements, filtering was twice as fast!
This is a very exciting time for Glazed Lists. In the last two weeks there has been more code written by Kevin and James than I have written myself. This is the very good because both guys have written really high quality stuff that simplifies Glazed Lists rather than introducing complexity.
# posted by Jesse Wilson
on Saturday, November 06, 2004
0 comments
post a comment
SWT Frustration of the day: Constants
The SWT
GridData class has 25
public static final int
constants, including the following:
BEGINNING
CENTER
END
HORIZONTAL_ALIGN_BEGINNING
HORIZONTAL_ALIGN_CENTER
HORIZONTAL_ALIGN_END
VERTICAL_ALIGN_BEGINNING
VERTICAL_ALIGN_CENTER
VERTICAL_ALIGN_END
Pop-Quiz:
GridData also has a constructor:
public GridData(int horizontalAlignment, int verticalAlignment, boolean grabExcessHorizontalSpace, boolean grabExcessVerticalSpace)
Which 3 of the above constants are accepted values for the horizontalAlignment
argument in this constructor?
Pop-Solution:
If you guessed HORIZONTAL_ALIGN_BEGINNING
, HORIZONTAL_ALIGN_CENTER
, and HORIZONTAL_ALIGN_END
, you're wrong. The constructor only understands BEGINNING
, CENTER
, and END
.
# posted by Jesse Wilson
on Tuesday, November 02, 2004
0 comments
post a comment