2

Solved: Thanks @MadProgrammer

I replaced g2.rotate(Math.toRadians(180.0)); by g2.scale(1, -1); thanks^^


I wrote program to show Digital Clock with mirror (Vertical Flip)

This is my code

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

Problem: I used rotate() method, but actually I don't want rotate the clock I want flip it vertically Question: How can I flip the shape (not image)?

4

1 に答える 1

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

        }

    }

}
于 2012-12-03T02:50:31.290 に答える