可以旋转绘制在JPanel中的多边形,但不能旋转嵌套在此JPanel内的JPanel中的多边形

时间:2014-04-20 02:24:31

标签: java paintcomponent

如果我将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 + ")";
        }
    }
}

0 个答案:

没有答案