欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Swing繪制動(dòng)態(tài)時(shí)鐘

 更新時(shí)間:2019年12月20日 17:12:08   作者:歐世樂(lè)  
這篇文章主要為大家詳細(xì)介紹了使用Swing繪制動(dòng)態(tài)時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了利用Swing繪制一個(gè)動(dòng)態(tài)時(shí)鐘的具體代碼,供大家參考,具體內(nèi)容如下

效果

代碼在下面,可跳過(guò)解析。

前言

編程實(shí)現(xiàn)一個(gè)時(shí)鐘

利用Swing繪制一個(gè)時(shí)鐘,只能是靜態(tài)的。利用Calendar類獲取當(dāng)前的時(shí)分秒,然后根據(jù)數(shù)學(xué)公式繪制相應(yīng)的時(shí)鐘就可以了。

如果靜態(tài)的時(shí)鐘已經(jīng)足夠你使用,那么就無(wú)須用到線程的概念。

如何讓時(shí)鐘“動(dòng)起來(lái)”

當(dāng)然了,動(dòng)起來(lái)肯定是不可能的,但是我們可以利用人眼的視覺(jué),讓時(shí)鐘“好像動(dòng)起來(lái)”,其實(shí)著很簡(jiǎn)單,只要讓當(dāng)前的圖像每隔一秒種刷新一次就可以了。這樣秒針在動(dòng),數(shù)字時(shí)間也在動(dòng),整個(gè)時(shí)鐘就好像“動(dòng)起來(lái)了”

線程

利用線程實(shí)現(xiàn)刷新,刷新間隔是1秒,每次刷新都先生成當(dāng)前的時(shí)間,然后JVM又會(huì)自動(dòng)調(diào)用paintComponent方法繪制圖形,這樣就好像時(shí)鐘動(dòng)起來(lái)了。

Thread thread = new Thread(){
      public void run(){
        while(true){
          StillClock clock = new StillClock();
          MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+
              clock.getMinute()+":"+clock.getSecond());
          //設(shè)置顯示居中
          messagePanel1.setCentered(true);
          //設(shè)置前景顏色
          messagePanel1.setForeground(Color.black);
          //設(shè)置字體
          messagePanel1.setFont(new Font("Courier",Font.BOLD,16));

          add(clock);
          add(messagePanel1,BorderLayout.SOUTH);
          clock.setVisible(true);
          validate();    //接下來(lái)會(huì)每隔一秒重繪一次時(shí)鐘——即(從frame中將clock組件刪除),因此調(diào)用validate方法,使容器重新布置其子組件
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          clock.setVisible(false);
          remove(clock);   //在父容器中將其刪除
          clock.invalidate();    //使容器失效
        }
      }
    };
    thread.start();

線程代碼解析

Thread thread = new Thread(){};

注意結(jié)尾使用了分號(hào),既然使用了線程,那么需要重寫它的run方法:

public void run(){}

既然想讓時(shí)鐘一直動(dòng)起來(lái),那么死循環(huán)是最好的選擇

while(true){}

在while里面,每次都先生成當(dāng)前的時(shí)間:

StillClock clock = new StillClock();

這里生成了一個(gè)無(wú)參構(gòu)造的StillClock類,StillClock的無(wú)參構(gòu)造方法里面會(huì)自動(dòng)生成當(dāng)前的時(shí)間。

注意:這里的StillClock是我自己定義的,代碼貼在后面,但是如果不關(guān)心他是怎么實(shí)現(xiàn)的,可以直接忽略原理,直接使用,包括代碼里面的messagePanel也是一樣的自定義類。

時(shí)間生成完了之后,把時(shí)鐘圖形、當(dāng)前時(shí)間的字符串、布局位置利用add()方法繪制到屏幕上

add(clock);
add(messagePanel1,BorderLayout.SOUTH);

接下來(lái)會(huì)每隔一秒重繪一次時(shí)鐘——即(從frame中將clock組件刪除),因此調(diào)用validate方法,使容器重新布置其子組件。

thread.start();

讓線程開(kāi)始工作把。

完整代碼

DisplayClock.java:

package Test;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;

public class DisplayClock extends JFrame {
  public DisplayClock(){
    //創(chuàng)建一個(gè)現(xiàn)在的時(shí)間
    StillClock clock=new StillClock();
    //獲取當(dāng)前的時(shí)間
    clock.setCurrentTime();
    //設(shè)置時(shí)間的顯示格式

    Thread thread = new Thread(){
      public void run(){
        while(true){
          StillClock clock = new StillClock();
          MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+
              clock.getMinute()+":"+clock.getSecond());
          //設(shè)置顯示居中
          messagePanel1.setCentered(true);
          //設(shè)置前景顏色
          messagePanel1.setForeground(Color.black);
          //設(shè)置字體
          messagePanel1.setFont(new Font("Courier",Font.BOLD,16));

          add(clock);
          add(messagePanel1,BorderLayout.SOUTH);
          clock.setVisible(true);
          validate();    //接下來(lái)會(huì)每隔一秒重繪一次時(shí)鐘——即(從frame中將clock組件刪除),因此調(diào)用validate方法,使容器重新布置其子組件
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          clock.setVisible(false);
          remove(clock);   //在父容器中將其刪除
          clock.invalidate();    //使容器失效
        }
      }
    };
    thread.start();
    //布局默認(rèn)為BorderLayout,讓顯示信息在底部(即南邊)

  }

  public static void main(String[] args) {
    DisplayClock frame=new DisplayClock();
    frame.setTitle("DisplayClock");
    frame.setSize(300,350);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);


  }
}

