Flickering When Redrawing in a Canvas (Again!)

Hi,

I realise this question has been asked a million times, however I'm having trouble getting a Canvas to draw without flickering.

I've tried to implement offscreen drawing however this doesn't seem to be working.

What am I doing wrong here?

import java.awt.*;

import java.util.*;

import java.awt.geom.*;

import javax.swing.*;

import java.awt.image.*;

publicclass myCanvasextends Canvas

{

publicint W;

publicint H;

public Vector Obstacles;

public Label messageLabel;

public visibility visibilitygraf;

public Path ShortestPath;

Point StartPoint;

Point EndPoint;

Vector invRobot;

publicboolean paintVisGraph;

publicboolean paintShortestPath;

private Dimension offDimension;

private Image offImage;

private Graphics2D offGraphics;

//============================================================

public myCanvas(){

setBackground(Color.white);

paintVisGraph =false;

paintShortestPath =false;

offDimension =new Dimension();

}

//============================================================

publicvoid setPaintVisGraph(){

paintVisGraph = !paintVisGraph;

repaint();

}

//============================================================

publicvoid setPaintShortestPath(){

paintShortestPath = !paintShortestPath;

repaint();

}

//============================================================

publicvoid paint(Graphics g){

repaint(g);

}

//============================================================

publicvoid repaint(Graphics g)

{

Dimension d = getSize();

if((offGraphics ==null) || (d.width != offDimension.width) || (d.height != offDimension.height) ){

offDimension = d;

offImage = createImage(d.width, d.height);

offGraphics = (Graphics2D)offImage.getGraphics();

}

// Erase the offscreen buffer.

offGraphics.setColor(getBackground());

offGraphics.fillRect(0, 0, d.width, d.height);

offGraphics.setColor(Color.black);

//Graphics2D graphics2d = (Graphics2D)g;

//============================================================

// The objects.

if(Obstacles !=null){

for(int j = 0; j < Obstacles.size(); j++){

Polygon polygon1 =new Polygon();

Obstacle obstacle1 = (Obstacle)Obstacles.elementAt(j);

for(int l = 0; l < obstacle1.ObstaclePoints.size(); l++){

Point point1 = (Point)obstacle1.ObstaclePoints.elementAt(l);

polygon1.addPoint(point1.x, point1.y);

}

offGraphics.fillPolygon(polygon1);

}

}

//============================================================

// The source and the destination

offGraphics.setColor(Color.red);

if(StartPoint !=null){

offGraphics.fillOval(StartPoint.x - 5, StartPoint.y - 5, 10, 10);

}

offGraphics.setColor(Color.green);

if(EndPoint !=null){

offGraphics.fillOval(EndPoint.x - 5, EndPoint.y - 5, 10, 10);

}

//============================================================

// The graph.

if(paintVisGraph ==true){

if(visibilitygraf !=null){

offGraphics.setColor(Color.blue);

offGraphics.setStroke(new BasicStroke(1.0F));

for(int k1 = 0; k1 < visibilitygraf.visibilityedges.size(); k1++){

offGraphics.drawLine(((edge)visibilitygraf.visibilityedges.elementAt(k1)).p1.x, ((edge)visibilitygraf.visibilityedges.elementAt(k1)).p1.y, ((edge)visibilitygraf.visibilityedges.elementAt(k1)).p2.x, ((edge)visibilitygraf.visibilityedges.elementAt(k1)).p2.y);

}

}

}

//============================================================

// The shortest path.

offGraphics.setStroke(new BasicStroke(2.0F));

if(paintShortestPath ==true){

if(ShortestPath !=null){

offGraphics.setColor(Color.red);

for(int l1 = 0; l1 < ShortestPath.points.size() - 1; l1++){

Point point4 = (Point)ShortestPath.points.elementAt(l1);

Point point5 = (Point)ShortestPath.points.elementAt(l1 + 1);

offGraphics.drawLine(point4.x, point4.y, point5.x, point5.y);

}

}

}

//============================================================

// Paint the image onto the screen.

g.drawImage(offImage, 0, 0,this);

}

}

[8026 byte] By [cpsmusica] at [2007-11-27 10:46:14]
# 1

Check out how to do this in my PaintArea class

/*

* Created on Jun 15, 2005 by @author Tom Jacobs

*

*/

package tjacobs.ui;

import java.awt.image.BufferedImage;

import java.awt.*;

import java.awt.event.*;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import javax.swing.ImageIcon;

import javax.swing.JComboBox;

import javax.swing.JComponent;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JToolBar;

import javax.swing.SwingUtilities;

import tjacobs.MathUtils;

/**

* PaintArea is a component that you can draw in similar to but

* much simpler than the windows paint program.

*/

