設計一個動畫程序,在圖片移動的同時變換不同的圖片,同時垂直線和水平線不斷延長,必須使用多線程的方式實現。
實現代碼:
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
class MainClass extends JPanel implements Runnable{
private Image[] im=new Image[3];
private int i=0;
private int X=100,Y=90;
Thread thread1;
public MainClass() {
try{
for(int j=0;j<3;j++)
im[j]=ImageIO.read(new File("image/"+j+".png"));
}catch(Exception e){
System.out.println("error");
}
this.start();
}
public void random(){
X=(int)(Math.random()*600);
Y=(int)(Math.random()*400);
}
public void start(){
thread1=new Thread(this);
thread1.start();
}
public void run(){
while(true){
try{
Thread.sleep((int)(Math.random()*2000));
}catch(InterruptedException e){}
this.random();
repaint();
}
}
public void paint(Graphics g) {
super.paint(g);
if(i==3)i=0;
g.drawImage(im[i],X,Y,44,44,this);//圖片錕斤拷錕斤拷錕斤拷爲44*44 錕斤拷錕斤拷一錕斤拷錕斤拷錕轎匡拷爲44*44錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷示
g.drawLine(X+22,0,X+22,Y);
g.drawLine(0,Y+22,X,Y+22);
i++;
}
}
public class myFrame extends JFrame{
public static void main(String[] args){
myFrame myframe=new myFrame();
MainClass mypanel=new MainClass();
myframe.add(mypanel);
myframe.setSize(700,500);
myframe.setVisible(true);
myframe.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
其中,public void paint(Graphics g)必須調用super.paint(),否則將會出現下面所示的情況:
從java JDK1.8.0_73的源碼javax\swing\JComponent.java 中找到public void paint(Graphcis g)的實現代碼如下:
public void paint(Graphics g) {
boolean shouldClearPaintFlags = false;
if ((getWidth() <= 0) || (getHeight() <= 0)) {
return;
}
Graphics componentGraphics = getComponentGraphics(g);
Graphics co = componentGraphics.create();
try {
RepaintManager repaintManager = RepaintManager.currentManager(this);
Rectangle clipRect = co.getClipBounds();
int clipX;
int clipY;
int clipW;
int clipH;
if (clipRect == null) {
clipX = clipY = 0;
clipW = getWidth();
clipH = getHeight();
}
else {
clipX = clipRect.x;
clipY = clipRect.y;
clipW = clipRect.width;
clipH = clipRect.height;
}
if(clipW > getWidth()) {
clipW = getWidth();
}
if(clipH > getHeight()) {
clipH = getHeight();
}
if(getParent() != null && !(getParent() instanceof JComponent)) {
adjustPaintFlags();
shouldClearPaintFlags = true;
}
int bw,bh;
boolean printing = getFlag(IS_PRINTING);
if (!printing && repaintManager.isDoubleBufferingEnabled() &&
!getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
(getFlag(IS_REPAINTING) || repaintManager.isPainting()))
{
repaintManager.beginPaint();
try {
repaintManager.paint(this, this, co, clipX, clipY, clipW,
clipH);
} finally {
repaintManager.endPaint();
}
}
else {
// Will ocassionaly happen in 1.2, especially when printing.
if (clipRect == null) {
co.setClip(clipX, clipY, clipW, clipH);
}
if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
if (!printing) {
paintComponent(co);
paintBorder(co);
}
else {
printComponent(co);
printBorder(co);
}
}
if (!printing) {
paintChildren(co);
}
else {
printChildren(co);
}
}
} finally {
co.dispose();
if(shouldClearPaintFlags) {
setFlag(ANCESTOR_USING_BUFFER,false);
setFlag(IS_PAINTING_TILE,false);
setFlag(IS_PRINTING,false);
setFlag(IS_PRINTING_ALL,false);
}
}
}