Thomas said:
Original x-posting restored:
c.l.j.g -- debatable whether I have anything to say that's relevant to that
NG, but since you left it in, so will I.
c.l.j.db -- this is as relevant to DB as it is to GUI.
c.l.j.p -- 'cos that's the only group I read of the three, and I would
rather see the replies (in any) to my posts.
What I didn't consider was that it is rather hard for many people to
slide a scrollbar by exactly one pixel. Todays cheap imprecise mouses
make it even difficult for skilled users. So a feasible number is maybe
1/2 or 1/5 of the rows.
Agreed. On this machine (a laptop with a touch pad, or whatever they're
called) it is quite easy to control positioning at the pixel level, but I
wouldn't claim that's the general case.
There's another reason for wanting the minimum scroll quantum to be
significantly less than one screensfull. If the scrolling "jumps" by more than
a smallish fraction of the whole window then it's easy to loose the sense of
continuity -- of the /same/ data being displayed in a different position --
since there isn't enough overlap between the "before" and "after" images for
pattern matching to pick up the similarities. That makes it easy to get lost
in the data, to loose your sense of where you are in the list of rows. Perhaps
that problem could be mitigated by using some sort of "smooth scrolling" rather
than simply jumping when the scrollbar moves by a small amount. I have no idea
how to implement that in a JTable, or even whether it's feasible at all without
more-or-less completely re-writing the display logic.
The 16 is Sun's hardcoded default, which JTable.getRowHeight() will
return unless you hit it over the head. Sun not even adjusts the default
row height to the size of the font used in the rows. One of the many
things which are wrong with JTable.
Fair enough. I haven't used JTable very much (only once, from unreliable
memory), and so was talking more in the abstract than about JTable-specifics.
I never did a sliding window implementation with JTable or in Swing. I
did it some time ago for a custom-made tree widget which was used to
navigate over a huge amount of data in a DB. It is rather simple if you
have control over both ends, DB and widget implementation. I would
imagine it is a real mess if you have to retro-fit it to a JTable.
I suspect that an intermediate custom TableModel wouldn't be difficult --
that's to say that plumbing the sliding window logic into a JTable looks easy
enough (though I haven't tried it), it's the sliding window logic itself that
might be tricky.
The problem with any kind of sliding window is that it relies on random access
to the underlying result set, and that will be to varying degrees
problematical. The way the database works, the nature of the cursor (if that's
the right word) -- forward-only, etc -- and the implementation of the DB driver
will all affect the feasibility of such techniques. I have tried to use a
sliding window technique with a JTable-like grid component (I wrote the
component so I know that it didn't "misuse" the underlying model -- I can't
claim that the same is true for JTable, it may be), and found it impossible to
make it work acceptably. The problem was that with the databases I was talking
to, I couldn't find any way to make scrolling /backwards/ up the table work
without unacceptable delays as the DB was apparently forced to re-run the query
to discover what row was at index, say, 85678. The problem could be mitigated
by using a very large sliding window, but then we are getting into the
territory of just copying /all/ the data into the model -- and that's a lot
simpler to implement.
In the end I found that -- where possible -- just lazy-loading all the data
sequentially worked best from every point of view except memory consumption.
In cases where that turned out to be too much of an issue, I found that using
an LRU list of large "pages" (each several thousand cached rows) worked better
than a sliding window since it caused less "thrashing" of the cached data as
the user scrolled around. It was easier to implement too ;-)
Incidentally, I also found that the ODBC driver for one of my databases, a
PostgreSQL db, was caching so much row data itself, that a completely
transparent implementation (not caching anything myself, but just going back to
the result set for any needed data) worked very well for even rather large
result sets. Unfortunately the same technique worked /exceedingly/ badly for
other combinations of DB and ODBC driver. So I think that there is no single
"best" solution, and not even a single acceptable solution -- the caching
strategy /has/ to be controllable in some way -- perhaps by a pluggable
strategy object, or (what I settled on) a choice of different caching wrappers
around the real result set object.
-- chris