Java計(jì)時(shí)器
這個(gè)簡(jiǎn)單的Java計(jì)時(shí)器和Java數(shù)字時(shí)鐘的原理差不多,都是利用Java的Timer做計(jì)時(shí),然后根據(jù)當(dāng)前的時(shí)間生成需要顯示的圖片或者文字,通過(guò)重寫(xiě)paintComponent方法呈現(xiàn)在界面上.
先看看效果:


基本的工程目錄結(jié)構(gòu)如下:

其中MissionTimerPanel是主要的類,它主要提供了計(jì)時(shí)器顯示數(shù)字的繪制,計(jì)時(shí)器背景的繪制,計(jì)時(shí)器閃爍的點(diǎn)的繪制,同時(shí)使用Swing的Timer使界面的時(shí)間發(fā)生改變,最終調(diào)用Java的重繪,通過(guò)paintComponent方法刷新界面.
先寫(xiě)一下它的繼承關(guān)系:
publicclass MissionTimerPanel extends JPanel implements ActionListener, MouseListener {
看一下它的主要屬性字段:
/** the image of number 0~9 */
privatefinal BufferedImage[] DIGIT_ARRAY = { createDigit(0),
createDigit(1), createDigit(2), createDigit(3), createDigit(4), createDigit(5), createDigit(6), createDigit(7), createDigit(8), createDigit(9) };
/** the image of the dots display */
privatefinal BufferedImage DOTS_ON = createDots(true);
/** the image of the dots disappear */
privatefinal BufferedImage DOTS_OFF = createDots(false);
/** the image of panel background */
privatefinal BufferedImage BACKGROUND_IMAGE = createBackground(450, 180);
/** mission timer */
privatefinal Timer TIMER = new Timer(500, this);
分別定義了數(shù)字的圖片,點(diǎn)的圖片,背景圖片和Timer.
通過(guò)構(gòu)造函數(shù)設(shè)置大小和增加鼠標(biāo)監(jiān)聽(tīng):
public MissionTimerPanel() {
setPreferredSize(new Dimension(450, 180));
setSize(new Dimension(450, 180));
addMouseListener(this);
}
然后是繪制數(shù)字的方法
// create digit with given number.
private BufferedImage createDigit(int digit) {
首先通過(guò)Java的GraphicsEnvironment取得GraphicsConfiguration,創(chuàng)建圖片:
GraphicsConfiguration gfxConf = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
BufferedImage IMAGE = gfxConf.createCompatibleImage(46, 65,
Transparency.TRANSLUCENT);
然后創(chuàng)建圖片的繪制樣式和上下文:
Graphics2D g2 = (Graphics2D) IMAGE.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
接著開(kāi)始創(chuàng)建數(shù)字組成的線,每個(gè)數(shù)字組成都是8這個(gè)數(shù)字的一份,所以先繪制一下8所需要的所有線段:
GeneralPath segment_a = new GeneralPath();
segment_a.moveTo(17, 0);
segment_a.lineTo(38, 0);
segment_a.lineTo(37, 8);
segment_a.lineTo(16, 8);
segment_a.closePath();
這是其中一條,其它的也類似.
最后就是根據(jù)數(shù)字使用上面的線條繪制指定的圖片了:
case 2:
g2.setColor(COLOR_ON);
g2.fill(segment_a);
g2.fill(segment_b);
g2.fill(segment_d);
g2.fill(segment_e);
g2.fill(segment_g);
g2.setColor(COLOR_OFF);
g2.fill(segment_c);
g2.fill(segment_f);
g2.setColor(FRAME_COLOR_ON);
g2.draw(segment_a);
g2.draw(segment_b);
g2.draw(segment_d);
g2.draw(segment_e);
g2.draw(segment_g);
g2.setColor(FRAME_COLOR_OFF);
g2.draw(segment_c);
g2.draw(segment_f);
break;
這是2的繪制,其它的也類似,這樣就生成了所有的數(shù)字.
然后是繪制點(diǎn)的方法:
private BufferedImage createDots(boolean on) {
它和繪制數(shù)字基本一致,也是通過(guò)Java的GraphicsEnvironment取得GraphicsConfiguration,創(chuàng)建圖片,然后創(chuàng)建圖片的繪制樣式和上下文,最后畫(huà)點(diǎn):
g2.setColor(COLOR_ON);
g2.fillOval(8, 20, 7, 7);
g2.fillOval(5, 39, 7, 7);
g2.setColor(FRAME_COLOR_ON);
g2.drawOval(8, 20, 7, 7);
g2.drawOval(5, 39, 7, 7);
接著是繪制背景的顏色、字和圖片:
private BufferedImage createBackground(int width, int height) {
前面創(chuàng)建圖片和設(shè)置樣式和繪制數(shù)字和點(diǎn)的基本一致,只是使用了LinearGradientPaint進(jìn)行顏色漸變的繪制:
final LinearGradientPaint GRADIENT_HIGHLIGHT = new LinearGradientPaint(START_HIGHLIGHT, STOP_HIGHLIGHT, FRACTIONS_HIGHLIGHT, COLORS_HIGHLIGHT);
g2.setPaint(GRADIENT_HIGHLIGHT);
g2.fillRect(17, 79, 176, 87);
g2.fillRect(193, 79, 239, 87);
最后把對(duì)應(yīng)的顯示字繪制上:
g2.drawString("HOURS", 75, 65);
這樣所有的繪制圖片就結(jié)束了.
然后是處理組件的監(jiān)聽(tīng):
@Override
publicvoid mouseClicked(MouseEvent event) {
當(dāng)鼠標(biāo)點(diǎn)擊組件時(shí)啟動(dòng)Timer,再次點(diǎn)擊終止Timer
if (event.getButton() == MouseEvent.BUTTON1) {
if (TIMER.isRunning()) {
stopTimer();
} else {
startTimer();
}
if (event.getClickCount() == 2) {
resetTimer();
}
}
啟動(dòng)、啟動(dòng)和重置Timer比較簡(jiǎn)單,直接使用Timer的Start和Stop就可以了.
publicvoid startTimer() {
TIMER.start();
}
重置的話還要停止Timer后再刷新一次畫(huà)面.
再來(lái)就是Timer啟動(dòng)后觸發(fā)的事件:
@Override
publicvoid actionPerformed(ActionEvent event) {
在這里會(huì)根據(jù)計(jì)數(shù)設(shè)置當(dāng)前應(yīng)該顯示的圖片,最后調(diào)用repaint.
if (sec_right == 10) {
sec_right = 0;
sec_left++;
}
最后就是復(fù)寫(xiě)paintComponent方法使組件更新了:
@Override
protectedvoid paintComponent(Graphics g) {
首先取得繪制的上下文Graphics2D g2 = (Graphics2D) g.create();
然后設(shè)置繪制的屬性和樣式:
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
g2.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
設(shè)置好顏色、鋸齒、混合色、邊等屬性后就可以繪制了:
//背景的繪制
g2.drawImage(BACKGROUND_IMAGE, 0, 0, this);
//點(diǎn)的繪制
g2.drawImage(DOTS_ON, 172, 90, this);
//時(shí)分秒等的繪制
g2.drawImage(DIGIT_ARRAY[hour_left], 38, 90, this);
繪制完所有的時(shí)分秒、點(diǎn)之后,重寫(xiě)就完成了.
因?yàn)檫@個(gè)組件就是一個(gè)Panel,可以和正常Panel一樣使用,通過(guò)new MissionTimerPanel();就可以調(diào)用了.
posted on 2010-04-06 21:40 zeyuphoenix 閱讀(5011) 評(píng)論(0) 編輯 收藏 所屬分類: Java的時(shí)鐘