zeyuphoenix

          愿我愛(ài)的人快樂(lè),愿愛(ài)我的人快樂(lè),為了這些,我愿意不快樂(lè).

          Java計(jì)時(shí)器

          這個(gè)簡(jiǎn)單的Java計(jì)時(shí)器和Java數(shù)字時(shí)鐘的原理差不多,都是利用JavaTimer做計(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í)使用SwingTimer使界面的時(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ò)JavaGraphicsEnvironment取得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ò)JavaGraphicsEnvironment取得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)單,直接使用TimerStartStop就可以了.

              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í)鐘

          導(dǎo)航

          <2010年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          統(tǒng)計(jì)

          常用鏈接

          留言簿(52)

          隨筆分類

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 静海县| 哈密市| 比如县| 翁牛特旗| 交城县| 金堂县| 东宁县| 刚察县| 舒兰市| 资源县| 沙湾县| 库尔勒市| 繁昌县| 义乌市| 泰来县| 池州市| 图们市| 临江市| 疏附县| 玉溪市| 阳谷县| 赞皇县| 达尔| 西昌市| 浮梁县| 固原市| 明溪县| 泽普县| 南乐县| 精河县| 苍山县| 台北县| 偏关县| 平阴县| 凭祥市| 买车| 南和县| 嘉定区| 淳安县| 黄山市| 章丘市|