由于延迟,Java Swing绘制错误的图片

时间:2013-04-21 00:38:04

标签: java swing synchronization

我是新手摇摆程序,我在线程同步方面遇到了一些困难。

我正在尝试迭代一个数组,并在每个索引处创建一个JPanel和一个JFrame,并希望在每个面板上绘制一张图片。与存储在数组中的值相关的图片。 但是所有的框架/面板只保留最后一个数组条目的图片。我认为这是由于一个单独的摆动螺纹(?),但我不知道如何改变它。 你能帮帮我吗?

package help;

import java.awt.Graphics;
import java.awt.image.BufferedImage; 
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class SwingSynchro{

private JPanel jPanel;
private JFrame jFrame;
int array[] = {1,2,3,4};
int current;
private BufferedImage image1;
private BufferedImage image2;
private BufferedImage image3;
private BufferedImage image4;

public SwingSynchro(){

    //try{
    //    image1 = ImageIO.read(new File("someFilePath1.png"));
    //    image2 = ImageIO.read(new File("someFilePath2.png"));
    //    image3 = ImageIO.read(new File("someFilePath3.png"));
    //    image4 = ImageIO.read(new File("someFilePath4.png"));
    //} catch(IOException e){
    //    e.printStackTrace();
    //    System.out.println("wrong file path");
    //}// try catch

    for(int i = 0 ; i < array.length ; i++){

        current = array[i];
            System.out.println("current Number: "+ current + " at array index:" +i);

            jPanel = new JPanel(){
                private static final long serialVersionUID = 6859593162185621113L;

                @Override
                protected void paintComponent(Graphics g){
                    super.paintComponent(g);

                    switch(current){
                        case 1:
                            System.out.println("case 1");
                            //g.drawImage(image1, 10, 10, getWidth() - 20, getHeight() - 20, this);
                            break;
                        case 2:
                            System.out.println("case 2");
                           // g.drawImage(image2, 20, 20, getWidth() - 40, getHeight() - 40, this);
                            break;
                        case 3:
                            System.out.println("case 3");
                            //g.drawImage(image3, 10, 10, getWidth() - 20, getHeight() - 20, this);
                            break;
                        case 4:
                            System.out.println("case 4");
                            //g.drawImage(image4, 10, 10, getWidth() - 20, getHeight() - 20, this);
                            break;
                        default:
                            System.out.println("RELEASE THE KRAKEN!");
                            break;
                    }// switch
                }// paintComponent()
            };// anonymous class(extends JPanel)


        jFrame = new JFrame(String.valueOf(current));
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setResizable(false);
        jFrame.getContentPane().add(jPanel);
        jFrame.setSize(200, 250);
        jFrame.setLocation(i * 203, 0);
        jFrame.setVisible(true);
    }
}
}

我注释掉了图片,因为控制台输出你可以清楚地看到drawImage方法在整个for循环之后被调用。

编辑:看起来没有其他线程,但在这种情况下,我不明白为什么图纸(或案例陈述)有这种延迟。你能解释一下为什么代码没有像往常一样执行。

这是输出:

current Number: 1 at array index:0
current Number: 2 at array index:1
current Number: 3 at array index:2
current Number: 4 at array index:3
case 4
case 4
case 4
case 4

2 个答案:

答案 0 :(得分:2)

Swing是单线程的。如果您想实时查看GUI更新,请使用Swing Timer

答案 1 :(得分:2)

您可以将JPanel设置为内部类,并使用字段来保存current变量的值,而不是将JPanel实例化为匿名类。

private static class CustomJPanel extends JPanel {
    private static final long serialVersionUID = 6859593162185621113L;
    private final int current;

    private CustomJPanel(int current) {
        this.current = current;
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);

        switch(current){
            case 1:
                System.out.println("case 1");
                //g.drawImage(image1, 10, 10, getWidth() - 20, getHeight() - 20, this);
                break;
            case 2:
                System.out.println("case 2");
                // g.drawImage(image2, 20, 20, getWidth() - 40, getHeight() - 40, this);
                break;
            case 3:
                System.out.println("case 3");
                //g.drawImage(image3, 10, 10, getWidth() - 20, getHeight() - 20, this);
                break;
            case 4:
                System.out.println("case 4");
                //g.drawImage(image4, 10, 10, getWidth() - 20, getHeight() - 20, this);
                break;
            default:
                System.out.println("RELEASE THE KRAKEN!");
                break;
        }// switch
    }// paintComponent()
}

然后将其实例化为

jPanel = new CustomJPanel(current);

这样,您确保在实例化JPanel时传递了current变量的值。