Java 我怎样才能使时钟滴答作响?

Java 我怎样才能使时钟滴答作响?,java,Java,我现在正在制作一个时钟,目前我的秒针、分针和时针都是用带有(x0,y0)起始坐标和(x1,y1)结束坐标的线对象以图形方式绘制的 现在让我困惑的是如何让秒针在每过一秒时都“滴答”一声。也就是说,我如何更新(x1,y1)坐标(因为起始坐标始终位于时钟的中心,我们不需要更新它),使其顺时针移动6度?这让我很困惑,因为单位圆的方向(因此弧度的方向)是逆时针的 有几种方法。因为你可能知道时钟的半径,所以你可以 theta = (theta - 6)%360; x1 = radius*cos(theta

我现在正在制作一个时钟,目前我的秒针、分针和时针都是用带有
(x0,y0)
起始坐标和
(x1,y1)
结束坐标的
线
对象以图形方式绘制的


现在让我困惑的是如何让秒针在每过一秒时都“滴答”一声。也就是说,我如何更新
(x1,y1)
坐标(因为起始坐标始终位于时钟的中心,我们不需要更新它),使其顺时针移动6度?这让我很困惑,因为单位圆的方向(因此弧度的方向)是逆时针的

有几种方法。因为你可能知道时钟的半径,所以你可以

theta = (theta - 6)%360;
x1 = radius*cos(theta * PI/180);
y1 = radius*sin(theta * PI/180);

有几种方法。因为你可能知道时钟的半径,所以你可以

theta = (theta - 6)%360;
x1 = radius*cos(theta * PI/180);
y1 = radius*sin(theta * PI/180);
效果出奇的好

public class TestClock {

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

    public TestClock() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ClockPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class ClockPane extends JPanel {

        public ClockPane() {
            Timer timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(false);
            timer.start();
        }

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

        protected Point getPointTo(float angle) {

            int x = Math.round(getWidth() / 2);
            int y = Math.round(getHeight() / 2);

            double rads = Math.toRadians(angle);
            // This is an arbitrary amount, you will need to correct for this
            // I'm working of a width of 200 pixels, so that makes the radius
            // 100...
            int radius = 100;

            // Calculate the outter point of the line
            int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
            int yPosy = Math.round((float) (y - Math.sin(rads) * radius));

            return new Point(xPosy, yPosy);

        }

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

            g2d.setColor(Color.RED);

            Calendar cal = Calendar.getInstance();
            int seconds = cal.get(Calendar.SECOND);
            float angle = -(360f * (seconds / 60f));
            angle += 90; // Correct for 0 being out to the right instead of up

            Point p = getPointTo(angle);

            int x = getWidth() / 2;
            int y = getHeight() / 2;

            g2d.drawLine(x, y, p.x, p.y);

            FontMetrics fm = g2d.getFontMetrics();
            String text = Integer.toString(seconds);
            g2d.drawString(text, getWidth() - fm.stringWidth(text), getHeight() - fm.getHeight() + fm.getAscent());

            g2d.dispose();
        }
    }
}
效果出奇的好

public class TestClock {

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

    public TestClock() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ClockPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class ClockPane extends JPanel {

        public ClockPane() {
            Timer timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(false);
            timer.start();
        }

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

        protected Point getPointTo(float angle) {

            int x = Math.round(getWidth() / 2);
            int y = Math.round(getHeight() / 2);

            double rads = Math.toRadians(angle);
            // This is an arbitrary amount, you will need to correct for this
            // I'm working of a width of 200 pixels, so that makes the radius
            // 100...
            int radius = 100;

            // Calculate the outter point of the line
            int xPosy = Math.round((float) (x + Math.cos(rads) * radius));
            int yPosy = Math.round((float) (y - Math.sin(rads) * radius));

            return new Point(xPosy, yPosy);

        }

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

            g2d.setColor(Color.RED);

            Calendar cal = Calendar.getInstance();
            int seconds = cal.get(Calendar.SECOND);
            float angle = -(360f * (seconds / 60f));
            angle += 90; // Correct for 0 being out to the right instead of up

            Point p = getPointTo(angle);

            int x = getWidth() / 2;
            int y = getHeight() / 2;

            g2d.drawLine(x, y, p.x, p.y);

            FontMetrics fm = g2d.getFontMetrics();
            String text = Integer.toString(seconds);
            g2d.drawString(text, getWidth() - fm.stringWidth(text), getHeight() - fm.getHeight() + fm.getAscent());

            g2d.dispose();
        }
    }
}

看一看,基本都是一样的。您是正确的,方向是逆时针移动的,因此您需要反转角度(用减法代替加法)
System.currentTimeMillis()/1000
返回第二个值,也许您可以跟踪从开始到当前
System.currentTimeMillis()/1000
的差值。请看一下,基本原理是一样的。您是正确的,方向是逆时针移动的,因此您需要反转角度(用减法代替加法)
系统。currentTimeMillis()/1000
返回第二个值,也许您可以跟踪从开始到当前
系统的差值。currentTimeMillis()/1000
。您能稍微澄清一下吗?什么是θ-6部分?@59eagle 360度成圆圈。有60秒,因此每秒钟的刻度线间隔为360/60=6度。θ是当前角度,减去6度将得到下一个记号。@59eagleθ=90度对应于单位圆中的点(0,1),即12点钟。你能稍微澄清一下吗?什么是θ-6部分?@59eagle 360度成圆圈。有60秒,因此每秒钟的刻度线间隔为360/60=6度。θ是当前角度,减去6度将得到下一个记号。@59eagleθ=90度对应于单位圆中的点(0,1),即12点。我使用了你的坐标计算方法,但我似乎无法正确计算。我的秒针越来越长,移动之间的增量也越来越小<代码>二手。重画(2.5,2.5,(双精度)数学圆(secondHand.xEnd+Math.cos(rads)*1.15),(双精度)数学圆(secondHand.yEnd-Math.sin(rads)*1.15),颜色为红色)计算中的x/y为中心点。手的长度由袭击定义(1.15)。据我所知,计算应该更像数学。round(2.5+Math.cos(rads)*1.15),这将给出终点x点。我使用了你的坐标计算方法,但我似乎没有得到正确的结果。我的秒针越来越长,移动之间的增量也越来越小<代码>二手。重画(2.5,2.5,(双精度)数学圆(secondHand.xEnd+Math.cos(rads)*1.15),(双精度)数学圆(secondHand.yEnd-Math.sin(rads)*1.15),颜色为红色)计算中的x/y为中心点。手的长度由袭击定义(1.15)。据我所知,计算应该更像Math.round(2.5+Math.cos(rads)*1.15),这将给出终点x