problems doing double-buffering on MSIE 6

P

pfalstad

Hi, I am having a problem with an applet that does double-buffering. I
use image.getGraphics() ... g.drawImage() to do double-buffering. It
works fine with the java plugin, but it stops working every once in a
while on MSIE 6 (java release 5.0.0.3810). Intermittently, the screen
simply stops updating; drawImage() doesn't do anything. drawImage()
returns true, and I don't get any exceptions. If I do createImage() to
make a fresh image, then things work again, but that is slow so I don't
want to do it too often. Anyone else have this problem? Thanks.
 
P

pfalstad

Hi, I am having a problem with an applet ...
URL? Link to the short code example that displays the problem.

Sorry, I'm lazy.. Here you go:

http://www.falstad.com/broken/

You might have to let it sit for 10 minutes or more until it stops
updating. The update routine is still getting called, though, as you
can check by viewing the console. I compiled it on linux java 1.4.2
with -target 1.1.
 
A

Andrew Thompson


That is seriously broken HTML. Once you fix the Java applet
problem (or sooner), I strongly recommend validating it.

Your code has deprecated methods that are easily replaced,
look into the -Xlint compilation option.
You might have to let it sit for 10 minutes ..

...and it works a lot quicker if you make it 200x150,
rather than 800x600.
...or more until it stops updating.

I tried the run using MSVM for about 10 minutes before I
gave up on it.

It is interesting to note, however, that it runs *much* more
slowly than in Sun's 1.5.0 beta VM.
..The update routine is still getting called, though, as you
can check by viewing the console. I compiled it on linux java 1.4.2
with -target 1.1.

Thanks for taking the effort, but I am not prepared to point
the MSVM at any class file on the internet. The MSVM is still
insecure, and could open up a PC to the Trojan Byte Verifier
virus, amongst other things.

The *only* classes I am prepared to load in the MSVM are ones
that I have compiled myself, from source I have examined.

I will keep trying the local code, to see if it falls over
(it might be a memory leak that is ameliorated by the
ridiculously small canvss size I set..) It might be an idea
to use this source yourself and see if the problem is still
evident.

Here is the slight variant of your code that I am using.

<sscce>
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

class BrokenCanvas extends Canvas {

public static final long serialVersionUID = 1;
BrokenFrame pg;
BrokenCanvas(BrokenFrame p) { pg = p; }
public void update(Graphics g) { pg.updateBroken(g); }
public void paint(Graphics g) { pg.updateBroken(g); }
};

public class Broken extends Applet {

public static final long serialVersionUID = 1;

BrokenFrame ogf;
public void init() {
ogf = new BrokenFrame(this);
ogf.init();
}
};

class BrokenFrame extends Frame {

public static final long serialVersionUID = 1;

Dimension size = new Dimension(100, 75);

Image dbimage;
int pause = 10;
BrokenCanvas cv;
Broken applet;
BrokenFrame(Broken a) {
super("Broken Applet");
applet = a;
}
public void init() {
cv = new BrokenCanvas(this);
add(cv);
pack();
setSize( size );
handleResize();
setVisible(true);
cv.repaint();
}

void handleResize() {
dbimage = createImage(size.width, size.height);
System.out.println(dbimage);
}

public void paint(Graphics g) {
cv.repaint();
}

int x = 0;

public void updateBroken(Graphics realg) {
if (dbimage == null)
handleResize();
Graphics g = dbimage.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, size.width, size.height);
g.setColor(Color.white);
g.drawLine(x, 0, 0, x);
x = (x+1) & 255;
if (!realg.drawImage(dbimage, 0, 0, this))
System.out.println("Drawimage returned false");
cv.repaint(pause);
if (x == 0)
System.out.println("updateBroken");
}
}
</sscce>
 
A

Andrew Thompson

I will keep trying the local code, to see if it falls over..

...just ran it for 5 hours straight in the MSVM.

Not a flicker of a problem, and that line is still drifting
diagonally across it on a regular basis.

Can you reproduce the error with the code I posted?
 
P

pfalstad

Your code has deprecated methods that are easily replaced,
look into the -Xlint compilation option.

