旋转变换不能正常重绘正在运行的线程工作时 [英] Rotation transform not working properly in repaint when running thread

查看:120
本文介绍了旋转变换不能正常重绘正在运行的线程工作时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力使本工作方案,尽管我似乎无法找到任何的问题。这一方案由以下2类,无多,不会少。它基本上应该借鉴在绘图区单击每一个点,并在3日点击所有的点都连接起来。我还是要对使它prettier和更准确的工作,但是这部分的工作。什么不工作是应该遵循:在第四点击线程应该开始(和它开始),和三角形本身应该旋转给定的任意刷新率,对于究竟80重绘。接下来点击不应该工作,直到动画结束,只有到那时,如果有动画停止后点击(线程死亡),将显示一个新的点,这一切重新开始。

难道所有的油漆呼叫堆叠,直到我的线程结束?我知道它可能发生的所有事件被堆叠在事件队列和为一体进行处理。使用重绘与时间参数于事无补。我已经添加了注释,以帮助澄清,因为所有的变量是法语单词(他们解释)。我有一个困难时期试图找出如果它在我的code,以发现问题,如果它是线程相关的,甚至类型有关。我只是无处可去在调试模式(使用的Eclipse )。我已经完全忽略了一些东西明显?

虽然我的方法可能不是这样做的最有效的方式,旋转是我的首要问题。我可以处理写code不成文的剩余部分。
感谢您的帮助!这里有两个类:

进口java.awt.EventQueue中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.border.EmptyBorder中;
进口javax.swing.JButton中;
进口java.awt.event.ActionListener;
进口java.awt.event.ActionEvent中;
进口java.awt.event.MouseAdapter;
进口java.awt.event.MouseEvent中;
公共类应用扩展的JFrame {私有静态最后的serialVersionUID长1L =;
私人的JPanel的contentPane;
私人的JButton btnTerminer;
私人三角三角;
私人INT totalClics = 0;/ **
 *启动应用程序。
 * /
公共静态无效的主要(字串[] args){
    EventQueue.invokeLater(新的Runnable(){
        公共无效的run(){
            尝试{
                应用程序框架=新的应用程序();
                frame.setVisible(真);
            }赶上(例外五){
                e.printStackTrace();
            }
        }
    });
}/ **
 *创建框架。
 * /
公共应用程序(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    的setBounds(100,100,453,692);
    的contentPane =新JPanel();
    contentPane.setBorder(新EmptyBorder(5,5,5,5));
    setContentPane(contentPane的);
    contentPane.setLayout(NULL);    btnTerminer =的新的JButton(Terminer);
    btnTerminer.addActionListener(新的ActionListener(){
        公共无效的actionPerformed(ActionEvent的为arg0){
            System.exit(0);
        }
    });
    btnTerminer.setBounds(138,622,132,23);
    contentPane.add(btnTerminer);    三角=新的三角形();
    //添加点,每点击一下鼠标
    triangle.addMouseListener(新MouseAdapter(){
        @覆盖
        公共无效的mouseClicked(的MouseEvent E){
            如果(totalClics 3;){
                triangle.ajouterPoint(e.getX(),e.​​getY());
                totalClics ++;
            }其他{
                。triangle.getAnim()开始();
                totalClics = 0;
            }
        }
    });
    triangle.setBounds(10,11,400,600);
    contentPane.add(三角形);
}
}


