如果我将Polygon绘制到某个JPanel容器上并将旋转放在计时器上,它可以正常工作。但是,如果我将多边形绘制到JPanel上,然后尝试旋转多边形,则它不会旋转。 Polygon坐标正在变化,JPanel(似乎)正在重新绘制,但它只是不会旋转。这是我的意思的一些示例代码。我知道我还需要解决一些问题,但我只关心让JPanel上的Polygon旋转。
package PolygonRotateTest;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class PolygonRotateTest {
static ConvexPolygon polygon;
static Timer t;
static Model m1;
static JPanel container;
static JFrame frame;
public static void main(String[] args) {
//Small compiler issue with "no enclosing instance of type PolygonRotateTest is in scope"
//because I lazily copy-pasted critical classes into one to make this more convenient.
//Should still run fine if you ignore the warning.
//ConvexPolygon makes a pentagon centered at (300,200) with a radius of 100
polygon = new ConvexPolygon(new Coordinate(300, 200), 100, 5);
//Model extends JPanel, accepts a polygon.
m1 = new BallModel(polygon, Color.red);
//Draws the polygon on the container
container = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillPolygon(polygon);
}
};
t = new Timer(1000 / 60, new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
m1.rotate(Math.toRadians(1));
container.repaint();
m1.repaint();
//Rotates the polygon 60 times per second.
//Drawing the black polygon directly onto the container rotates correctly
//However, the model (m1) does not redraw/rotate the red polygon
//despite using the same polygon.
}
});
t.start();
container.setPreferredSize(new Dimension(800, 600));
frame = new JFrame();
frame.add(container);
container.add(m1);
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
///Other stuff begins here///////////////
public static abstract class ActorPolygon extends Polygon {
private Coordinate center;
public ActorPolygon(Coordinate center) {
this.center = center;
}
public void rotate(double radianIncrement) {
for (int i = 0; i < npoints; i++) {
Coordinate rotate = rotatePoint(new Coordinate(xpoints[i], ypoints[i]), radianIncrement);
xpoints[i] = rotate.getX();
ypoints[i] = rotate.getY();
}
}
public Coordinate rotatePoint(Coordinate c, double radianIncrement) {
double xDist = c.getX() - getCenter().getX();
double yDist = c.getY() - getCenter().getY();
Coordinate rotated = new Coordinate(
(int) (0.5 + center.getX() + xDist * Math.cos(radianIncrement) - yDist * Math.sin(radianIncrement)),
(int) (0.5 + center.getY() + xDist * Math.sin(radianIncrement) + yDist * Math.cos(radianIncrement)));
return rotated;
}
@Override
public void translate(int dx, int dy) {
super.translate(dx, dy);
int x = center.getX() + dx;
int y = center.getY() + dy;
center = new Coordinate(x, y);
}
@Override
public String toString() {
String output = "";
output += "Center at " + center + "\n";
output += "contains " + npoints + " points" + "\n";
for (int i = 0; i < npoints; i++) {
output += i + " " + "(" + xpoints[i] + "," + ypoints[i] + ")" + "\n";
}
return output;
}
public Coordinate getCenter() {
return center;
}
@Override
public abstract ActorPolygon clone();
}
public static class ConvexPolygon extends ActorPolygon {
private int radius;
public ConvexPolygon(Coordinate center, int r, int n) {
super(center);
this.npoints = n;
this.radius = r;
xpoints = new int[npoints];
ypoints = new int[npoints];
double radianIncrement = 2 * Math.PI / npoints;
double shift = Math.PI / npoints - 3 * Math.PI / 2;
for (int i = 0; i < npoints; i++) {
xpoints[i] = getCenter().getX() + (int) (radius * Math.cos(i * radianIncrement + shift));
ypoints[i] = getCenter().getY() + (int) (radius * Math.sin(i * radianIncrement + shift));
}
}
public int getRadius() {
return radius;
}
@Override
public ConvexPolygon clone() {
return new ConvexPolygon(getCenter(), getRadius(), npoints);
}
}
public abstract class Model extends JPanel {
private ActorPolygon original;
public Model(ActorPolygon polygon) {
this.original = polygon;
this.setPreferredSize(original.getBounds().getSize());
Rectangle bounds = polygon.getBounds();
this.setBounds(bounds);
}
public ActorPolygon getActorPolygon() {
return original;
}
public void rotate(double increment) {
original.rotate(increment);
}
public void drawModel(Graphics g) {
Rectangle bounds = getActorPolygon().getBounds();
this.setBounds(bounds);
this.setPreferredSize(this.getBounds().getSize());
ActorPolygon shiftedPolygon = getActorPolygon().clone();
shiftedPolygon.translate(
-1 * getActorPolygon().getCenter().getX() + (int) bounds.getWidth() / 2,
-1 * getActorPolygon().getCenter().getY() + (int) bounds.getHeight() / 2);
g.fillPolygon(shiftedPolygon);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawModel(g);
}
@Override
public String toString() {
String output = original + this.getSize().toString() + "\n" + this.getLocation() + "\n";
return output;
}
}
public static class BallModel extends Model {
private Color color;
public BallModel(ConvexPolygon p, Color c) {
super(p);
color = c;
}
@Override
public void drawModel(Graphics g) {
g.setColor(color);
super.drawModel(g);
}
}
public static class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public String toString() {
return "(" + x + "," + y + ")";
}
}
}