使用多线程重绘paintComponent
use mutli thread to repaint paintComponent
我想用Thread重绘两张图,但总是只重绘pan2。
屏幕显示蓝色背景和只有一张照片。
我还以为有两条鱼在游呢
import java.awt.*;
import java.util.Random;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class demo {
public static void main(String args[]) throws IOException{
JFrame frm = new JFrame("sea");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel pan = new drawPanel(50,50,1);
drawPanel pan2 = new drawPanel(100,100,2);
pan.newThread.start();
pan2.newThread.start();
frm.add(pan);
frm.add(pan2);
frm.setSize(300, 300);
frm.setVisible(true);
}
}
class drawPanel extends JPanel implements Runnable{
int X,Y,moveX,moveY,dirX=1,dirY=1;
private Image img_icon;
Thread newThread;
int a;
static int width = 300;
static int height = 300;
drawPanel (int x,int y,int num) throws IOException {
File file = new File("fish"+num+".png");
a= num;
img_icon = ImageIO.read(file);
X = x;
Y = y;
newThread = new Thread(this);
}
public void paintComponent( Graphics g ) {
super.paintComponent( g );
this.setBackground( Color.blue );
g.drawImage(img_icon, X, Y,this);
}
public void stop(){
newThread = null;
}
pan1 和 pan2s 的线程工作正常,但 pan1s 的重绘不起作用。
public void run() {
while(newThread != null)
{
repaint();
try
{
Thread.sleep(50);
}
catch(InterruptedException E){ }
moveX = dirX*((int)(Math.random()*100)%3);
moveY = dirY*((int)(Math.random()*100)%3);
X = X + moveX;
Y = Y + moveY;
}
}
您的问题与线程或绘画无关,而与布局管理器有关。您以默认方式将这两个组件添加到使用 BorderLayout 的容器、JFrame 的 contentPane,因此第二个组件将覆盖第一个组件。
解决方案:改变容器的布局,比如GridLayout。
请注意,如果您希望鱼在同一区域一起游动,那么您的设置是错误的——您应该只有一个绘图面板,并且鱼应该是在该单一绘图面板上绘制的逻辑结构绘制 JPanel,而不是 GUI 结构。
顺便说一句,您将想要学习和使用 Java naming conventions。变量名称应全部以小写字母开头,而 class 名称应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。
我想用Thread重绘两张图,但总是只重绘pan2。 屏幕显示蓝色背景和只有一张照片。 我还以为有两条鱼在游呢
import java.awt.*;
import java.util.Random;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class demo {
public static void main(String args[]) throws IOException{
JFrame frm = new JFrame("sea");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel pan = new drawPanel(50,50,1);
drawPanel pan2 = new drawPanel(100,100,2);
pan.newThread.start();
pan2.newThread.start();
frm.add(pan);
frm.add(pan2);
frm.setSize(300, 300);
frm.setVisible(true);
}
}
class drawPanel extends JPanel implements Runnable{
int X,Y,moveX,moveY,dirX=1,dirY=1;
private Image img_icon;
Thread newThread;
int a;
static int width = 300;
static int height = 300;
drawPanel (int x,int y,int num) throws IOException {
File file = new File("fish"+num+".png");
a= num;
img_icon = ImageIO.read(file);
X = x;
Y = y;
newThread = new Thread(this);
}
public void paintComponent( Graphics g ) {
super.paintComponent( g );
this.setBackground( Color.blue );
g.drawImage(img_icon, X, Y,this);
}
public void stop(){
newThread = null;
}
pan1 和 pan2s 的线程工作正常,但 pan1s 的重绘不起作用。
public void run() {
while(newThread != null)
{
repaint();
try
{
Thread.sleep(50);
}
catch(InterruptedException E){ }
moveX = dirX*((int)(Math.random()*100)%3);
moveY = dirY*((int)(Math.random()*100)%3);
X = X + moveX;
Y = Y + moveY;
}
}
您的问题与线程或绘画无关,而与布局管理器有关。您以默认方式将这两个组件添加到使用 BorderLayout 的容器、JFrame 的 contentPane,因此第二个组件将覆盖第一个组件。
解决方案:改变容器的布局,比如GridLayout。
请注意,如果您希望鱼在同一区域一起游动,那么您的设置是错误的——您应该只有一个绘图面板,并且鱼应该是在该单一绘图面板上绘制的逻辑结构绘制 JPanel,而不是 GUI 结构。
顺便说一句,您将想要学习和使用 Java naming conventions。变量名称应全部以小写字母开头,而 class 名称应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。