public class PaintArea extends JComponent {

BufferedImage mImg; //= new BufferedImage();

int mBrushSize = 1;

private boolean mSizeChanged = false;

private Color mColor1, mColor2;

static class PaintIcon extends ImageIcon {

int mSize;

public PaintIcon(Image im, int size) {

super(im);

mSize = size;

}

}

public PaintArea() {

super();

setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));

addComponentListener(new CListener());

MListener ml = new MListener();

addMouseListener(ml);

addMouseMotionListener(ml);

setBackground(Color.WHITE);

setForeground(Color.BLACK);

}

public void paintComponent(Graphics g) {

if (mSizeChanged) {

handleResize();

}

//g.drawImage(mImg, mImg.getWidth(), mImg.getHeight(), null);

g.drawImage(mImg, 0, 0, null);

//super.paintComponent(g);

//System.out.println("Image = " + mImg);

//System.out.println("Size: " + mImg.getWidth() + "," + mImg.getHeight());

}

public void setBackground(Color c) {

super.setBackground(c);

if (mImg != null) {

Graphics g = mImg.getGraphics();

g.setColor(c);

g.fillRect(0, 0, mImg.getWidth(), mImg.getHeight());

g.dispose();

}

}

public void setColor1(Color c) {

mColor1 = c;

}

public void setColor2(Color c) {

mColor2 = c;

}

public Color getColor1() {

return mColor1;

}

public Color getColor2() {

return mColor2;

}

class ToolBar extends JToolBar {

ToolBar() {

final ColorButton fore = new ColorButton();

fore.setToolTipText("Foreground Color");

final ColorButton back = new ColorButton();

back.setToolTipText("Background Color");

JComboBox brushSize = new JComboBox();

//super.createImage(1, 1).;

FontMetrics fm = new FontMetrics(getFont()) {};

int ht = fm.getHeight();

int useheight = fm.getHeight() % 2 == 0 ? fm.getHeight() + 1 : fm.getHeight();

final BufferedImage im1 = new BufferedImage(useheight, useheight, BufferedImage.TYPE_INT_RGB);

Graphics g = im1.getGraphics();

g.setColor(Color.WHITE);

g.fillRect(0, 0, useheight, useheight);

g.setColor(Color.BLACK);

g.fillOval(useheight / 2, useheight / 2, 1, 1);

g.dispose();

//im1.setRGB(useheight / 2 + 1, useheight / 2 + 1, 0xFFFFFF);

final BufferedImage im2 = new BufferedImage(useheight, useheight, BufferedImage.TYPE_INT_RGB);

g = im2.getGraphics();

g.setColor(Color.WHITE);

g.fillRect(0, 0, useheight, useheight);

g.setColor(Color.BLACK);

g.fillOval(useheight / 2 - 1, useheight / 2 - 1, 3, 3);

g.dispose();

//im2.setRGB(useheight / 2 - 1, useheight / 2 - 1, 3, 3, new int[] {0, 0xFFFFFF, 0,

//0xFFFFFF, 0xFFFFFFF, 0xFFFFFF,

//0, 0xFFFFFF, 0}, 0, 1);

final BufferedImage im3 = new BufferedImage(useheight, useheight, BufferedImage.TYPE_INT_RGB);

g = im3.getGraphics();

g.setColor(Color.WHITE);

g.fillRect(0, 0, useheight, useheight);

g.setColor(Color.BLACK);

g.fillOval(useheight / 2 - 2, useheight / 2 - 2, 5, 5);

g.dispose();

//im3.setRGB(useheight / 2 - 2, useheight / 2 - 2, 5, 5, new int[] {0, 0, 0xFFFFFF, 0, 0,

//0, 0xFFFFFF, 0xFFFFFFF, 0xFFFFFF, 0,

//0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,

//0, 0xFFFFFF, 0xFFFFFFF, 0xFFFFFF, 0,

//0, 0, 0xFFFFFF, 0, 0}, 0, 1);

//JLabel l1 = new JLabel("1 pt", new ImageIcon(im1), JLabel.LEFT);

//JLabel l2 = new JLabel("3 pt", new ImageIcon(im2), JLabel.LEFT);

//JLabel l3 = new JLabel("5 pt", new ImageIcon(im3), JLabel.LEFT);

brushSize.addItem(new PaintIcon(im1, 1));

brushSize.addItem(new PaintIcon(im2, 3));

brushSize.addItem(new PaintIcon(im3, 5));

//brushSize.addItem("Other");

add(fore);

add(back);

add(brushSize);

PropertyChangeListener pl = new PropertyChangeListener() {

public void propertyChange(PropertyChangeEvent ev) {

Object src = ev.getSource();

if (src != fore && src != back) {

return;

}

Color c = (Color) ev.getNewValue();

if (ev.getSource() == fore) {

mColor1 = c;

}

else {

mColor2 = c;

}

}

};

fore.addPropertyChangeListener("Color", pl);

back.addPropertyChangeListener("Color", pl);

fore.changeColor(Color.BLACK);

back.changeColor(Color.WHITE);

brushSize.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent ev) {

System.out.println("ItemEvent");

if (ev.getID() == ItemEvent.DESELECTED) {

return;

}

System.out.println("Selected");

Object o = ev.getItem();

mBrushSize = ((PaintIcon) o).mSize;

}

});

