Flickering graphics

I am trying to use the Graphics from a Canvas within a frame to draw some simple circles. I have gotten the code worked out so that it draws the circles, but they only stay on screen for a split second before disappearing. I developed the code using eclipse, but also ran the class from the command line and had the same problem.

Here is the method:

import java.awt.*;

class myShapes{

...

publicstaticvoid drawShapes()

{

Frame myFrame =new Frame();

Canvas myCanvas =new Canvas();

myFrame.add(myCanvas);

myFrame.setSize(500,500);

myFrame.setVisible(true);

myCanvas.setSize(500,500);

myCanvas.setVisible(true);

Graphics myGraphics = myCanvas.getGraphics();

myGraphics.setColor(Color.black);

myGraphics.fillRect(0,0, 200, 200);

myGraphics.setColor(Color.red);

myGraphics.fillRect(50,50,100,100);

JOptionPane.showMessageDialog(null,"Method end");

}

...

}

Just before the final message dialog displays, I see a red rectangle centered in a black one, but they disappear as the dialog box appears. Trying to use the paint() or update() methods only makes it so I never see the shapes at all. Is there some basic thing I'm missing, or am I going about this completely wrong?

[1743 byte] By [thelizardreborna] at [2007-10-3 6:49:30]
# 1

A technique calld double buffering is normally used. There are various implementations but one is as follows.

BufferedImage globalImg;

BufferedImage tempr;

public class drawShapes()

{

tempr=new BufferedImage(stat_wid, stat_hie, BufferedImage.TYPE_INT_RGB);

Graphics2D gr=tempr.createGraphics();

gr.setColor.....

gr.fillRect.....

gr.dispose();

globalImg=tempr;//copy the reference to new image;

someFlag=true;

//or for testing purposes call repaint() onto your canvas instance:

}

public class whatEver extends Canvas //this is a subclass with access to global variables

{

public void paint(Graphics _g)

{if(someFlag){

_g.drawImage(globalImg, 0, 0, obs);

someFlag=false;

}}

}

}

Flags are ussually used to optimize the ammount of processing between drawing to screen and drawing to the buffer image.

Hope this helps - if you want to look ata full code sample, leave your email address and i can email you a little double buffering applet.

Bamkin.

bamkin-ov-lestaa at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 2

Whoa there. You're going entirely the wrong way about painting.

Always do your painting in the paint() method (or paintComponent() method for Swing components).

What you're doing is creating some components, painting to them, and then the paint cycle comes in and uses the default paint logic and blats it.

You can't just paint to a Graphics object and expect stuff to stay there. It will get repainted, and when that happens your stuff needs to be repainted, it won't magically appear.

Look up on the Java Tutorial how to do this.

itchyscratchya at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 3
I was following the OP's model of the drawShapes methodThis could well be called from the paint(), just showing the buffering part...Or if it were an active component the 'logic' may be in a different method such as run().Tutiorial will be invaluable though.
bamkin-ov-lestaa at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 4
This could well be called from the paint()I seriously hope he's not creating Frame and Canvas objects inside the paint() method :o)
itchyscratchya at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 5

The only java tutorials I can find are about swing. Do I have to use swing, or are the awt classes sufficient?

If awt is sufficient, then this is how I understand that I have to do this. (It's not what I'm doing yet.) My class needs to extend frame or canvas, and then have a method named paint(), that takes the graphics object from my class as a parameter, which will perform the graphics operations I am going for.

Is this closer? I'm trying to piece together how I've seen the class used, since I haven't found any tutorials.

thelizardreborna at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 6

import java.awt.*;

import java.awt.event.*;

public class CircleApp extends Frame {

public CircleApp() {

addWindowListener(closer);

add(new CircleCanvas());

setSize(400,400);

setLocation(200,200);

setVisible(true);

}

private WindowListener closer = new WindowAdapter() {

public void windowClosing(WindowEvent e) {

dispose();

System.exit(0);

}

};

public static void main(String[] args) {

new CircleApp();

}

}

class CircleCanvas extends Canvas {

public void paint(Graphics g) {

super.paint(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

int w = getWidth();

int h = getHeight();

g2.setPaint(Color.red);

g2.drawOval(w/2,h/12, w/4, h/4);

g2.setPaint(Color.green.darker());

g2.drawOval(w/8, h*2/3, w/4, h/4);

}

}

crwooda at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 7

Do I have to use swing, or are the awt classes sufficient?

You don't have to use Swing, but there are lots of good reasons to use it and in a desktop environment I can't think of a single good reason to use AWT.

My class needs to extend frame or canvas

Then extend Canvas (or JComponent in Swing) - extending Frame is poor practice.

itchyscratchya at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 8
Tutorial and examples http://java.sun.com/docs/books/tutorial/extra/fullscreen/doublebuf.html http://java.sun.com/docs/books/tutorial/extra/fullscreen/example.html:-)
bamkin-ov-lestaa at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...
# 9
Thanks everyone, I think I understand better how this package should work. If I have any problems, I'll let you know.
thelizardreborna at 2007-7-15 1:40:03 > top of Java-index,Desktop,Core GUI APIs...