StillClock.java:

package Test;

import sun.util.calendar.Gregorian;

import javax.swing.*;
import java.awt.*;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class StillClock extends JPanel {
  public int getHour() {
    return hour;
  }

  public void setHour(int hour) {
    this.hour = hour;
    repaint();
  }

  public int getMinute() {
    return minute;
  }

  public void setMinute(int minute) {
    this.minute = minute;
    repaint();
  }

  public int getSecond() {
    return second;
  }

  public void setSecond(int second) {
    this.second = second;
    repaint();
  }

  private int hour;
  private int minute;
  private int second;

  public StillClock() {
    setCurrentTime();
  }

  public StillClock(int hour, int minute, int second) {
    this.hour = hour;
    this.minute = minute;
    this.second = second;
  }

  //使用Graphics類繪制圖形,需要重寫paintComponent方法
  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    //繪制時(shí)鐘參數(shù)
    int clockRadius=(int)(Math.min(getWidth(),getHeight())*0.8*0.5);
    int xCenter=getWidth()/2;
    int yCenter=getHeight()/2;

    //繪制一個(gè)圓
    g.setColor(Color.BLACK);
    g.drawOval(xCenter-clockRadius,yCenter-clockRadius,2*clockRadius
    ,2*clockRadius);
    g.drawString("12",xCenter-5,yCenter-clockRadius+12);
    g.drawString("9",xCenter-clockRadius+3,yCenter+5);
    g.drawString("3",xCenter+clockRadius-10,yCenter
    +3);
    g.drawString("6",xCenter-3,yCenter+clockRadius-3);

    //繪制秒針
    int sLength=(int)(clockRadius*0.8);
    int xSecond=(int)(xCenter+sLength*Math.sin(second*(2*Math.PI/60)));
    int ySecond=(int)(xCenter-sLength*Math.cos(second*(2*Math.PI/60)));
    g.setColor(Color.red);
    g.drawLine(xCenter,yCenter,xSecond,ySecond);

    //繪制分針
    int mLength=(int)(clockRadius*0.65);
    int xMinute=(int)(xCenter+mLength*Math.sin(minute*(2*Math.PI/60)));
    int yMinute=(int)(xCenter-mLength*Math.cos(minute*(2*Math.PI/60)));
    g.setColor(Color.blue);
    g.drawLine(xCenter,yCenter,xMinute,yMinute);

    //繪制時(shí)針
    int hLength=(int)(clockRadius*0.5);
    int xHour=(int)(xCenter+hLength*Math.sin((hour%12+minute/60.0)*(2*Math.PI/12)));
    int yHour=(int)(xCenter-hLength*Math.cos((hour%12+minute/60.0)*(2*Math.PI/12)));
    g.setColor(Color.green);
    g.drawLine(xCenter,yCenter,xHour,yHour);


    }
  public void setCurrentTime(){
    //構(gòu)造一個(gè)日歷類設(shè)定當(dāng)前日期和時(shí)間
    Calendar calendar=new GregorianCalendar();

    //設(shè)定時(shí)分秒
    this.hour=calendar.get(Calendar.HOUR_OF_DAY);
    this.minute=calendar.get(Calendar.MINUTE);
    this.second=calendar.get(Calendar.SECOND);
  }

  public Dimension getPreferredSize(){
    return new Dimension(200,200);
  }
}

messagePanel:

package Test;

import javax.swing.*;
import java.awt.*;

public class MessagePanel extends JPanel {
  //顯示的信息
  private String message="Welcome to java";
  //顯示信息x的坐標(biāo)
  private int xCoordinate=20;
  //顯示信息y的坐標(biāo)
  private int yCoordinate=20;
  //信息是否被顯示在中心部位
  private boolean centered;
  //水平和垂直的移動(dòng)顯示信息
  private int interval=10;

  public int getXCoordinate() {
    return xCoordinate;
  }

  public void setXCoordinate(int xCoordinate) {
    this.xCoordinate = xCoordinate;
    repaint();
  }

  //無(wú)參構(gòu)造
  public MessagePanel() {
  }
  //帶參構(gòu)造
  public MessagePanel(String message) {
    this.message = message;
    repaint();

  }

