Swing重新绘制线程

时间:2013-11-03 23:37:47

标签: java multithreading swing jcomponent

我有2个jcomponents,动画和gardenpanel。我把它们放在jlayeredpane中,但动画类是一个始终保持运动的角色。当我在主方法中调用重绘时它非常不稳定且缓慢。所以我创建了一个名为Update的新类,它将实现runnable并启动一个只调用animation.repaint()的新线程。但它仍然是小丑和波涛汹涌。有什么帮助吗?

public class Driver {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run(){

                 JFrame frame = new JFrame();
                    JLayeredPane pane = new JLayeredPane();
                    Animation animation = new Animation();

                GardenPanel gPanel = new GardenPanel(6,4,600,800);



                frame.setSize(800,600);
                frame.add(pane);
                // establish transparent background
                //Color transparent = new Color(0,0,0,0);

                // Initilize jcomponents
                //Garden garden = new Garden(6,4); 

                //making jcomponents visible
                animation.setSize(frame.getSize());
                gPanel.setSize(frame.getSize());


                animation.setOpaque(true);
                pane.add(animation);
                pane.add(gPanel);
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);


            }

        });

-------动画类-------

package view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;



  public class Animation extends JComponent implements MouseMotionListener, MouseListener{
    final int frameCount = 10;
    int picNum = 0;
    BufferedImage[][] pics;
    int xloc = 0;
    int yloc = 0;
    final int xIncr = 8;
    final int yIncr = 2;
    final static int frameWidth = 900;
    final static int frameHeight = 600;
    final static int imgWidth = 165;
    final static int imgHeight = 165;
    //basic info about the orc
    Color c = new Color(0, 0, 0, 0);

    BufferedImage seedImage; 
    int mouseX;
    int mouseY;
    int seedX = xloc+imgWidth/2;
    int seedY = yloc+imgHeight/2;
    int shootX;
    int shootY;
    boolean seedShooting = false;
    boolean mouseholding;
    boolean moving = false;
    int power;
    public enum stage {
        MOVE, POWER
    }
    stage s;
    int seedPower;
    long pSeedTime;
    long cSeedTime;
    double seedPowerRatio = 0.75;

    //Override this JPanel's paint method to cycle through picture array and draw images
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        picNum = (picNum + 1) % frameCount;
        if(mouseholding && (s == s.POWER)){
            System.out.println(power++);
        }
        if(seedShooting){
            cSeedTime = System.currentTimeMillis();

            seedX = (int) ( seedPowerRatio * 1*seedPower*1.5*(cSeedTime - pSeedTime)/50 + shootX ); // calculate x-coor of seed
            seedY = (int) ( seedPowerRatio * (-1)*seedPower*1.5*((int)(cSeedTime - pSeedTime))/50 + 0.5*0.02*(cSeedTime - pSeedTime)*(cSeedTime - pSeedTime)/(50^2) +shootY);   
            //calculate y-coor of seed
        }
        if(seedY>shootY+imgWidth/4){
            seedShooting = false;
            seedX = xloc+imgWidth/2;
            seedY = yloc+imgHeight/2;
        }
        g.drawImage(pics[1][picNum], xloc, yloc, c, this);
        g.drawImage(seedImage, seedX, seedY, imgWidth/8, imgHeight/8, this);
    }



    //Constructor: get image, segment and store in array
    public Animation(){
        seedImage = createImage(); ;
        BufferedImage[] img = createAnimation();
        pics = new BufferedImage[img.length][10];
        for(int j = 0; j < img.length; j++){
            for(int i = 0; i < frameCount; i++)
                pics[j][i] = img[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight);
        }
        addMouseMotionListener(this);
        addMouseListener(this);

        Thread background = new Thread(new Background());
        //background.setDaemon(true);
        background.start();

    }  

    //Read image from file and return
    private BufferedImage[] createAnimation(){
        BufferedImage[] bufferedImage = new BufferedImage[4];
        try {
            bufferedImage[0] = ImageIO.read(new File("images/orc_forward_southeast.png"));
            bufferedImage[1] = ImageIO.read(new File("images/orc_forward_southwest.png"));
            bufferedImage[2] = ImageIO.read(new File("images/orc_forward_northeast.png"));
            bufferedImage[3] = ImageIO.read(new File("images/orc_forward_northwest.png"));
            return bufferedImage;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private BufferedImage createImage(){
        BufferedImage bufferedImage;
        try {
            bufferedImage = ImageIO.read(new File("images/seed.png"));
            return bufferedImage;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

        // TODO: Change this method so you can load other orc animation bitmaps
    }

    // implement the method in mouseListener and mouseMotionListener interface
    @Override
    public void mouseDragged(MouseEvent event) {
        mouseX = event.getX();
        mouseY = event.getY();
        if( ( xloc<mouseX ) && (xloc+imgWidth >mouseX) && (yloc<mouseY) && (yloc+imgHeight>mouseY) && (s==stage.MOVE) ){
            //System.out.println("Imagecoor:("+xloc+", "+yloc+")"+" mousecoor:("+mouseX+","+mouseY+")"); 
            // you can print the coordinate if you want     
            //xloc = mouseX-imgWidth/2;
            yloc = mouseY-imgHeight/2;
            seedX = xloc + imgWidth/2;
            seedY = yloc + imgHeight/2;
        }   
    } // draging the image
    @Override
    public void mouseMoved(MouseEvent arg0) {
    }
    @Override
    public void mouseClicked(MouseEvent e) {
    }
    @Override
    public void mouseEntered(MouseEvent e) {    
    }
    @Override
    public void mouseExited(MouseEvent e) { 
    }

    // for increasing the power.
    @Override
    public void mousePressed(MouseEvent event) { 
        mouseholding = true;
        mouseX = event.getX();
        mouseY = event.getY();
        if((xloc+imgWidth/2+1> mouseX) && (xloc-imgWidth/2-1< mouseX)&&(yloc+imgHeight/2+1 > mouseY)&&(yloc-imgHeight/2-1 < mouseY)  ){     
            s = stage.POWER;
        }
    }
    @Override
    public void mouseReleased(MouseEvent event) {
        mouseholding = false;
        if(s == stage.POWER){
            pSeedTime = System.currentTimeMillis();
            seedPower = power;
            shootX = seedX;
            shootY = seedY;
            seedShooting = true;
        }
        s = stage.MOVE;
        power = 0;
    }

    protected class Background implements Runnable{

        @Override
        public void run() {
            while(true){

                repaint();


            }
        }


    }

1 个答案:

答案 0 :(得分:1)

Thread background = new Thread(new Background());
    //background.setDaemon(true);
    background.start();

以及您的Background()可运行代码:

protected class Background implements Runnable{

        @Override
        public void run() {
            while(true){ <-- it is true, true and true, who is changing it?

                repaint();


            }
        }

永远致电repaint()请求,无结束,无sleep控件。处理器中会发生多少个周期?你的处理器什么时候可以休息一下与其他计算单元交谈?