아날로그 시계

By Vaibhav Choudhary, 2008년 10월 10일

JavaFX로 당신 자신만의 최적화된 아날로그 시계를 쉽게 개발할 수 있다.

코드 이해하기

그림 1은 아날로그 시계를 만든 소스코드이다. 대부분은 public 속성으로 되어있고, 약간의 세팅을 바꾸면 당신이 원하는 대로 시계 외관을 변경할 수 있도록 되어있다.

소스 코드
package analogclock;

import javafx.stage.*;
import javafx.scene.*;
import javafx.geometry.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.transform.*;
import javafx.animation.*;
import javafx.scene.image.*;
import javafx.scene.shape.*;

// Java Legacy
import java.util.*;
import java.lang.Math;
import java.lang.System;

var months:String[] = ["JAN", "FEB", "MA80R", "APR", "MAY", "JUN",
				"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];

public class AnalogClock extends CustomNode {

    var radius: Number = 80;    // Decides the main size of the clock.
    var centerX: Number = 115 ; // shifting the X center
    var centerY: Number = 144 ; // shifting the Y center
    var hours:Number;
    var minutes:Number;
    var seconds:Number;
    var date:String;
    var month:String;
    var year:String;
    var combination: String;

    // intializing the watch
    init {
        var timeline = Timeline {
            repeatCount: Timeline.INDEFINITE
            keyFrames : [
                KeyFrame {
                    time : 1s
                    action: function() {
                        actionOnTick();
                        }
                }
            ]
        }
        timeline.play();
    }
    function createCalendar() {
        def calendar = Calendar.getInstance();
        calendar.setTime(new Date()); // fix for mobile
        calendar
    }
    // action taken on one tick
    public function actionOnTick () {
        var calendar = createCalendar();
        seconds = calendar.get(Calendar.SECOND);
        minutes = calendar.get(Calendar.MINUTE);
        hours = calendar.get(Calendar.HOUR);
        date = String.valueOf(calendar.get(Calendar.DATE));
        if(date.length()!=2)  {
            date = "0{date}";
        }
        month = months[(calendar.get(Calendar.MONTH))];
        year = String.valueOf((calendar.get(Calendar.YEAR))); // 1900 offset
        combination = "{date}-{month}-{year}";
    }

    // overriding the method create()
    public override function create(): Node {
        return Group {
            transforms: [
                Transform.translate(centerX, centerY)
            ]
            content: [
                Circle {
                    radius: radius + 20
                    fill: RadialGradient {
                        centerX: 0
                        centerY: 0
                        radius: radius + 20
                        proportional: false
                        stops: [

                            Stop { offset: 0.9 color: Color.SILVER },
                            Stop { offset: 1.0 color: Color.BLACK }
                        ]
                    }

                },
                Circle {
                    radius: radius + 10
                    stroke: Color.BLACK
                    fill: RadialGradient {
                        centerX: 0
                        centerY: 0
                        radius: 90
                        proportional: false
                        stops: [
                            Stop { offset: 0.0 color: Color.WHITE },
                            Stop { offset: 1.0 color: Color.CADETBLUE }

                        ]
                    }

                },
                Rectangle {
                    x: -35, y: 2*radius/3 - 15
                    width: 71 height: 20
                    fill: Color.GRAY
                    opacity:0.4
                    strokeWidth: 2
                    stroke: Color.BLACK
                    arcHeight:10
                    arcWidth:10
                },
                Text {
                    font: Font {
                        size: 11
				name: "Arial"
                    }
                    x: -31 , y: 2 * radius / 3
                    content: bind combination
                },
                //setting the main digits 3,6,9,12
                for (i in [3, 6, 9, 12])
                Text {
                    transforms:bind [
                        Transform.translate(-5, 5)
                    ]
                    x: radius * (( i + 0 ) mod 2 * ( 2 - i / 3))
                    y: radius * (( i + 1 ) mod 2 * ( 3 - i / 3))
                    content: "{i}"
                    font: Font {
                        size: 11
                        name: "Arial"
                    }
                },
                // making dots on rest of the place
                for (i in [1..12])
                if (i mod 3 != 0 ) then Circle {
                    transforms:Rotate { angle: 30 * i }
                    centerX: radius
                    radius: 3
                    fill: Color.BLACK
                } else [ ],

                // circle at the core center
                Circle {
                    radius: 5
                    fill: Color.BLACK
                },
                // one more circle inside the above circle
                Circle {
                    radius: 3
                    fill: Color.GRAY
                },
                // second arm
                Line {
                    transforms: Rotate { angle: bind seconds * 6 }
                    endY: -radius - 3
                    strokeWidth: 2
                    stroke: Color.RED

                },
                // hour arm
                Path {
                    transforms: Rotate {
				angle: bind (hours + minutes / 60) * 30 - 90
			  }
                    fill: Color.BLACK
                    elements: [
                        MoveTo {x: 4, y: 4},
                        ArcTo {x: 4 y: -4 radiusX: 1 radiusY: 1},
                        LineTo{ x: radius - 15  y: 0},
                    ]
                },
                // minute arm
                Path {
                    transforms: Rotate { angle: bind minutes * 6 - 90 }
                    fill: Color.BLACK
                    elements: [
                        MoveTo {x: 4, y: 4},
                        ArcTo {x: 4 y: -4 radiusX: 1 radiusY: 1},
                        LineTo{ x: radius  y: 0},
                    ]
                }

            ]
        };
        }
}

그림 1: AnalogClock.fx 클래스

맴버변수 radius값을 변경하여 시계 크기를 조절할 수 있다.

Source Code
var radius: Number = 80;    // Decides the main size of the clock.

그림 2: Data Member radius

커스터마이징 코드

시계의 원형 안에 색과 그레디언트를 변경하기 위해 gradient와 몇개의 속성들을 바꾼다.

소스 코드
Circle {
    radius: radius + 10
    stroke: Color.BLACK
    fill: RadialGradient {
          centerX: 0
          centerY: 0
          radius: 90
          proportional: false
          stops: [
              Stop { offset: 0.0 color: Color.WHITE },
              Stop { offset: 1.0 color: Color.YELLOWGREEN }
          ]
    }
},

그림 3: 색과 그레디언트 변경


그림 4:다른 그림자로 만든 시계