  public int getYCoordinate() {
    return yCoordinate;
  }

  public void setYCoordinate(int yCoordinate) {
    this.yCoordinate = yCoordinate;
    repaint();

  }

  public boolean isCentered() {
    return centered;

  }

  public void setCentered(boolean centered) {
    this.centered = centered;
    repaint();

  }

  public int getInterval() {
    return interval;
  }

  public void setInterval(int interval) {
    this.interval = interval;
    repaint();

  }

  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if(centered){
      //設(shè)定字體
      FontMetrics fm=g.getFontMetrics();
      //設(shè)置顯示字體
      int stringWidth=fm.stringWidth(message);
      int stringAscent=fm.getAscent();
      xCoordinate=getWidth()/2-stringWidth/2;
      yCoordinate=getHeight()/2+stringAscent/2;
    }
    g.drawString(message,xCoordinate,yCoordinate);
  }
  //讓信息往左邊移動(dòng)
  public void moveLeft(){
    xCoordinate-=interval;
    repaint();
}
  //讓信息往右邊移動(dòng)
  public void moveRight(){
    xCoordinate+=interval;
    repaint();
  }
  //讓信息向上移動(dòng)
  public void moveUp(){
    yCoordinate+=interval;
    repaint();
  }
  public void moveDown(){
    yCoordinate-=interval;
    repaint();
  }
  //固定寫法,不必探究
  @Override
  public Dimension getPreferredSize() {
    return new Dimension(200,30);
  }
}

結(jié)束

寫的有些粗糙,有需要的可以根據(jù)自己的需求進(jìn)行更改,比如如何更加穩(wěn)定的實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘,讓時(shí)鐘刻度更加精細(xì)(根據(jù)數(shù)學(xué)公式增加刻度線即可),希望可以幫助到你。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中輸入輸出方式的簡(jiǎn)單示例

    Java中輸入輸出方式的簡(jiǎn)單示例

    Java語(yǔ)言的輸入輸出功能是十分強(qiáng)大而靈活的,美中不足的是看上去輸入輸出的代碼并不是很簡(jiǎn)潔,因?yàn)槟阃枰b許多不同的對(duì)象,下面這篇文章主要給大家介紹了關(guān)于Java中輸入輸出方式的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Mybatis?plugin的使用及原理示例解析

    Mybatis?plugin的使用及原理示例解析

    這篇文章主要為大家介紹了?Mybatis?plugin的使用及原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • SpringBoot和前端Vue的跨域問(wèn)題及解決方案

    SpringBoot和前端Vue的跨域問(wèn)題及解決方案

    所謂跨域就是從 A 向 B 發(fā)請(qǐng)求,如若他們的地址協(xié)議、域名、端口都不相同,直接訪問(wèn)就會(huì)造成跨域問(wèn)題,跨域是非常常見(jiàn)的現(xiàn)象,這篇文章主要介紹了解決SpringBoot和前端Vue的跨域問(wèn)題,需要的朋友可以參考下
    2023-11-11
  • 使用SpringBoot中web項(xiàng)目推薦目錄結(jié)構(gòu)的問(wèn)題

    使用SpringBoot中web項(xiàng)目推薦目錄結(jié)構(gòu)的問(wèn)題

    這篇文章主要介紹了SpringBoot中web項(xiàng)目推薦目錄結(jié)構(gòu)的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • 使用SpringBoot 工廠模式自動(dòng)注入到Map

    使用SpringBoot 工廠模式自動(dòng)注入到Map

    這篇文章主要介紹了使用SpringBoot 工廠模式自動(dòng)注入到Map,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 一文搞清楚Java中Comparable和Comparator的區(qū)別

    一文搞清楚Java中Comparable和Comparator的區(qū)別

    Java中的Comparable和Comparator都是用于集合排序的接口,但它們有明顯的區(qū)別,文中通過(guò)一些實(shí)例代碼詳細(xì)介紹了Java中Comparable和Comparator的區(qū)別,感興趣的同學(xué)跟著小編一起學(xué)習(xí)吧
    2023-05-05
  • 詳解spring boot集成RabbitMQ

    詳解spring boot集成RabbitMQ

    RabbitMQ作為AMQP的代表性產(chǎn)品,在項(xiàng)目中大量使用。結(jié)合現(xiàn)在主流的spring boot,極大簡(jiǎn)化了開(kāi)發(fā)過(guò)程中所涉及到的消息通信問(wèn)題。
    2017-03-03
  • JVM垃圾收集器詳解

    JVM垃圾收集器詳解

    本文主要介紹了JVM垃圾收集器的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 簡(jiǎn)單理解Java的抽象類

    簡(jiǎn)單理解Java的抽象類

    這篇文章主要介紹了Java的抽象類,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • mybatis的MappedStatement線程安全探究

    mybatis的MappedStatement線程安全探究

    這篇文章主要為大家介紹了mybatis的MappedStatement線程安全示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論