Java 重新油漆
我想重新粉刷我的jPanel 我有一个App类来处理这个JFrame中的屏幕显示,我添加了一个Board JPanel对象来处理所有的JPanel。 在我上的董事会课上Java 重新油漆,java,swing,jpanel,repaint,concurrency,Java,Swing,Jpanel,Repaint,Concurrency,我想重新粉刷我的jPanel 我有一个App类来处理这个JFrame中的屏幕显示,我添加了一个Board JPanel对象来处理所有的JPanel。 在我上的董事会课上 ex = new Explosion(10, 10); new Thread(ex).start(); 在我的爆炸类中,我有一个构造函数裁剪我的sprite文件,覆盖paint()和: public void run() { while(光标
ex = new Explosion(10, 10);
new Thread(ex).start();
在我的爆炸类中,我有一个构造函数裁剪我的sprite文件,覆盖paint()和:
public void run()
{
while(光标<(行*列))
{
重新油漆();
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(光标);
游标++;
}
}
循环工作正常,但我的屏幕上没有重新绘制,只显示第一幅图像
我可以做些什么来刷新
谢谢
编辑:
这是我的密码:
public class Explosion extends JPanel implements Runnable{
private BufferedImage img;
final int width = 320;
final int height = 320;
final int rows = 5;
final int cols = 5;
private int x,y;
private int cursor;
BufferedImage[] sprites = new BufferedImage[rows * cols];
public Explosion(int x, int y)
{
this.x = x;
this.y = y;
try {
try {
this.img = ImageIO.read(new File((this.getClass().getResource("files/explosion2.png")).toURI()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
cursor = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sprites[(i * cols) + j] = img.getSubimage(
i * (width/rows),
j * (height/cols),
width/rows,
height/cols
);
}
}
}
public void run()
{
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
cursor++;
repaint();
}
};
while(cursor < (rows*cols))
{
new Timer(50, taskPerformer).start();
if (cursor==(rows*cols)-1)
cursor=0;
}
}
public void paintComponent(Graphics g){
System.out.println("paintComponent");
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(sprites[cursor], x, y, this);
g.dispose();
}
/*public void paint(Graphics g) {
super.paint(g);
System.out.println("paint");
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(sprites[cursor], x, y, this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}*/
}
public class Main extends JFrame{
public Main()
{
Board board = new Board();
add(board);
setTitle("Explosion");
setSize(500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
public class Board extends JPanel{
Explosion ex;
public Board()
{
setDoubleBuffered(true);
ex = new Explosion(10,10);
new Thread(ex).start();
}
public void paint(Graphics g) {
ex.paintComponent(g);
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
}
公共类爆炸扩展JPanel实现可运行{
专用缓冲图像img;
最终整数宽度=320;
最终内部高度=320;
最终整数行=5;
最终整数cols=5;
私有整数x,y;
私有int游标;
BuffereImage[]精灵=新的BuffereImage[行*列];
公共爆炸(整数x,整数y)
{
这个.x=x;
这个。y=y;
试一试{
试一试{
this.img=ImageIO.read(新文件((this.getClass().getResource(“files/explosion2.png”)).toURI());
}捕获(URISyntaxException e){
e、 printStackTrace();
}
}捕获(IOE异常){
e、 printStackTrace();
}
光标=0;
对于(int i=0;i
必须在EDT中调用重新绘制
使用SwingUtilities.invokeAndWait()或invokeLater()调用重新绘制。必须在EDT中调用重新绘制 使用SwingUtilities.invokeAndWait()或invokeLater()调用重新绘制。@StanislavL(我还不能评论):不,您不必在EDT中调用
repaint()
:
从任何线程调用以下JComponent方法都是安全的:repaint()
、revalidate()
和invalidate()
。repaint()
和revalidate()
方法分别对事件调度线程调用paint()
和validate()
的请求进行排队。invalidate()
方法只是将组件及其所有直接祖先标记为需要验证
资料来源:
cursor
是否声明为volatile
?如果没有,EDT可能看不到线程对光标所做的更改。因此,始终绘制第一幅图像。@StanislavL(我还不能评论):不,您不必在EDT中调用repaint()
:
从任何线程调用以下JComponent方法都是安全的:repaint()
、revalidate()
和invalidate()
。repaint()
和revalidate()
方法分别对事件调度线程调用paint()
和validate()
的请求进行排队。invalidate()
方法只是将组件及其所有直接祖先标记为需要验证
资料来源:
cursor
是否声明为volatile
?如果没有,EDT可能看不到线程对光标所做的更改。因此,始终绘制第一个图像
不要覆盖paint
,而是覆盖paintComponent
不要使用Thread.sleep
,而是使用实用程序类,例如以指定的间隔执行特定操作。这将确保所有更改都在EDT上完成,并且等待发生在后台线程中
请注意,如果没有可编译的代码,很难判断真正的问题是什么;这全是猜测
不要覆盖paint
,而是覆盖paintComponent
不要使用Thread.sleep
,而是使用实用程序类,例如以指定的间隔执行特定操作。这将确保所有更改都在EDT上完成,并且等待发生在后台线程中
请注意,如果没有可编译的代码
public class Explosion extends JPanel implements Runnable{
private BufferedImage img;
final int width = 320;
final int height = 320;
final int rows = 5;
final int cols = 5;
private int x,y;
private int cursor;
BufferedImage[] sprites = new BufferedImage[rows * cols];
public Explosion(int x, int y)
{
this.x = x;
this.y = y;
try {
try {
this.img = ImageIO.read(new File((this.getClass().getResource("files/explosion2.png")).toURI()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
cursor = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sprites[(i * cols) + j] = img.getSubimage(
i * (width/rows),
j * (height/cols),
width/rows,
height/cols
);
}
}
}
public void run()
{
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
cursor++;
repaint();
}
};
while(cursor < (rows*cols))
{
new Timer(50, taskPerformer).start();
if (cursor==(rows*cols)-1)
cursor=0;
}
}
public void paintComponent(Graphics g){
System.out.println("paintComponent");
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(sprites[cursor], x, y, this);
g.dispose();
}
/*public void paint(Graphics g) {
super.paint(g);
System.out.println("paint");
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(sprites[cursor], x, y, this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}*/
}
public class Main extends JFrame{
public Main()
{
Board board = new Board();
add(board);
setTitle("Explosion");
setSize(500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
public class Board extends JPanel{
Explosion ex;
public Board()
{
setDoubleBuffered(true);
ex = new Explosion(10,10);
new Thread(ex).start();
}
public void paint(Graphics g) {
ex.paintComponent(g);
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
}