1

私はプログラムをスイングするのが初めてで、スレッドの同期に問題があります。

配列を反復処理して、すべてのインデックスで JPanel と JFrame を作成し、各パネルに画像を描画したいと考えています。配列に格納された値に関連する画像。ただし、すべてのフレーム/パネルは、最後の配列エントリの画像のみを保持します。これは別のswing-Thread(?)が原因だと思いますが、変更方法がわかりません。手伝って頂けますか?

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);
    }
}
}

コンソール出力を見ると、for ループ全体の後に drawImage メソッドが呼び出されることがはっきりとわかるため、画像をコメントアウトしました。

編集:他のスレッドはないようですが、その場合、図面(またはケースステートメント)にこの遅延がある理由がわかりません。コードが通常どおり実行されない理由を教えてください。

出力は次のとおりです。

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
4

2 に答える 2

2

JPanel を匿名クラスとしてインスタンス化する代わりに、それを内部クラスにして、フィールドを使用してcurrent変数の値を保持することができます。

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);

currentこのようにして、JPanel がインスタンス化されたときに変数が持っていた値が渡されたことを確認します。

于 2013-04-21T00:55:40.270 に答える
2

Swing はシングルスレッドです。GUI の更新をリアルタイムで確認したい場合は、スイング タイマーを使用します。

于 2013-04-21T00:41:38.947 に答える