进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.RenderingHints中;
的Bean;
进口的java.util.ArrayList;
进口java.util.Iterator的;
进口javax.swing.JPanel中;
公共类三角继承JPanel实现Runnable,Serializable接口{私有静态最后的serialVersionUID长1L =;
私人的ArrayList<点和GT;点= NULL;
//动画线程
私人主题动画;
私人色彩couleurPrin;
私人色彩couleurBoite;
//一个点的直径
私人INT不倒= 8;
//矩形的宽度
私人诠释largeur;
//矩形的高度
私人诠释傲慢;
//矩形的左上角
私人诠释其minX;
私人诠释MINY;
//角度增量倍增
私人INT nbAng = 0;
//螺纹停止变
私人布尔continuer = TRUE;
公共三角(){
    集preferredSize(新尺寸(400,600));
    的setBackground(Color.BLACK);
    couleurPrin = Color.GREEN;
    couleurBoite = Color.RED;
    setAnim(新线(本));
    点=新的ArrayList<点和GT;();
}
/ **
 *重绘此组件
 * /
@覆盖
公共无效的paintComponent(图形G){
    super.paintComponent方法(G);
    Graphics2D的G2D =(Graphics2D的)克;
    INT I = 0;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    INT [] coorX =新INT [points.size()+ 1];
    INT [] coorY =新INT [points.size()+ 1];
    迭代器<点和GT; ITER = points.iterator();
    而(iter.hasNext()){
        点P = iter.next();
        coorX [I] = p.getX();
        coorY [I] = p.getY();
        我++;
    }
    coorX [points.size()] = coorX [0];
    coorY [points.size()] = coorY [0];
    如果(points.size()!= 0){
        g2d.setColor(Color.white);
        g2d.fillOval(其minX + largeur / 2,MINY +傲慢/ 2,6,6);
        g2d.setColor(couleurPrin);
        对于(i = 0; I< points.size();我++){
            g2d.drawLine(coorX [I],coorY [I],coorX第[i + 1],coorY第[i + 1]);
        }
        对于(i = 0; I< points.size();我++){
            g2d.fillOval(coorX [I] -diametre / 2,coorY [I] -diametre / 2,不倒,不倒);
        }
        g2d.setColor(couleurBoite);
        g2d.drawRect(疯丫头,MINY,largeur,傲慢);
        g2d.rotate(15.0 * nbAng,(largeur +的getWidth())/ 2,(傲慢+的getWidth())/ 2);
    }}
/ **
 *再添一分。停在3。
 * @参数点¯x
 * @参数ÿ
 *
 *
 * /
公共无效ajouterPoint(INT X,int y)对{
    点p =新点(X,Y);
    的System.out.println(p.toString());
    如果(points.size()> = 0&放大器;&放大器; points.size()3;){
        points.add(P);
        其minX = p.getX() - 3;
        MINY = p.getY() - 3;
    }
    如果(points.size()== 3){
        rectanguler(点);
    }
    重绘();}众彩getCouleurPrin(){
    返回couleurPrin;
}
公共无效setCouleurPrin(颜色C){
    this.couleurPrin = C;
    重绘();
}
公众诠释getDiametre(){
    返回不倒;
}
公共无效setDiametre(INT D){
    this.diametre = D;
    重绘();
}
/ **
 *设置矩形的价值观,以最大可能的范围
 * @参数点
 * /
私人无效rectanguler(ArrayList的<点和GT;点){
    迭代器<点和GT; ITER = points.iterator();
    点P1,P2,P3;
    P1 = iter.next();
    P2 = iter.next();
    P3 = iter.next();
    INT dLarg;
    INT dLong;
    如果(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());
        傲慢= Math.abs(p1.getY() - p2.getY());
        如果(P3!= NULL){
            其minX = Math.min(疯丫头,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);
            豪特= Math.max(dLong,傲慢);
        }
    }
}
/ **
 *自定义点类
 *存储一个x和y值
 *
 * /
私有类点{
    @覆盖
    公共字符串的toString(){
        回归点[X =+ X +,Y =+ Y +];
    }
    私人诠释的x,y;
    公共点(){
        setX的(0);
        SETY(0);
    }
    公共点(INT X,int y)对{
        setX的(X);
        塞蒂(Y);
    }
    公众诠释的getX(){
        返回X;
    }
    公共无效setX的(INT X){
        this.x = X;
    }
    公众诠释的getY(){
        返回是;
    }
    公共无效塞蒂(int y)对{
        this.y = Y;
    }}
/ **
 *启动旋转
 *
 * /
