间隔后重新绘制Swing JComponent

Tom*_*Tom 3 java swing timer repaint graphics2d

我被分配了一个项目,我必须使用java中的GregorianCalendar对象制作模拟时钟.首先,我们被告知让时钟工作,以便在每次运行时显示正确的时间.然后我们被告知要在每秒运行时重绘时钟.我做了一个计时器对象,并认为我可以添加一个ActionListener并在每次调用actionPerformed时重新绘制它,但显然不能以这种方式使用重绘.这是我的代码:

    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.*;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.Date;
    import javax.swing.Timer;
    import java.lang.Math;    

    public class SwingClock {

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                MyFrame frame = new MyFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                ActionListener listener = new TimePrinter();
                Timer t = new Timer(1000, listener);
                GregorianCalendar calendar = new GregorianCalendar();
                t.start();
                frame.setVisible(true);
            }
        });
    }
}

    class TimePrinter implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            //I'd like to repaint here every second, but I can't
        }
    }

    class MyFrame extends JFrame
    {
        public MyFrame()
        {
            setTitle("Swing Clock");
            setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

            MyComponent component = new MyComponent();
            add(component);
        }

        public static final int DEFAULT_WIDTH = 500;
        public static final int DEFAULT_HEIGHT = 500;
    }

    class MyComponent extends JComponent
    {
        public void paint(Graphics g)
        {
            Graphics2D g2 = (Graphics2D)g;
            int leftX = 50, topY = 50, width = 300, height = 300;
            Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);

            Ellipse2D clockFace = new Ellipse2D.Double();
            clockFace.setFrame(rect);
            g2.draw(clockFace);

            double centerX = clockFace.getCenterX();
            double centerY = clockFace.getCenterY();
            GregorianCalendar calendar = new GregorianCalendar();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);

            int minute = calendar.get(Calendar.MINUTE);
            int second = calendar.get(Calendar.SECOND);

            double minusMinute = (90 - (minute*6))*(Math.PI/180);           
            double minuteCosine = Math.cos(minusMinute);
            double minuteSine = Math.sin(minusMinute);

            double minusSecond = (90 - (second*6))*(Math.PI/180);
            double secondCosine = Math.cos(minusSecond);
            double secondSine = Math.sin(minusSecond);

            double hourTheta = (90-(hour+(minute/60)*30))*(Math.PI/180);
            g2.draw(new Line2D.Double(centerX,centerY,centerX+50*(Math.cos(hourTheta)),
                    centerY - 50*(Math.sin(hourTheta))));   
            g2.draw(new Line2D.Double(centerX,centerY,centerX+150*(minuteCosine),centerY-150*(minuteSine)));
        g2.draw(new Line2D.Double(centerX, centerY, centerX+100*secondCosine, 
                    centerY-100*(secondSine)));
        }
    }
Run Code Online (Sandbox Code Playgroud)

关于如何解决这个问题的任何想法?也许我错了?

mrk*_*rts 5

"Swing程序应该覆盖paintComponent()而不是覆盖paint(),"尽管你会看到,这根本不是必需的.其次,你正确使用javax.swing.Timer.第三,为什么不让自己轻松自如并使用JLabel实例显示时间呢?

  • 嗯,难道你没有倒退kemosabe - 他应该**覆盖paintComponent,而不是绘画(如果他需要做自定义绘画)? (2认同)