標籤:
1 import java.awt.Color; 2 import java.awt.Font; 3 import java.awt.Graphics; 4 import java.util.Calendar; 5 import java.util.GregorianCalendar; 6 7 import javax.swing.JFrame; 8 import javax.swing.JPanel; 9 10 /** 11 * 12 * @author YYCat 13 * 14 */ 15 public class TestImitateClock extends JPanel{ 16 17 private static final long serialVersionUID = 1L; 18 19 public static final int DEFAULT_HEIGHT = 350; //面板的高度 20 public static final int DEFAULT_WIDTH = 300; //面板的寬度 21 public static final int DEFAULT_X = 100; //面板初始位置 22 public static final int DEFAULT_Y = 50; 23 public static final int PADDING_X = 30; 24 public static final int PADDING_Y = 60; 25 public static final int clockRadius = (DEFAULT_WIDTH-60)/2; //定義時鐘圓的半徑radius 26 int xCenter = PADDING_X + clockRadius; //時鐘圓的圓心座標 27 int yCenter = PADDING_Y + clockRadius; 28 29 /** 30 * 定義時間變數,便於計算對應的時、分、秒針對應的位置 31 */ 32 private int second, minute, hour; 33 34 public TestImitateClock(){ 35 initTime(); 36 } 37 38 39 40 public void paint(Graphics g){ 41 /** 42 * 畫時鐘輪廓 43 * 定義半徑clockRadius:120px; 44 */ 45 46 // int clockRadius = DEFAULT_WIDTH - 60; //半徑為 (300-600)/2 47 g.drawOval(PADDING_X, PADDING_Y, clockRadius*2, clockRadius*2); 48 49 paintClockNum(g); 50 51 paintClockHands(g); 52 53 54 } 55 56 /** 57 * 畫時鐘數字 58 * @param g 59 */ 60 public void paintClockNum(Graphics g){ 61 62 int strLength = xCenter - PADDING_X; 63 Font afterFont = new Font("宋體", Font.BOLD, 14); 64 Font beforeF = g.getFont(); 65 66 for(int i=0; i<12; i++){ 67 if(i%3==0){ //固定位置數字加粗顯示 68 g.setFont(afterFont); 69 } 70 g.drawString(i*1 + "", (int) (xCenter + strLength*Math.sin(2*Math.PI/12*i)), (int) (yCenter + strLength*Math.cos(Math.PI + 2*Math.PI/12*i))); 71 g.setFont(beforeF); 72 } 73 74 } 75 76 /** 77 * 畫時針、分針、秒針 78 */ 79 public void paintClockHands(Graphics g){ 80 81 /** 82 * 設定時分秒針的長度、顏色、寬度 83 */ 84 double secondLen = clockRadius * 0.85; 85 double minuteLen = clockRadius * 0.75; 86 double hourLen = clockRadius * 0.65; 87 88 Color colorBefore = g.getColor(); 89 90 91 //秒針 92 g.setColor(Color.RED); 93 g.drawLine(xCenter, yCenter, (int)(xCenter + secondLen*Math.sin(2*Math.PI/60*second)),(int)( yCenter + secondLen*Math.cos(Math.PI+2*Math.PI/60*second))); 94 95 //分針 96 g.setColor(Color.CYAN); 97 g.drawLine(xCenter, yCenter, (int)(xCenter + minuteLen*Math.sin(2*Math.PI/60*minute)),(int)( yCenter + minuteLen*Math.cos(Math.PI+2*Math.PI/60*minute))); 98 99 //時針100 g.setColor(Color.DARK_GRAY);101 g.drawLine(xCenter, yCenter, (int)(xCenter + hourLen*Math.sin(2*Math.PI/12*hour)),(int)( yCenter + hourLen*Math.cos(Math.PI+2*Math.PI/12*hour)));102 103 g.setColor(colorBefore);104 }105 /**106 * 擷取時間107 */108 public void initTime(){109 Calendar calendar = new GregorianCalendar();110 second = calendar.get(Calendar.SECOND);111 minute = calendar.get(Calendar.MINUTE);112 hour = calendar.get(Calendar.HOUR_OF_DAY); //24小時制113 114 }115 public static void main(String[] args){116 117 final JFrame frame = new JFrame();118 frame.setTitle("Clock");119 frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);120 frame.setLocation(DEFAULT_X, DEFAULT_Y);121 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);122 frame.setVisible(true);123 124 Thread thread = new Thread(){125 public void run(){126 while(true){127 TestImitateClock clock = new TestImitateClock();128 frame.add(clock);129 clock.setVisible(true);130 frame.validate(); //接下來會每隔一秒重繪一次時鐘——即(從frame中將clock組件刪除),因此調用validate方法,使容器重新布置其子組件131 try {132 Thread.sleep(1000);133 } catch (InterruptedException e) {134 // TODO Auto-generated catch block135 e.printStackTrace();136 }137 clock.setVisible(false);138 frame.remove(clock); //在父容器中將其刪除139 clock.invalidate(); //使容器失效140 }141 }142 };143 144 thread.start();145 }146 147 }
運行效果:
使用到frame.add(panel) //向容器中添加面板組件
frame.validate() //使容器再次布置其子組件,在修改此容器的子組件時使用
Thread thread = new Thread(){...} //線程的使用,這裡並沒有使用太高深的東西
Math.sin() //函數見API
java-swing類比實現時鐘效果