JDK-4200690 : JViewport backingstore doesn't work with scrollRectToVisible
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: solaris_2.5.1,windows_nt
  • CPU: x86,sparc
  • Submitted: 1999-01-05
  • Updated: 2013-11-01
  • Resolved: 1999-02-05
Related Reports
Duplicate :  
Description
Snippit from an email sent by Steve:

----------------------------------
Hi Folks,

I was talking to some of you earlier today about the possibility that 
JViewport's backing store isn't working as advertised.  I've been doing a 
little expirementing and come to the conclusion that something seems to have 
broken.  

My first test was to modify Tina Su's Table SwingMark test to toggle the 
backing store.  I didn't find much difference there.  I realized that there 
was so much baggage with that test (which involves a lot more that scrolling) 
that perhaps I should create a leaner focused test.  You can find it at:

/home/wilsonsd/SwingMarks/TableScrollTest

You can run the test in one of two ways:

java TableScrollTest   (this leaves the backing store on)
java TableScrollTest -bs=off (this turns it off)

Please feel free to check my code and make sure I deactivated it correctly.  
My first few trys were tripped up by the fact that JTable seems to turn it on 
at addNotify time.  I think I've got it now, but please check to be sure.

In addition to tracking execution time, which is always tough, I added checks 
to track the number of times paint is called (for the JTable and the 
Renderer).

This test creates a table with 10 columns and 1000 rows.  The test scrolls 
though ~200 rows one row at a time.

The results from running these (with JDK 1.1.7 are as follows):

Time: ~16 seconds for both (within 0.1 seconds)
JTable Repaints: 189
Renderer Repaints: 45,360

Now, those numbers might look funny, but I have found there is a pattern.  
When the table comes up it is showing 10 columns and 24 rows by default.

10 cols * 24 rows * 189 paints = 45,360 render paints

This seems to show that every time the JTable is asked to paint, the renderer 
is called for each visible cell in the table.  It seems that the point of the 
backing store is that it should only be called for newly exposed cells, which 
means it should be something more like 1,890 times (10 cols * 189 newly 
exposed rows).  I would think this should give us a significant speed increase 
if we could get to that point.
--------------------------------
Reply from Scott:

Yep, it would appear that any paints done via scrollRectToVisible will 
not use the backing store, regardless of what it is set to.
A boolean is maintained in JViewport, scrollUnderway, to indicate if a 
scroll is underway so that paint will try and use the backing
store. scrollRectToVisible will always set this to false after calling 
setViewPosition (setViewPosition sets it to true), which results in
the backing store never being used:( Most of the time the user will
click and drag the scrollbar, which only results in setViewPosition
being called, which sets scrollUnderway to true, and results in the
backing store being used... We probably haven't heard too much about
this since it only happens when scrollRectToVisible is programaticly
invoked.

Comments
EVALUATION As outlined in the email, scrollRectToVisible was incorrectly setting the scrollUnderway ivar to false so that offscreen buffer would not be used. scrollRectToVisible no longer sets scrollUnderway to false. scott.violet 1999-02-01 The way the backing store is used in flawed. setBounds is invoked and scrollUnderway is set to true, which triggers a repaint. When the repaint is processed by the RepaintManager and paint is invoked on viewport it looks at the scrollUnderway flag, and if true it then scrolls the necessary region and messages the view to paint the scrolled region. The above logic fails if repaint is invoked on the view in the meantime, as viewport has no way to know that part of the scrolled region is dirty and should be painted. It just so happens that JTable does a scrollRectToVisible followed by a repaint (try holding the up/down keys down to see this behavior), which is why the scrollUnderway = false; was added. To fix this paintImmediately should be used instead of repaint. But since we added the new blitting code we will eventually deprecate the backing store. And since this change would be risky so close to freeze we are not going to fix it. scott.violet 1999-02-05
11-06-2004

WORK AROUND There are a couple of options: Turn off the backing store: viewport.setBackingStoreEnabled(false); After changing the selection and scrolling do something like: SwingUtilities.invokeLater(new Runnable() { public void run() { table.repaint(); } }); scott.violet 1999-02-11
11-06-2004