翻转形状(不是图像)

时间:2012-12-03 02:27:24

标签: java swing awt shape graphics2d

解决: 谢谢@MadProgrammer

我将g2.rotate(Math.toRadians(180.0));替换为g2.scale(1, -1);,感谢^^


我编写的程序用镜子显示数字时钟(垂直翻转)

这是我的代码

    import java.awt.*;
    import java.awt.font.GlyphVector;
    import javax.swing.*;
    import java.util.*;

    public class DigitalClock extends JFrame implements Runnable {
        /**
         * @author HASSAN
         */
        Thread runner; // declare global objects
        Font clockFont;
        Shape mirror;

        public DigitalClock() {
            super("Digital Clock - Hassan Sharaf 12MCMB33");
            setSize(600, 500);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setVisible(true);
            setResizable(false); // create window
            setLocationRelativeTo(null);
            clockFont = new Font("digifacewide", Font.BOLD, 100); // create font

            Container contentArea = getContentPane();
            ClockPanel timeDisplay = new ClockPanel();
            contentArea.add(timeDisplay); // add components
            setContentPane(contentArea);
            start(); // start thread running
        }

        public class ClockPanel extends JPanel {

            public void paintComponent(Graphics painter) {
                // super.paintComponent(painter);
                Graphics2D g2 = (Graphics2D) painter;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setFont(clockFont); // create clock components
                g2.setColor(Color.black);
                g2.drawString(timeNow(), 20, 140);
                GlyphVector v = clockFont.createGlyphVector(getFontMetrics(clockFont).getFontRenderContext(), timeNow());
                mirror = v.getOutline();
                g2.translate(553, 160);
                g2.rotate(Math.toRadians(180.0));   
                g2.fill(mirror);
                        g2.draw(mirror);

            }
        }

        // get current time
        public String timeNow() {
            Calendar now = Calendar.getInstance();
            int hrs = now.get(Calendar.HOUR_OF_DAY);
            int min = now.get(Calendar.MINUTE);
            int sec = now.get(Calendar.SECOND);
            String time = zero(hrs) + ":" + zero(min) + ":" + zero(sec);
            return time;
        }

        public String zero(int num) {
            String number = (num < 10) ? ("0" + num) : ("" + num);
            return number; // Add leading zero if needed
        }

        public void start() {
            if (runner == null) {
                runner = new Thread(this);
            }
            runner.start();
            // method to start thread
        }

        public void run() {
            while (runner == Thread.currentThread()) {
                repaint();
                // define thread task
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("Thread failed");
                }
            }
        }

        // create main method
        public static void main(String[] args) {
            DigitalClock clock = new DigitalClock();
        }
    }

问题:我使用了rotate()方法,但实际上我不想旋转时钟我想垂直翻转它 问题:如何翻转形状(不是图片)

1 个答案:

答案 0 :(得分:3)

根据你想要达到的目标,你有很多选择......

你可以......

  • 使用符合您的旋转要求的PathIterator从形状对象创建AffineTransform。这将要求您创建一个新路径,将PathIterator附加到它,以便您可以绘制它...或
  • 使用要旋转的形状作为新路径的基础并将Path2D传递给它,创建一个新的AffineTransform。这与第一个选项几乎相同,但需要的代码更少......

这是一个例子......

public class SpinningTriangle {

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

    public SpinningTriangle() {
        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 SpinPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SpinPane extends JPanel {

        private Triangle triangle;
        private float angle = 0;

        public SpinPane() {
            triangle = new Triangle(50, 100);
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle += 2;
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(110, 110);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Rectangle bounds = triangle.getBounds();
//            PathIterator pi = triangle.getPathIterator(AffineTransform.getRotateInstance(Math.toRadians(angle), bounds.width / 2, bounds.height / 2));
//            Path2D path = new Path2D.Float();
//            path.append(pi, true);
            Path2D path = new Path2D.Float(triangle, AffineTransform.getRotateInstance(Math.toRadians(angle), bounds.width / 2, bounds.height / 2));
            int x = (getWidth() - bounds.width) / 2;
            int y = (getHeight() - bounds.height) / 2;
            g2d.translate(x, y);
            g2d.setColor(Color.RED);
            g2d.fill(path);
            g2d.setColor(Color.YELLOW);
            g2d.draw(path);
            g2d.dispose();
        }

    }

    public class Triangle extends Path2D.Float {

        public Triangle(int width, int height) {

            moveTo(width / 2f, 0);
            lineTo(width, height);
            lineTo(0, height);
            closePath();

        }

    }

}

<强>已更新

如果您只想“镜像”形状,则可以按-1缩放轴...

public class SpinningTriangle {

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

    public SpinningTriangle() {
        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 FlipPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class FlipPane extends JPanel {

        private Triangle triangle;
        private boolean flip;

        public FlipPane() {
            triangle = new Triangle(50, 100);
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    flip = !flip;
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(110, 110);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Rectangle bounds = triangle.getBounds();

            double scale = 1 * (flip ? -1 : 1);

            Path2D path = new Path2D.Float(triangle, AffineTransform.getScaleInstance(scale, scale));
            int x = (getWidth() - bounds.width) / 2;
            int y = (getHeight() - bounds.height) / 2;
            if (flip) {

                y += bounds.height;
                x += bounds.width;

            }
            g2d.translate(x, y);
            g2d.setColor(Color.RED);
            g2d.fill(path);
            g2d.setColor(Color.YELLOW);
            g2d.draw(path);
            g2d.dispose();
        }

    }

    public class Triangle extends Path2D.Float {

        public Triangle(int width, int height) {

            moveTo(width / 2f, 0);
            lineTo(width, height);
            lineTo(0, height);
            closePath();

        }

    }

}