Skip to main content

AWT Panel repainted on FocusChange event

5 replies [Last post]
aillescas
Offline
Joined: 2008-02-18
Points: 0

Hello,

We are testing phoneme to use it in a project that use old AWT code. We found that our components (custom subclasses of Frame, and Panel) were been repainted whenever there was a change in the focus.

The phoneme version we are using is linux-x86 mr1-b31 in a Fedora 7 distro. I don't know if this is a bug or not, but in case it wasn't we need a way to avoid it.

Here is some code to show what I mean

import java.awt.*;
import java.awt.image.*;

public class TestPanel extends Panel
{
protected VolatileImage buffer;

public TestPanel()
{
init();
}

protected void init()
{
//Trying to avoid the repainting... no luck
setIgnoreRepaint(true);

disableEvents(AWTEvent.FOCUS_EVENT_MASK);
enableInputMethods(false);

buffer = null;

}

public Graphics getGraphics()
{
//A little bit drastic, but we did't want
//somebody outside this object to do g.clearRect(...)
if(buffer == null)
{
buffer = createVolatileImage(500,500);
}
return buffer == null ? super.getGraphics() : buffer.getGraphics();
}

public void update(Graphics g)
{
//The original update do call g.clearRect(...)
this.paint(g);
}

public void paint(Graphics g)
{
//We need to paint something to see the effect
Graphics g2 = super.getGraphics();

//We use a crude aproximation to double buffer
//only to avoid calling clearRect(...) in the main
//buffer
Graphics bufferGraphics = buffer.getGraphics();
bufferGraphics.clearRect(0,0,500,500);
int x1,y1,x2,y2;
x1 = (int)Math.round(Math.random() * 500);
y1 = (int)Math.round(Math.random() * 500);
for(int i = 0; i < 500; i++)
{
x2 = (int)Math.round(Math.random() * 500);
y2 = (int)Math.round(Math.random() * 500);
bufferGraphics.setColor(Color.black);
bufferGraphics.drawLine(x1,y1,x2,y2);

x1 = x2;
y1 = y2;

}
g2.drawImage(buffer,0,0,500,500,this);
bufferGraphics.dispose();
}

public static void main(String[] args)
{
Frame myFrame = new Frame("Focus Test");

Panel basePanel = new Panel();
TestPanel myPanel = new TestPanel();
myPanel.setLayout(null);

basePanel.setBounds(0,0,600,600);
basePanel.setLayout(null);
basePanel.setBackground(Color.black);
basePanel.add(myPanel);

myPanel.setBounds(0,0,500,500);
myPanel.setBackground(Color.gray);

myFrame.add(basePanel);
myFrame.setSize(600,600);

myFrame.pack();
myFrame.show();
}

}

Well, if you click into the gray area and then out of there, you will see component repaint.

Thank you for your patience.

Antonio Illescas

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ffg
Offline
Joined: 2006-11-09
Points: 0

Hi Antonio,

We know about this issue -- the fix should be ready soon, we're still testing it.

If you want to experiment fixing this bug yourself before our fix is out, the general idea is to disallow Qt to erase background in containers, and set this erase at Java peer side.

So you could start with calling natively setBackgroundMode(Qt::NoBackground) on QpFrame, since it's the peer for all containers in Java.

Thanks,
-Felix Gorbatsevich
CDC Team

aillescas
Offline
Joined: 2008-02-18
Points: 0

Thanks Felix,

It seems that now the program runs smoothly...

This is a great job... Thank you all for it!

Antonio Illescas

ffg
Offline
Joined: 2006-11-09
Points: 0

Hi Antonio,

Just to let you know -- the code with the proper fix is now in the trunk of cdc.

Regards
-Felix

aillescas
Offline
Joined: 2008-02-18
Points: 0

Hi Felix,

Thank you very much for telling me! It came just in time to us.

Best wishes

Antonio Illescas

aillescas
Offline
Joined: 2008-02-18
Points: 0

One more detail, this is related somehow with de Qt libraries, we have made test with a cvm that uses GTK and there is no repainting.