3

何が問題なのかわからないようですが、私はこのプログラムを機能させるために取り組んできました。このプログラムは、以下の2つのクラスで構成されています。基本的には、描画ゾーンでクリックするたびにポイントを描画することになっており、3回目のクリックですべてのポイントが接続されます。私はまだそれをより美しく、より正確にするために取り組む必要がありますが、この部分は機能します。動作しないのは、次のことです。4回目のクリックでスレッドが開始(および開始)し、三角形自体が任意のリフレッシュレートで回転し、正確に80回再描画されます。次のクリックは、アニメーションが終了するまで機能しないはずです。アニメーションが停止した後(スレッドが終了した後)にクリックが発生した場合にのみ、新しいポイントが表示され、最初からやり直します。

スレッドの最後まですべてのペイント呼び出しがスタックされる可能性はありますか?すべてのイベントがイベントキューにスタックされ、1つとして扱われる可能性があることを私は知っています。時間パラメータを指定して再描画を使用しても効果はありません。すべての変数はフランス語の単語であるため、明確にするためにコメントを追加しました(説明されています)。問題がスレッドに関連しているのか、タイプに関連しているのか、問題を見つけることがコードにあるのかどうかを判断するのに苦労しています。デバッグモードではどこにも行きません(Eclipseを使用)。明らかなことを完全に無視しましたか?

私の方法はこれを行うための最も効率的な方法ではないかもしれませんが、回転は私の主な問題です。コードの未書き込みの残りの部分の書き込みを処理できます。助けてくれてありがとう!これが2つのクラスです:

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;


public class Application extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JButton btnTerminer;
private Triangle triangle;
private int totalClics = 0;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Application frame = new Application();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Application() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 453, 692);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    btnTerminer = new JButton("Terminer");
    btnTerminer.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            System.exit(0);
        }
    });
    btnTerminer.setBounds(138, 622, 132, 23);
    contentPane.add(btnTerminer);

    triangle = new Triangle();
    //Adds points for every mouse click
    triangle.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if(totalClics < 3){
                triangle.ajouterPoint(e.getX(), e.getY());
                totalClics++;
            } else {
                triangle.getAnim().start();
                totalClics = 0;
            }
        }
    });
    triangle.setBounds(10, 11, 400, 600);
    contentPane.add(triangle);
}
}

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;


import javax.swing.JPanel;


public class Triangle extends JPanel implements Runnable,Serializable{

private static final long serialVersionUID = 1L;
private ArrayList<Point> points = null;
//Animation thread
private Thread anim;
private Color couleurPrin;
private Color couleurBoite;
//A point's diameter
private int diametre = 8;
//The rectangle's width
private int largeur;
//The rectangle's height
private int hauteur;
//The rectangle's top-left corner
private int minX;
private int minY;
//Angle incrementation multiplier
private int nbAng = 0 ;
//Thread stopping variable
private boolean continuer = true;


public Triangle() {
    setPreferredSize(new Dimension(400, 600));
    setBackground(Color.BLACK);
    couleurPrin = Color.GREEN;
    couleurBoite = Color.RED;
    setAnim(new Thread(this));
    points = new ArrayList<Point>();


}
/**
 * Repaints this component
 */
@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    int i = 0;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    int[] coorX = new int[points.size()+1];
    int[] coorY = new int[points.size()+1];
    Iterator<Point> iter = points.iterator();
    while(iter.hasNext()){
        Point p = iter.next();
        coorX[i] = p.getX();
        coorY[i]= p.getY();
        i++;
    }
    coorX[points.size()] = coorX[0];
    coorY[points.size()] = coorY[0];
    if(points.size() != 0){
        g2d.setColor(Color.white);
        g2d.fillOval(minX+largeur/2, minY+hauteur/2, 6, 6);
        g2d.setColor(couleurPrin);
        for(i =0; i<points.size(); i++){
            g2d.drawLine(coorX[i], coorY[i], coorX[i+1], coorY[i+1]);
        }
        for(i = 0; i<points.size(); i++){
            g2d.fillOval(coorX[i]-diametre/2, coorY[i]-diametre/2, diametre, diametre);
        }
        g2d.setColor(couleurBoite);
        g2d.drawRect(minX, minY, largeur, hauteur);
        g2d.rotate(15.0*nbAng, (largeur+getWidth())/2, (hauteur+getWidth())/2); 


    }

}
/**
 * Adds a point. Stops at 3.
 * @param x
 * @param y
 * 
 * 
 */
