JDK-4073822 : Fast scrolling causes un-needed refreshings of the whole child of a ScrollPane.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.2,1.1.5
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_95
  • CPU: x86
  • Submitted: 1997-08-22
  • Updated: 2013-11-01
  • Resolved: 1999-08-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.3.0 kestrelFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description

Name: joT67522			Date: 08/22/97


1. Construct a Frame sub-class (we are talking about an application)
   with its default layout.
2. Construct a new ScrollPane object with the default constructor:
   'new ScrollPane()'.
3. Construct a new Canvas sub-class.
4. Draw on the canvas some graphical figures using the Graphics
   drawing API, also in coordinates beyond the shown area of the
   Frame so that the scroll bars will be created.
5. Scroll fas in any direction by continuously holding the button
   left button on any of the scroll bar's arrowed edges.
The Problem:
 When successive scrolling is requested, such that the canvas
 contents does not ends moving the increment amount before the 
 next scrolling event is received, the whole
 canvas is refreshed, i.e. erased and redrawn again, what makes
 scrolling very inconvenient and very very slow.

 This behaved differently in JDK1.1Beta3. There was never a redraw
 of the whole canvas. I think that you have fixed some other bug
 regarding resources consumed during scrolling in the Beta3, but 
 have brouht in another problem.

company - Softera , email - ###@###.###
======================================================================

ronan.mandel@Eng 1997-10-23
After a validate(), ScrollPane redraws the whole
of the component it contains. This redraw is not 
limited to the visible region of the component 
within the viewport of the ScrollPane. If the 
ScrollPane contains a large component it takes 
ages to redraw, rather than the redraw being 
proportional to the size of the ScrollPane.
This is a very inefficient implementation.
The ScrollPane should impose a clip region
defined by the viewport when it redraws the
component it contains.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: kestrel FIXED IN: kestrel INTEGRATED IN: kestrel
14-06-2004

WORK AROUND Name: joT67522 Date: 08/22/97 ======================================================================
11-06-2004

PUBLIC COMMENTS ScrollPane flicker fixed as per final evaluation comments.
10-06-2004

EVALUATION The problem is that scrolling a ScrollPane causes Component.move on the contained component. At the Win32 native level, this translates into a call to ::SetWindowPos _without_ the SWP_NOREDRAW flag set. Now,, we can detect the parent of a component is a ScrollPane and in that case set the SWP_NOREDRAW bit. This eliminates the flicker, but introduces a whole new set of refresh problems. As far as I can tell, ::ScrollWindow/::ScrollWindowEx do not verify that the source bits they are copying are validated. In a normal Win32 problem you can assure that they are by calling ::UpdateWindow after every ::ScrollWindow call. Then, the next ::ScrollWindow call will be guaranteed to copy only valid bits. However, our WM_PAINT handler does not immediately paint the specified region. Instead, it posts an event back to Java to repaint that region as soon as possible. In fast scrolling cases, though, another scroll event comes through before the painting can be completed, spewing garbage all over the window. Thoughts on how to fix this: The easiest way is to block WmPaint waiting for callback notification from Java that the region has been repainted. However, we have adopted the convention that no event synchronization will take place in the toolkit thread. The other option is to drop ::ScrollWindow/::ScrollWindowEx all together and do all the bit transfers with ::BitBlt. Then, we can check the current invalidated region by calling ::GetUpdateRect and copy only valid bits. We would also need to replace the calls to ::BeginPaint and ::EndPaint in WmPaint when we're scrolling with a ::ValidateRect call that is executed only after callback notification from Java. david.mendenhall@eng 1998-04-06 This bug also causes side effects not related to ScrollPane. Any system level paint events are subject to thrashing of the clip. It can effect applications and applets. Applets are often especially bad. steve.wilson@eng 1999-05-11 All right, final word on this. Clip region corruption is a symptom of this bug, not it's cause. The underlying reason ScrollPane's flicker is that there is redundant scrolling going on. The native Win32 code moves the scrollpane child (twice!) using ScrollWindow calls in response to WM_VSCROLL/WM_HSCROLL messages and again in response to WScrollPanePeer.setScrollPosition. ScrollPane/PeerFixer also moves the scrollpane child by listening to adjustment events and doing Component.move calls. There is a race condition where the Component.move call (executed asynchronously on the Java event dispatch thread) may or may not execute before the WScrollPanePeer.setScrollPosition ScrollWindow call. In the cases where Component.move gets there first, the entire window is refreshed because AwtComponent::Reshape uses SWP_NOCOPYBITS when reshaping the window via Set/DeferWindowPos. If on the other hand, Component.move comes in a little later, the window has already been moved by ScrollWindow so Windows no-ops the Set/DeferWindowPos call avoiding the flicker. The best way to fix this is to: 1) Get rid of all the ScrollWindow calls in awt_ScrollPane.cpp. They are redundant since ScrollPane's move the component via Component.move. 2) Change the implementation of AwtComponent::Reshape to specify SWP_NOCOPYBITS only when the component _size_ is changing-- on a move, the contents should be blitted to the new location. 3) Make scrolling one atomic operation that executes on the Java event dispatch thread so the scrollbar thumbs, component move, and repaint of the exposed area all happen synchronously (this requires coalescing scroll events). The clip region corruption referred to in the previous evaluations still exists, but this is a symptom of the scroll operation occuring on the Windows thread while the paint operation happens on the event dispatch thread. Making the scroll/paint both happen on the event dispatch thread avoids the problem for ScrollPane's. The more general problem of clip corruption with multiple threads needs to be dealt with separately (see Bug 4045781). robi.khan@eng 1999-07-21
21-07-1999