|
Quick Lists
|
|
Bug ID:
|
4096745
|
|
Votes
|
1
|
|
Synopsis
|
disable()/enable() make AWT [lightweight] components blink
|
|
Category
|
java:classes_awt
|
|
Reported Against
|
1.2
, 1.3
, 1.4
, 1.1.4
, 1.3.1_04
|
|
Release Fixed
|
1.3.1_05,
1.4.0_02(Bug ID:2118971)
, 1.4.1(hopper-beta) (Bug ID:2118972)
|
|
State
|
10-Fix Delivered,
request for enhancement
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
4407186
,
4673900
,
4684354
|
|
Submit Date
|
03-DEC-1997
|
|
Description
|
Hi!
When enable()/disable() of most AWT components is
called [ex: Button, TextField, etc] - they are doing
repaint(). They blink becouse of it.
[repaint() at the start probably clears whole
components area].
Example - when calling Button's disable() method -
text of Button nicely changes to gray ...and
WHOLE Button's area is repainted! Although nothing
changed there and nothing need to be repainted!
Becouse of it - application, which enables/disables
components alot (on Containers, which are shown) looks a bit odd.
It would be great if enable()/disable() of AWT components
will not call repaint() in this way.
[maybe call something like update()
which will paint ONLY changed parts. For example
to disable Button - it need only to paint gray
text over current text, and there is no need to clear
nothing at all.]
Thanks! 8-)
---
- leon
(Review ID: 21207)
======================================================================
When issuing a setEnabled() call on any component the
entire component is repainted. For smaller components like
a JTextField and JMenuItem this is annoying. For larger
components like JFrame or JDialog the blink caused by
the repaint makes the application completely unacceptable
to our user group.
An analysis of the Java source reveals that in fact every
component is repainted on a enable/disable:
Taken from awt_component.cpp:
JNIEXPORT void JNICALL
Java_sun_awt_windows_WComponentPeer_enable(JNIEnv *env, jobject self)
{
jint pData;
JNI_CHECK_PEER_RETURN(self);
AwtComponent* p = (AwtComponent*)pData;
::EnableWindow(p->GetHWnd(), TRUE);
::InvalidateRect(p->GetHWnd(), NULL, TRUE); // Bug #4038881 Labels don't enable and disable properly
CriticalSection::Lock l(p->GetLock());
p->VerifyState();
}
The InvalidateRect call was apparently added because of a
bug in labels. The side effect is that instead of
only repainting labels everything is being repainted.
For some reason you have had difficulty reproducing this
bug because it has been reported several times before:
4145715, 4024346, 4096745
Please make every effort to reproduce this bug, it is
critical that we have it fixed as we see no workaround.
I would be happy to suggest a fix, fly out and fix it,
in general do anything to see that it be fixed.
(Review ID: 84484)
======================================================================
|
|
Work Around
|
N/A
|
|
Evaluation
|
Definitely a problem. Needs further investigation.
xxxxx@xxxxx 1999-08-11
xxxxx@xxxxx
The last parameter in ::InvalidateRect(p->GetHWnd(), NULL, TRUE)
means clearing background before paint. Since it is TRUE the window
flickers. The fix of this problem is to set it FALSE.
======================================================================
This is still reproducable in Merlin and Hopper. It was caused by adding back the shouldClearRectBeforePaint() back into the peers. This will be fixed in Hopper.
xxxxx@xxxxx 2002-01-14
As of Hopper 1.4.1 (Build 02) the blinking only occurs when lightweight components are added to the container (i.e. Swing). See attached test case (simpleFrame.java) for demonstration. Press the Dialog button.
xxxxx@xxxxx 2002-03-08
When Component.enable() is called, we call
::InvalidateRect(GetHWnd(), NULL, FALSE); in awt_Component.cpp ::Enable
which generates a WM_PAINT. When we process the resulting paint event,
we erase the background for all lightweight components, since we have no
way of distinguishing between those lw components that need the background
erased (like all of swing), and those that do not.
The ultimate fix is to provide a public method in Component.java that clears
the background of the Component. Subclasses could override the method to
either clear or prevent clearing of the component. See 4519407. That way,
client code can make the distinction about whether the background should
be erased or not.
Note: the fix that was put into the 1.3.1 source tree should not be ported
to the 1.4 source tree. The reason is that in 1.3.1, we were erasing the
background on the toolkit thread and on the EDT. That caused problems on
dual-processor systems. So, on 1.4, we only erase on the EDT. I don't see a
good solution for 1.4.
xxxxx@xxxxx 2002-03-11
As we are aware that the blinking is caused by the line ::InvalidateRect(GetHWnd(), NULL, FALSE); in AwtComponent.Enable(). This line
is introduced to fix bug #4038881 " Labels don't enable and disable properly".
If we back out this fix then we don't see the blinking. And the fix for awt labels should get into AwtLabel.Enable() not into AwtComponent.Enable as it is
now in 1.4 and upward
- xxxxx@xxxxx 2002-04-05
|
|
Comments
|
Submitted On 04-FEB-1998
lichunyue
Who will be kind enough to help me how to make blink AWT component?
Submitted On 28-JAN-2002
alexc1
I've seen this on our AWT-based applications that runs
(slowly) using Personal Java on a handheld device. It is
particularly noticable because the drawing performance of
the device is not great. It looks terrible! I'm sure that
performance would improve a lot if AWT only updated the
display when obsolutely necessary.
Submitted On 23-FEB-2004
albo
Currently using 1.4.2-03 and this is still a problem.
Calling setEnabled(true/false) causes major window
flashes and can cause windows to be painted behind
other windows. Has this been re-raised yet?
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |