0

これが私の単純なコードの一部です。このコードには、移動可能な楕円形と座標付きの静的な楕円形が含まれていますnewX=100,newY=100。マウスの左ボタンを押した後、その可動な楕円形を自動的に移動させようとしています。移動コード行は新しいスレッドにthreadあります。 、しかし、何も起こりません。矢印キーを使用して 1 つの移動を行った直後に、楕円形が移動を開始します。repaint()別の場所でメソッドを呼び出してみましたが、役に立たないようです。何か提案はありますか? ありがとうございました!

public class Buffer extends JPanel implements Runnable,KeyListener,MouseListener{
public static int x;
public static int y;
public static int newX;
public static int newY;
public static Thread thread;
public static boolean check;
public static JFrame frame;
public static int pointX;
public static int pointY;
public static boolean repaint;


public void paintComponent(Graphics g){
    super.paintComponent(g);

    g.drawOval(x, y, 20, 20);

        newX=100;
        newY=100;
        g.fillOval(newX, newY, 20, 20);

        if(repaint)
            repaint();
}
public static void main(String args[]){
    Buffer z=new Buffer();
    z.setBackground(Color.white);

    frame=new JFrame();
    frame.setSize(500,500);
    frame.addKeyListener(z);
    frame.addMouseListener(z);
    frame.add(z);
    frame.setVisible(true);
    frame.requestFocusInWindow();

    thread=new Thread(){
        public void run(){
            try{
                for(int i=0;i<=5;i++){
                    x=x+i;
                    repaint=true;
                    thread.sleep(1000);

                }
            }catch(InterruptedException v){System.out.println(v);}
           }
        };

}
public void keyPressed(KeyEvent e){
    if(e.getKeyCode()==KeyEvent.VK_LEFT){
        x=x-10;
        repaint();
    }
    if(e.getKeyCode()==KeyEvent.VK_RIGHT){
        x=x+10;
        repaint();
    }
    if(e.getKeyCode()==KeyEvent.VK_UP){
        y=y-10;
        repaint();
    }
    if(e.getKeyCode()==KeyEvent.VK_DOWN){
        y=y+10;
        repaint();
    }
}

public void mouseClicked(MouseEvent e) {
        thread.start();
    }
}
4

2 に答える 2

2

スレッドから共有変数を変更し、同期を行わずに別のスレッドからそれらを読み取ります。それは間違っている。共有変数へのすべてのアクセスは、同期された方法で行うか、スレッドセーフなオブジェクト (たとえば AtomicInteger など) を使用する必要があります。

さらに、スレッドはxループ内で値を変更しますが、 を呼び出すことはrepaint()ないため、パネル自体を再描画する理由はありません。

于 2013-07-26T15:57:39.560 に答える
1

それがここで考えられる問題かどうかはわかりませんが、試してみます。

コードはスレッドセーフではないため、変数xと変数に AtomicInteger を使用してみてください。y

複数のスレッド間で共有変数にアクセスしようとしており、アトミックではないためスレッドセーフではないインクリメント操作を実行しています。

private static AtomicInteger x = new AtomicInteger(0); //take the initial value that you need

//where you are incrementing the x
x.incrementAndGet();


//where you want to read x
value = x.get();
于 2013-07-26T15:58:02.353 に答える