有没有办法在Java中使用Thread在JPanel上绘制图形?

时间:2015-11-08 16:21:35

标签: java multithreading graphics

在下面的代码中,我试图从paint方法中绘制一个椭圆,并从Thread中绘制另一个椭圆。但是只有从paint方法中绘制的椭圆显示在JPanel上。如果不可能,那么请说明替代方案。

import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Ani extends JPanel{

    public Ani(){
        JFrame jf = new JFrame();
        jf.setSize(555,555);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(this);
        jf.setVisible(true);
    }

    public void paint(Graphics g){         
         g.fillOval(22,22, 55, 55);  
         Thread t = new Thread(new MyThread(g)); 
         t.start();
    }

    public static void main(String[] args) {
        new Ani();
    }

}

class MyThread extends Thread{
    Graphics g;
    MyThread(Graphics g){
        this.g = g; 
    }

    public void run(){
        g.fillOval(222, 222, 55, 55);       
    }
}

2 个答案:

答案 0 :(得分:0)

修改

所有绘制到swing组件都应该由UI线程通过paintComponent(Graphics g)方法完成

结束编辑

如果要在循环中绘制动画,则应使用javax.swing.timer

int x = 0;

public void paintComponent(Graphics g) {
  g.drawString("Hello World", x * 10, 40);
}
//...
public void init() {
  //...
  Timer t = new Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
      x = (x + 1) % 10;
      repaint();
    }
  });
}

答案 1 :(得分:0)

试试这个

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Ani2 extends JPanel implements Runnable{
private Thread animator;
int x=0, y=0;
private final int DELAY = 50;
    public Ani2(){
        JFrame jf = new JFrame();
        jf.setSize(555,555);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(this);
        jf.setVisible(true);
    }

    @Override
    public void addNotify() {
        super.addNotify();
        animator = new Thread(this);
        animator.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        g2d.fillOval(x,y, 55, 55);
        g.dispose();
    }
    public void cycle() {

        x += 1;
        y += 1;
    }

    public static void main(String[] args) {
        new Ani2();
    }

    @Override
    public void run() {
        long beforeTime, timeDiff, sleep;

        beforeTime = System.currentTimeMillis();

        while (true) {

            cycle();
            repaint();

            timeDiff = System.currentTimeMillis() - beforeTime;
            sleep = DELAY - timeDiff;

            if (sleep < 0)
                sleep = 2;
            try {
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                System.out.println("interrupted");
            }

            beforeTime = System.currentTimeMillis();
        }
    }

}