2012-10-29 23 views
0

我正在製作一個時鐘,目前我的秒針,分針和時針都以圖形方式使用Line對象以(x0, y0)開始座標和(x1, y1)結束座標進行繪製。如何製作時鐘?

現在令我困惑的是如何讓秒針每次一秒鐘都「打勾」。也就是說,我怎樣才能更新座標(因爲開始的座標總是在時鐘的中心,我們不需要更新它),所以它會順時針移動6度?這令我感到困惑,因爲單位圓的方向(因此弧度方向)逆時針旋轉。

+1

看看[這個答案](http://stackoverflow.com/問題/ 12964983/rotate-image-around-character-java/12971987#12971987),基本都是一樣的。你是正確的,方向逆時針移動,所以你需要反轉你的角度(減去代替添加) – MadProgrammer

+0

'System.currentTimeMillis()/ 1000'返回第二個值,也許你可以跟蹤從開始到當前的'System.currentTimeMillis()/ 1000'。 – user1610406

回答

1

That example作品出奇地好......

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

我用你的方法來計算座標,但我似乎無法做到正確。我的第二手牌越來越長,而且兩手之間的增幅逐漸變小。 (double)Math.round(secondHand.xEnd + Math.cos(rads)* 1.15), (double)Math.round(secondHand.yEnd - Math.sin(rads) * 1.15), Color.RED);' – yiwei

+0

計算中的x/y是中心點。手的長度由突襲(1.15)定義。從我所知道的來看,計算看起來應該更像Math.round(2.5 + Math.cos(rads)* 1.15),這會給你終點x點 – MadProgrammer

2

有幾種方法。既然你可能知道的時鐘半徑,你可以做

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

你能澄清一點嗎?什麼是'theta - 6'部分? – yiwei

+1

@ 59鷹一圈360度。有60秒,所以每秒的刻度線是360/60 = 6度。 theta是當前角度,減去6度會給我們下一個刻度標記。 – ehuang

+0

好吧。我應該怎樣初始化theta? – yiwei