@覆盖
公共无效的run(){
    INT I = 1;
    而(continuer){        nbAng = I;
        重绘();
        尝试{
            视频下载(200);
        }赶上(InterruptedException的E){
            的System.out.println(ERREUR丹斯乐线);
            e.printStackTrace();
        }
        我++;
        如果(我== 80){
            continuer = FALSE;
        }
    }
    动画=新主题(本);}
公共主题getAnim(){
    返回动画;
}
公共无效setAnim(螺纹阿尼姆){
    this.anim =动画;
    重绘();
}}


解决方案

A 是矫枉过正你想要达到的目标。 A javax.swing.Timer中的更简单,更容易使用,它也可重复使用,不像

的Graphics2D#旋转适用翻译所有后续的渲染,这意味着你需要在你画什么应用它。

您的鼠标点击的逻辑是有点过为好,它不会允许点击继续前检查线程的状态。

我修改codea的小为例(对不起,我移动鼠标点击操作的三角类,但是你应该能够将其删除; ))

 公共类TestRotation01 {    公共静态无效的主要(字串[] args){
        新TestRotation01();
    }    公共TestRotation01(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                JFrame的帧=新的JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的BorderLayout());
                frame.add(新三角());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类三角继承JPanel {        私有静态最后的serialVersionUID长1L =;
        私人的ArrayList<点和GT;点= NULL;
//动画线程
//私人主题动画;
        私人色彩couleurPrin;
        私人色彩couleurBoite;
//一个点的直径
        私人INT不倒= 8;
//矩形的宽度
        私人诠释largeur;
//矩形的高度
        私人诠释傲慢;
//矩形的左上角
        私人诠释其minX;
        私人诠释MINY;
//角度增量倍增
        私人INT nbAng = 0;
//螺纹停止变
        私人布尔continuer = TRUE;
        私人INT totalClics = 0;
        私人定时器定时器;
        私人诠释循环;        公共三角(){
            集preferredSize(新尺寸(400,600));
            的setBackground(Color.BLACK);
            couleurPrin = Color.GREEN;
            couleurBoite = Color.RED;
            点=新的ArrayList<点和GT;();
            addMouseListener将(新MouseAdapter(){
                @覆盖
                公共无效的mouseClicked(的MouseEvent E){
                    如果(!timer.isRunning()){
                        如果(totalClics 3;){
                            nbAng = 0;
                            ajouterPoint(e.getX(),e.​​getY());
                            totalClics ++;
                        }其他{
                            周期= 0;
                            totalClics = 0;
                            timer.restart();
                        }
                    }
                }
            });            定时器=新定时器(200,新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    nbAng + = 5;
                    重绘();
                    循环++;
                    如果(循环== 80){
                        timer.stop();
                    }
                }
            });
            timer.setRepeats(真);
            timer.setCoalesce(真);
        }        / **
         *重绘此组件
         * /
        @覆盖
        公共无效的paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();            如果(timer.isRunning()){                g2d.rotate(15.0 * nbAng,(largeur +的getWidth())/ 2,(傲慢+的getWidth())/ 2);            }            INT I = 0;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            INT [] coorX =新INT [points.size()+ 1];
            INT [] coorY =新INT [points.size()+ 1];
            迭代器<点和GT; ITER = points.iterator();
            而(iter.hasNext()){
                点P = iter.next();
                coorX [I] = p.getX();
                coorY [I] = p.getY();
                我++;
            }
            coorX [points.size()] = coorX [0];
            coorY [points.size()] = coorY [0];
            如果(points.size()!= 0){
                g2d.setColor(Color.white);
                g2d.fillOval(其minX + largeur / 2,MINY +傲慢/ 2,6,6);
                g2d.setColor(couleurPrin);
                对于(i = 0; I< points.size();我++){
                    g2d.drawLine(coorX [I],coorY [I],coorX第[i + 1],coorY第[i + 1]);
                }
                对于(i = 0; I< points.size();我++){
                    g2d.fillOval(coorX [I] - 不倒/ 2,coorY [I] - 不倒/ 2,不倒,不倒);
                }
                g2d.setColor(couleurBoite);
                g2d.drawRect(疯丫头,MINY,largeur,傲慢);
            }            g2d.dispose();        }        / **
         *再添一分。停在3。
         *
         * @参数点¯x
         * @参数ÿ
         *
         *
         * /
        公共无效ajouterPoint(INT X,int y)对{
            点p =新点(X,Y);
            的System.out.println(p.toString());
            如果(points.size()> = 0&放大器;&放大器; points.size()3;){
                points.add(P);
                其minX = p.getX() - 3;
                MINY = p.getY() - 3;
            }
            如果(points.size()== 3){
                rectanguler(点);
            }
            重绘();        }        众彩getCouleurPrin(){
            返回couleurPrin;
        }        公共无效setCouleurPrin(颜色C){
            this.couleurPrin = C;
            重绘();
        }        公众诠释getDiametre(){
            返回不倒;
        }        公共无效setDiametre(INT D){
            this.diametre = D;
            重绘();
        }        / **
         *设置矩形的价值观,以最大可能的范围
         *
         * @参数点
         * /
        私人无效rectanguler(ArrayList的<点和GT;点){
            迭代器<点和GT; ITER = points.iterator();
            点P1,P2,P3;
            P1 = iter.next();
            P2 = iter.next();
            P3 = iter.next();
            INT dLarg;
            INT dLong;
            如果(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());
                傲慢= Math.abs(p1.getY() - p2.getY());
                如果(P3!= NULL){
                    其minX = Math.min(疯丫头,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);
                    豪特= Math.max(dLong,傲慢);
                }
            }
        }        / **
         *自定义点类存储的X和Y值
         *
         * /
        私有类点{            @覆盖
            公共字符串的toString(){
                回归点[X =+ X +,Y =+ Y +];
            }
            私人诠释的x,y;            公共点(){
                setX的(0);
                SETY(0);
            }            公共点(INT X,int y)对{
                setX的(X);
                塞蒂(Y);
            }            公众诠释的getX(){
                返回X;
            }            公共无效setX的(INT X){
                this.x = X;
            }            公众诠释的getY(){
                返回是;
            }            公共无效塞蒂(int y)对{
                this.y = Y;
            }
        }
    }
}