Hi, sorry, I have been ignoring the deprecation warnings; long ago when
I tried using the new methods, things started breaking on some old
browser I was using.
It is interesting to note, however, that it runs *much* more
slowly than in Sun's 1.5.0 beta VM.

Yes, Sun is much much faster on most things. Although MSJVM is still
faster on some things in my experience, like MemoryImageSource. I have
not tried BufferedImage yet because MSJVM doesn't support it. (?)
Might be time to ditch MSJVM.
It might be an idea
to use this source yourself and see if the problem is still
evident.

It still breaks after 10-15 minutes or so. I compiled with 1.5.0 as
you are doing and it still breaks.
 
A

Andrew Thompson

On 18 Jan 2005 08:57:09 -0800, (e-mail address removed) wrote:

....
It still breaks after 10-15 minutes or so.

Really? That is odd.

As my other post mentioned, I got it to run for 5 hours continuously
last night (looking at both the page and the MSVM console (open the
entire run) regularly.

I am beginning to suspect it is a broken MSVM installation on
that machine itself.

Compile that code and upload it, see if you can reproduce the problem
on *any* other IE with MSVM, and if not, update that particular IE to
the Sun VM[1], *that* should fix the problem.

[1] Which really should be done immediately on any MS IE that does not
specifically require the 'com.ms.*' classes, in any case.
<http://www.physci.org/javac.jsp> Chase the links at the top for
compelling reasons to *uninstall* the MSVM. (Even the 3810 version).
 
P

pfalstad

I am beginning to suspect it is a broken MSVM installation on
that machine itself.

Compile that code and upload it, see if you can reproduce the problem
on *any* other IE with MSVM,

My brother-in-law's computer has the same problem. (I haven't tried
the same test, but the same problem happens in the original program
which I created the test program from.)

I still get a lot of hits on my site from people who don't seem to have
Sun java installed, so it would be nice to support it. I don't think
it's worth any more trouble on my part though. There is a fairly easy
workaround--resizing the window will cause the image to be recreated,
and that fixes it. If there were some easy way I could check to see if
the image has been drawn has been updated, then I could just recreate
the image automatically whenever I detect that it failed.
 
A

Andrew Thompson

My brother-in-law's computer has the same problem. (I haven't tried
the same test, ...

How is that information useful in the current context?
We need to reproduce the problem in a *self* *contained* example first,
to ensure everybody understands exactly what you are doing.
...but the same problem happens in the original program
which I created the test program from.)

Further information about the original applet is not getting
us closer to the solution.

...Let me check here specifically. When you say 'original
program' do you mean the applet as it existed on *first* posting,
or are you referring to the applet you compiled from the
example code you supplied?

[ If you are referring to the first applet, I stick with the
above statements, whereas the latter would indicate we are
extremely close to a solution. ]
..There is a fairly easy
workaround--resizing the window will cause the image to be recreated,
and that fixes it.

...hmmm. Based on the current information (and not having yet seen
the error) the best advice I can offer is this.

Java image and graphics caching is horrendous for producing
memory leaks. So I suggest the following strategy.
In your 'BrokenFrame' class you have..

<snippet>
public void updateBroken(Graphics realg) {
if (dbimage == null)
handleResize();
Graphics g = dbimage.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, size.width, size.height);
g.setColor(Color.white);
g.drawLine(x, 0, 0, x);
x = (x+1) & 255;
if (!realg.drawImage(dbimage, 0, 0, this))
System.out.println("Drawimage returned false");
cv.repaint(pause);
if (x == 0)
System.out.println("updateBroken");
}
</snippet>

I notice that you are not disposing of the graphics object specifically.
Try this instead.

<snippet>
public void updateBroken(Graphics realg) {
if (dbimage == null)
handleResize();
Graphics g = dbimage.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, size.width, size.height);
g.setColor(Color.white);
g.drawLine(x, 0, 0, x);
x = (x+1) & 255;
if (!realg.drawImage(dbimage, 0, 0, this))
System.out.println("Drawimage returned false");
cv.repaint(pause);
if (x == 0)
System.out.println("updateBroken");
g = null;
}
</snippet>

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top