//Graphics g = im1.getGraphics();

//g.fillOval(0, 0, 1, 1);

//BufferedImage im1 = new BufferedImage();

//BufferedImage im1 = new BufferedImage();

}

}

protected class MListener extends MouseAdapter implements MouseMotionListener {

Point mLastPoint;

public void mouseDragged(MouseEvent me) {

Graphics g = mImg.getGraphics();

if ((me.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {

g.setColor(mColor1);

} else {

g.setColor(mColor2);

}

Point p = me.getPoint();

if (mLastPoint == null) {

g.fillOval(p.x - mBrushSize / 2, p.y - mBrushSize / 2, mBrushSize, mBrushSize);

//g.drawLine(p.x, p.y, p.x, p.y);

}

else {

g.drawLine(mLastPoint.x, mLastPoint.y, p.x, p.y);

//g.fillOval(p.x - mBrushSize / 2, p.y - mBrushSize / 2, mBrushSize, mBrushSize);

double angle = MathUtils.angle(mLastPoint, p);

if (angle < 0) {

angle += 2 * Math.PI;

}

double distance = MathUtils.distance(mLastPoint, p) * 1.5;

if (angle < Math.PI / 4 || angle > 7 * Math.PI / 4 || Math.abs(Math.PI - angle) < Math.PI / 4) {

for (int i = 0; i < mBrushSize / 2; i ++) {

g.drawLine(mLastPoint.x, mLastPoint.y + i, p.x, p.y + i);

g.drawLine(mLastPoint.x, mLastPoint.y - i, p.x, p.y - i);

//System.out.println("y");

//System.out.println("angle = " + angle / Math.PI * 180);

}

}

else {

for (int i = 0; i < mBrushSize / 2; i ++) {

g.drawLine(mLastPoint.x + i, mLastPoint.y, p.x + i, p.y);

g.drawLine(mLastPoint.x - i, mLastPoint.y, p.x - i, p.y);

//System.out.println("x");

}

}

//System.out.println("new = " + PaintUtils.printPoint(p));

//System.out.println("last = " + PaintUtils.printPoint(mLastPoint));

//System.out.println("distance = " + distance);

//Graphics2D g2 = (Graphics2D) g;

//g2.translate(mLastPoint.x + mBrushSize / 2, mLastPoint.y);

//g2.rotate(angle);

//g2.fillRect(0, 0, (int) Math.ceil(distance), mBrushSize);

//g2.rotate(-angle);

//g2.translate(-mLastPoint.x + mBrushSize / 2, -mLastPoint.y);

//g.setColor(Color.RED);

//g.drawRect(p.x, p.y, 1, 1);

}

mLastPoint = p;

g.dispose();

repaint();

}

public void mouseMoved(MouseEvent me) {}

public void mouseReleased(MouseEvent me) {

mLastPoint = null;

}

}

private void handleResize() {

Dimension size = getSize();

mSizeChanged = false;

if (mImg == null) {

mImg = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);

Graphics g = mImg.getGraphics();

g.setColor(getBackground());

g.fillRect(0, 0, mImg.getWidth(), mImg.getHeight());

g.dispose();

}

else {

int newWidth = Math.max(mImg.getWidth(),getWidth());

int newHeight = Math.max(mImg.getHeight(),getHeight());

if (newHeight == mImg.getHeight() && newWidth == mImg.getWidth()) {

return;

}

BufferedImage bi2 = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);

Graphics g = bi2.getGraphics();

g.setColor(getBackground());

g.fillRect(0, 0, bi2.getWidth(), bi2.getHeight());

g.drawImage(mImg, mImg.getWidth(), mImg.getHeight(), null);

g.dispose();

mImg = bi2;

}

}

public JToolBar getToolBar() {

if (mToolBar == null) {

mToolBar = new ToolBar();

}

return mToolBar;

}

private ToolBar mToolBar;

public static void main (String args[]) {

PaintArea pa = new PaintArea();

JPanel parent = new JPanel();

parent.setLayout(new BorderLayout());

parent.add(pa, BorderLayout.CENTER);

pa.setPreferredSize(new Dimension(150, 150));

parent.add(pa.getToolBar(), BorderLayout.NORTH);

WindowUtilities.visualize(parent);

}

protected class CListener extends ComponentAdapter {

public void componentResized(ComponentEvent ce) {

mSizeChanged = true;

}

}

}

tjacobs01a at 2007-7-28 20:17:47 > top of Java-index,Desktop,Core GUI APIs...