I know a lot of people had the same problem as me, but I can't seem to able to fix my applet looking at their solutions. I should probably use JApplet, JFrames and JPanel to do this project but I want to do a project first with Applet before I move on to using Japplet(I want to see the difference between those two). Could someone please look at my paint method and see why it flickers? Can't seem to be able to double buffer it.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Main extends Applet implements Runnable, KeyListener {
private Ninja ninja;
private Image character;
private URL base;
@Override
public void init() {
setSize(800, 480);
setBackground(Color.WHITE);
setFocusable(true);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("NinjaGirl");
addKeyListener(this);
try {
base = getDocumentBase();
} catch (Exception e) {
}
character = getImage(base, "data/FrontStanding.png");
super.init();
}
@Override
public void start() {
ninja = new Ninja();
Thread thread = new Thread(this);
thread.start();
super.start();
}
@Override
public void stop() {
super.stop();
}
@Override
public void destroy() {
super.destroy();
}
@Override
public void update(Graphics g) {
super.update(g);
}
@Override
public void paint(Graphics g) {
g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);
}
@Override
public void run() {
while (true) {
ninja.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
ninja.moveUp();
System.out.println("Up key pressed");
break;
case KeyEvent.VK_DOWN:
ninja.moveDown();
break;
case KeyEvent.VK_RIGHT:
ninja.moveRight();
break;
case KeyEvent.VK_LEFT:
ninja.moveLeft();
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
ninja.stop();
break;
case KeyEvent.VK_DOWN:
ninja.stop();
break;
case KeyEvent.VK_RIGHT:
ninja.stop();
break;
case KeyEvent.VK_LEFT:
ninja.stop();
break;
}
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
You're primary problem is here...
@Override
public void update(Graphics g) {
super.update(g);
}
@Override
public void paint(Graphics g) {
g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);
}
Applet
(and all top level containers) is not double buffered, this means, you are drawing directly onto the screen device. Some of the these functions can be slow (flood fill for example) which, if done fast enough, can cause flickering.
Instead, you need to implement your own double buffering process
@Override
public void update(Graphics g) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(getWidth(), getHeight(), Transparency.OPAQUE);
Graphics2D g2d = image.getGraphics();
super.update(g2d);
g2d.dispose();
g.drawImage(image, 0, 0, this);
}
@Override
public void paint(Graphics g) {
g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);
}
Now, having said that, Applet is over 15 years out of date and was replaced with JApplet
and the Swing API.
Instead, you should start creating your UI on something like a JPanel
and override it's paintComponent
method and do your custom painting there.
Swing components are double buffered by default, so you don't need to go to the extra trouble...unless you really, really want to
You can then add this to whatever top level container you like JFrame
, JWindow
, JDialog
, JApplet
Take a look at Performing Custom Painting for more details
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.