1

私はピンポン(一種)のプロジェクトを持っていて、それは動作しますが、run()関数に問題があります。パネルに書き込んだ関数でフレームを描画すると(動作しますが、チェックしました)、グラフィックの問題が発生します。再ペイントを使用すると(私が想定しているように)、フレームを描画してすぐに削除すると、すべての解決策が役立ちます(私のコードのレベルでは単純なものの方が良いです):

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import java.util.Random;
import javax.swing.*;
import sun.org.mozilla.javascript.internal.Kit;



public class Picture extends JPanel implements MouseListener, Runnable{

    private int k = 0;
    Thread MyThread;
    private DrawPic img;
 
    private Rectangle r1, r3;

    public Picture(DrawPic img, Rectangle rect1, Rectangle rect3) {
        super();
        this.setLocation(0, 85);
        this.setLayout(new FlowLayout());
        this.setSize(1280, 1024);
          
        this.addMouseListener(this);
        this.setFocusable(true);
      
        this.r1 = rect1;
    
        this.r3 = rect3;
        this.img = img;
        this.MyThread = new Thread(this);
        MyThread.start();
        this.setVisible(true);
    
    }
    
    

 
    public void paintRectangleL(Rectangle rect, Graphics g) {
        k = 3;
        
        rect.DrawRectangle(g);
        rect.FillRectangle(g);


    }
    public void paintRectangleR(Rectangle rect, Graphics g) {
        k = 1;
      
        rect.DrawRectangle(g);
        rect.FillRectangle(g);

    }
    public void paintImage(DrawPic img, Graphics g) {
        k = 2;
     
        //g.clearRect(0, 0, this.getWidth(), this.getHeight());
        img.DrawImg(g, this);
        


    }
    public void changeK(int k1){
        k = k1;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // throw new UnsupportedOperationException("Not supported yet.");
      
        
       
    }

    @Override
    public void mousePressed(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
        
            Point p = r3.FindCenter();
            double dx, dy;

            dy = e.getY() - p.getY();
            r3.Move(0, dy);
              this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight());
            this.paintRectangleL(r3, this.getGraphics());
            this.paintRectangleR(r1, this.getGraphics());
            this.paintImage(img, this.getGraphics());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //   throw new UnsupportedOperationException("Not supported yet.");
    }
    public void animate(){
        double dx = 0, dy = 2;
        if ((this.img.getX() + 160 + this.r1.RightPoint().getX() - this.r1.LeftPoint().getX() > this.getWidth() || this.img.getX() < this.r3.RightPoint().getX() - this.r3.LeftPoint().getX())) {
                    dx = -1 * dx;
                    

                }
                if (this.img.getY() + 120> this.getHeight() || this.img.getY() < 0 ) {
                    dy = -1 * dy;
                }
                img.Move(dx, dy);
             //   this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight());
              //  this.paintImage(img, this.getGraphics());
              //  this.paintRectangleL(r3, this.getGraphics());
              //  this.paintRectangleR(r1, this.getGraphics());
                repaint();            
    }

    @Override
    public void run() {
        
        Color col;
        while (true) {
                 animate();

                try {
                    MyThread.sleep(35);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Picture.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        //   throw new UnsupportedOperationException("Not supported yet.");
    }
4

1 に答える 1

5

getGraphics()カスタムペイントは、次の再ペイントで再利用される一時的なバッファであるため、使用しないでください。で絵を描いていますかpaintComponent()

詳細と例については、カスタムペイントの実行を参照してください。セクションAペイントメカニズムpaint()の詳細には、方法の概要が記載されていpaintComponent()ます。AWTおよびSwingでのペイントも参照してください。

編集:

プログラムのロジックと構造は、Swingのペイントプロセスに適合していません。プログラムをリファクタリングして、そのプロセスにプラグインし、適切なタイミングで適切なものをペイントできるようにする必要があります。通常、コンポーネントをオーバーライドしてコンポーネントをカスタマイズしますpaintComponent()。その方法では、すべてのペイントが行われます。この方法はできるだけ速くする必要があります。そこにアプリケーションロジックを入れすぎないようにしてください。

状態が変化したら、ペイントされたオブジェクトのある種の状態(つまり、座標、色など)を維持する必要がありますrepaint()。これにより、再ペイントがスケジュールされ、最終的にSwingがpaint()を呼び出すコンポーネントで実行されますpaintComponent()

あなたの場合、あなたは定期的に発火するタイマーを持っています。paintComponent使用するをオーバーライドできますJPanel。座標の計算を行うロジックはすでにあります。これらの座標をメンバー変数に格納します。次に、を発行しrepaint()ます。でpaintComponent、計算された座標に基づいて画像を描画します。

編集:

スレッドに関する別の注意。Swingにはシングルスレッドのペイントモデルがあります。すべてのUIインタラクションとペイントは、Swingのイベントディスパッチスレッド(EDT)で実行されます。EDTの詳細については、Swingの同時実行性を参照してください。animate()メソッドはEDTでは実行されないことに注意してください。あなたは何をするかを示しませんでしたimg.Move(dx, dy)が、このように実行することはおそらく安全ではありません。invokeLaterは、コードがEDTで実行されるようにするためにここで役立つ場合があります。ただし、この特定のケースでは、アクションがEDTで実行されることを保証するSwingタイマーを使用する方が簡単な場合があります。

于 2013-03-26T23:16:21.987 に答える