|
Hello! I was coding a java applet and encountered a weird problem. The solution is probably simple but I haven't figured it out.
I have a class which extends class Canvas and implements interface Mouselistener. Objects created from that class are shown in applet. When users clicks the canvas the image in it is supposed to change (object represents a playing-card which flips when it's clicked).
The problem is that paint (and also update) method is called only in every second clicks, although repaint() is called everytime.
Here is a snippet from the code:
public void paint(Graphics g) {
System.out.println("Sum1 called paint(Graphics).");
/* Draw. */
}
private void flip() {
System.out.println("Sum1 called flip().");
if (i == back) i = face;
else i = back;
repaint();
}
public void mousePressed(MouseEvent e) { flip(); }
The card should flip every time but here's what happens:
Sum1 called paint(Graphics). <-- Card is drawn the first time.
Sum1 called flip() <-- click
Sum1 called flip() <-- click
Sum1 called paint(Graphics). <-- paint is called (but the image naturally stays same)
Sum1 called flip() etc...
Sum1 called flip()
Sum1 called paint(Graphics).
So what's going on? This is driving me nuts. ;-)
|
|
|
It sounds like you could be loading images inside the paint method. If so, move the loading code to a method that will be called during construction.
// <applet code="DrawingTest" width="400" height="400"></applet>
// use: >appletviewer DrawingTest.java
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.swing.ImageIcon;
public class DrawingTest extends Applet
{
public void init()
{
Image[] images = getImages();
DrawingCanvas drawingCanvas = new DrawingCanvas(images);
ImageController controller = new ImageController(drawingCanvas);
drawingCanvas.addMouseListener(controller);
setLayout(new BorderLayout());
add(drawingCanvas);
}
private Image[] getImages()
{
String[] pathNames = { "/forum/Bird.gif", "/forum/Rabbit.gif" };
String prefix = "images/";
Image[] images = new Image[pathNames.length];
for(int j = 0; j < images.length; j++)
{
// getResource searches class path for files
URL url = getClass().getResource(prefix + pathNames[j]);
if(url == null)
reportError("null url for: " + pathNames[j]);
ImageIcon icon = new ImageIcon(url);
int status = icon.getImageLoadStatus();
if(status != MediaTracker.COMPLETE)
reportError("image loading error: " + status);
images[j] = icon.getImage();
}
return images;
}
private void reportError(String errorMessage)
{
System.err.println(errorMessage);
System.exit(5);
}
public static void main(String[] args)
{
Applet applet = new DrawingTest();
Frame f = new Frame();
f.addWindowListener(closer);
f.add(applet);
f.setSize(400,400);
f.setLocation(200,200);
applet.init();
f.setVisible(true);
}
private static WindowListener closer = new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
};
}
class DrawingCanvas extends Canvas
{
Image[] images;
int imageIndex;
public DrawingCanvas(Image[] images)
{
this.images = images;
imageIndex = 0;
}
public void paint(Graphics g)
{
super.paint(g);
int w = getWidth();
int h = getHeight();
int imageWidth = images[imageIndex].getWidth(this);
int imageHeight = images[imageIndex].getHeight(this);
int x = (w - imageWidth)/2;
int y = (h - imageHeight)/2;
g.drawImage(images[imageIndex], x, y, this);
}
public void update(Graphics g)
{
paint(g);
}
public void flip()
{
imageIndex = ++imageIndex > 1 ? 0 : 1;
repaint();
}
}
class ImageController extends MouseAdapter
{
DrawingCanvas drawingCanvas;
public ImageController (DrawingCanvas dc)
{
drawingCanvas = dc;
}
public void mousePressed(MouseEvent e)
{
drawingCanvas.flip();
}
}
|
|
|
|
|
Nope. Images are loaded during construction. Paint method looks like this (i is Image):
public void paint(Graphics g) {
System.out.println("Sum1 called paint(Graphics).");
g.drawImage(i,0,0,this);
}
|
|
In the flip method i is changed to refer to another Image. The problem is the paint method doesn't get called every time the canvas is clicked (only every second time). flip is called on every click.
|
|
|
Now it's working! I don't know why though. I put the images in an array as in the example above. Why it didn't work the original way is still a mystery for me... thanks!
|
|
|
|
|
|
|
|