public void ajouterPoint(int x, int y){
    Point p = new Point(x,y);
    System.out.println(p.toString());
    if(points.size()>=0 && points.size()<3){
        points.add(p);
        minX = p.getX()-3;
        minY = p.getY()-3;
    }
    if(points.size() == 3){
        rectanguler(points);
    }
    repaint();

}

public Color getCouleurPrin() {
    return couleurPrin;
}
public void setCouleurPrin(Color c) {
    this.couleurPrin = c;
    repaint();
}
public int getDiametre() {
    return diametre;
}
public void setDiametre(int d) {
    this.diametre = d;
    repaint();
}
/**
 * Sets rectangle's values to the largest bounds possible
 * @param points
 */
private void rectanguler(ArrayList<Point> points){
    Iterator<Point> iter = points.iterator();
    Point p1, p2, p3;
    p1 = iter.next();
    p2 = iter.next();
    p3 = iter.next();
    int dLarg;
    int dLong;
    if(p2 != null && p3 != null){
        minX = Math.min(p1.getX(), p2.getX());
        minY = Math.min(p1.getY(), p2.getY());
        largeur = Math.abs(p1.getX()-p2.getX());
        hauteur = Math.abs(p1.getY()-p2.getY());
        if(p3 != null){
            minX = Math.min(minX, p3.getX());
            minY = Math.min(minY, p3.getY());
            dLarg = Math.max(Math.abs(p3.getX()-p2.getX()), Math.abs(p3.getX()-p1.getX()));
            dLong = Math.max(Math.abs(p3.getY()-p2.getY()), Math.abs(p3.getY()-p1.getY()));
            largeur = Math.max(dLarg, largeur);
            hauteur = Math.max(dLong, hauteur);
        }       
    }
}
/**
 * Custom point class
 * Stores an x and y value
 *
 */
private class Point{
    @Override
    public String toString() {
        return "Point [x=" + x + ", y=" + y + "]";
    }
    private int x,y;
    public Point(){
        setX(0);
        setY(0);
    }
    public Point(int x,int y){
        setX(x);
        setY(y);
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }

}
/**
 * Starts the rotation
 * 
 */
@Override
public void run() {
    int i =1;
    while(continuer){

        nbAng = i;
        repaint();
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            System.out.println("Erreur dans le thread");
            e.printStackTrace();
        }
        i++;
        if(i== 80){
            continuer = false;
        }
    }
    anim = new Thread(this);

}
public Thread getAnim() {
    return anim;
}
public void setAnim(Thread anim) {
    this.anim = anim;
    repaint();
}

}
4

2 に答える 2

3

start()最初の問題は、アニメーション スレッドを呼び出すことがないことです。

2 つ目の問題は、EDT 以外で GUIを使用してはならないことです。@AndrewThompson のコメントで言及されているように、スレッドの代わりにスイングタイマーを使用する必要があります。

于 2012-12-20T02:52:50.773 に答える
3

AThreadはあなたが達成したいことに対してやり過ぎです。はシンプルjavax.swing.Timerで使いやすく、 とは異なり、再利用も可能Threadです。

Graphics2D#rotateは、後続のすべてのレンダリングに変換を適用します。つまり、何かをペイントする前に適用する必要があります。

マウス クリックのロジックも少しずれています。クリックを続行できるようにする前に、スレッドの状態をチェックしません。

例として、コードを少し変更しました (申し訳ありませんが、マウス クリック処理をTriangleクラスに移動しましたが、削除できるはずです ;))

public class TestRotation01 {

    public static void main(String[] args) {
        new TestRotation01();
    }