I have been working on trying to make this program work, even though I can't seem to find whatever is the problem. This program is made of the following 2 classes, no more, no less. It is basically supposed to draw a point on each click in the drawing zone, and on the 3rd click all points are connected. I still have to work on making it prettier and more accurate, but this part works. What doesn't work is what should follow : on the fourth click a thread should start (and it starts), and the triangle itself should rotate given an arbitrary refresh rate, for exactly 80 repaints. The next click should not work until the animating is finished and only then if there is a click after the animation stops(the thread dies), a new point is displayed and it starts all over again.

Is it possible that all paint calls are stacked until the end of my thread? I know it can happen that all events are stacked in the event queue and treated as one. Using a repaint with a time parameter doesn't help. I have added comments to help clarify, because all variables are french words (they're explained). I have a hard time trying to figure out if it's in my code to find the problem, if it's thread-related or even type-related. I'm just going nowhere in debug mode (using Eclipse). Have I completely ignored something obvious?

While my methods might not be the most efficient way to do this, the rotation is my primary problem. I can handle writing the unwritten remaining part of the code. Thanks for any help! Here are the two classes :

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

}

解决方案

A Thread is overkill for what you want to achieve. A javax.swing.Timer is simpler and easier to use, it is also re-usable, unlike a Thread.

Graphics2D#rotate applies a translation to all subsequent rendering, meaning you need to apply it BEFORE you paint anything.

Your mouse click logic is a little off as well, it doesn't check the state of the thread before allowing the clicks to continue.

I modified your code a little as an example (sorry, I moved the mouse click handling to the Triangle class, but you should be able to remove it ;))

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

这篇关于旋转变换不能正常重绘正在运行的线程工作时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