    public TestRotation01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new Triangle());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Triangle extends JPanel {

        private static final long serialVersionUID = 1L;
        private ArrayList<Point> points = null;
//Animation thread
//        private Thread anim;
        private Color couleurPrin;
        private Color couleurBoite;
//A point's diameter
        private int diametre = 8;
//The rectangle's width
        private int largeur;
//The rectangle's height
        private int hauteur;
//The rectangle's top-left corner
        private int minX;
        private int minY;
//Angle incrementation multiplier
        private int nbAng = 0;
//Thread stopping variable
        private boolean continuer = true;
        private int totalClics = 0;
        private Timer timer;
        private int cycle;

        public Triangle() {
            setPreferredSize(new Dimension(400, 600));
            setBackground(Color.BLACK);
            couleurPrin = Color.GREEN;
            couleurBoite = Color.RED;
            points = new ArrayList<Point>();
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (!timer.isRunning()) {
                        if (totalClics < 3) {
                            nbAng = 0;
                            ajouterPoint(e.getX(), e.getY());
                            totalClics++;
                        } else {
                            cycle = 0;
                            totalClics = 0;
                            timer.restart();
                        }
                    }
                }
            });

            timer = new Timer(200, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    nbAng += 5;
                    repaint();
                    cycle++;
                    if (cycle == 80) {
                        timer.stop();
                    }
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
        }

        /**
         * Repaints this component
         */
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            if (timer.isRunning()) {

                g2d.rotate(15.0 * nbAng, (largeur + getWidth()) / 2, (hauteur + getWidth()) / 2);

            }

            int i = 0;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            int[] coorX = new int[points.size() + 1];
            int[] coorY = new int[points.size() + 1];
            Iterator<Point> iter = points.iterator();
            while (iter.hasNext()) {
                Point p = iter.next();
                coorX[i] = p.getX();
                coorY[i] = p.getY();
                i++;
            }
            coorX[points.size()] = coorX[0];
            coorY[points.size()] = coorY[0];
            if (points.size() != 0) {
                g2d.setColor(Color.white);
                g2d.fillOval(minX + largeur / 2, minY + hauteur / 2, 6, 6);
                g2d.setColor(couleurPrin);
                for (i = 0; i < points.size(); i++) {
                    g2d.drawLine(coorX[i], coorY[i], coorX[i + 1], coorY[i + 1]);
                }
                for (i = 0; i < points.size(); i++) {
                    g2d.fillOval(coorX[i] - diametre / 2, coorY[i] - diametre / 2, diametre, diametre);
                }
                g2d.setColor(couleurBoite);
                g2d.drawRect(minX, minY, largeur, hauteur);
            }

            g2d.dispose();

        }

        /**
         * Adds a point. Stops at 3.
         *
         * @param x
         * @param y
         *
         *
         */
        public void ajouterPoint(int x, int y) {
            Point p = new Point(x, y);
            System.out.println(p.toString());
            if (points.size() >= 0 && points.size() < 3) {
                points.add(p);
                minX = p.getX() - 3;
                minY = p.getY() - 3;
            }
            if (points.size() == 3) {
                rectanguler(points);
            }
            repaint();

        }

        public Color getCouleurPrin() {
            return couleurPrin;
        }

        public void setCouleurPrin(Color c) {
            this.couleurPrin = c;
            repaint();
        }

        public int getDiametre() {
            return diametre;
        }

        public void setDiametre(int d) {
            this.diametre = d;
            repaint();
        }

        /**
         * Sets rectangle's values to the largest bounds possible
         *
         * @param points
         */
        private void rectanguler(ArrayList<Point> points) {
            Iterator<Point> iter = points.iterator();
            Point p1, p2, p3;
            p1 = iter.next();
            p2 = iter.next();
            p3 = iter.next();
            int dLarg;
            int dLong;
            if (p2 != null && p3 != null) {
                minX = Math.min(p1.getX(), p2.getX());
                minY = Math.min(p1.getY(), p2.getY());
                largeur = Math.abs(p1.getX() - p2.getX());
                hauteur = Math.abs(p1.getY() - p2.getY());
                if (p3 != null) {
                    minX = Math.min(minX, p3.getX());
                    minY = Math.min(minY, p3.getY());
                    dLarg = Math.max(Math.abs(p3.getX() - p2.getX()), Math.abs(p3.getX() - p1.getX()));
                    dLong = Math.max(Math.abs(p3.getY() - p2.getY()), Math.abs(p3.getY() - p1.getY()));
                    largeur = Math.max(dLarg, largeur);
                    hauteur = Math.max(dLong, hauteur);
                }
            }
        }

        /**
         * Custom point class Stores an x and y value
         *
         */
        private class Point {

            @Override
            public String toString() {
                return "Point [x=" + x + ", y=" + y + "]";
            }
            private int x, y;

            public Point() {
                setX(0);
                setY(0);
            }

            public Point(int x, int y) {
                setX(x);
                setY(y);
            }

            public int getX() {
                return x;
            }

            public void setX(int x) {
                this.x = x;
            }

            public int getY() {
                return y;
            }

            public void setY(int y) {
                this.y = y;
            }
        }
    }
}
于 2012-12-20T03:29:41.370 に答える