本文实例为大家分享了利用Swing绘制一个动态时钟的具体代码,供大家参考,具体内容如下
效果
代码在下面,可跳过解析。
前言
编程实现一个时钟
利用Swing绘制一个时钟,只能是静态的。利用Calendar类获取当前的时分秒,然后根据数学公式绘制相应的时钟就可以了。
如果静态的时钟已经足够你使用,那么就无须用到线程的概念。
如何让时钟“动起来”
当然了,动起来肯定是不可能的,但是我们可以利用人眼的视觉,让时钟“好像动起来”,其实着很简单,只要让当前的图像每隔一秒种刷新一次就可以了。这样秒针在动,数字时间也在动,整个时钟就好像“动起来了”
线程
利用线程实现刷新,刷新间隔是1秒,每次刷新都先生成当前的时间,然后JVM又会自动调用paintComponent方法绘制图形,这样就好像时钟动起来了。
Thread thread = new Thread(){ public void run(){ while(true){ StillClock clock = new StillClock(); MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+ clock.getMinute()+":"+clock.getSecond()); //设置显示居中 messagePanel1.setCentered(true); //设置前景颜色 messagePanel1.setForeground(Color.black); //设置字体 messagePanel1.setFont(new Font("Courier",Font.BOLD,16)); add(clock); add(messagePanel1,BorderLayout.SOUTH); clock.setVisible(true); validate(); //接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用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(){};
注意结尾使用了分号,既然使用了线程,那么需要重写它的run方法:
public void run(){}
既然想让时钟一直动起来,那么死循环是最好的选择
while(true){}
在while里面,每次都先生成当前的时间:
StillClock clock = new StillClock();
这里生成了一个无参构造的StillClock类,StillClock的无参构造方法里面会自动生成当前的时间。
注意:这里的StillClock是我自己定义的,代码贴在后面,但是如果不关心他是怎么实现的,可以直接忽略原理,直接使用,包括代码里面的messagePanel也是一样的自定义类。
时间生成完了之后,把时钟图形、当前时间的字符串、布局位置利用add()方法绘制到屏幕上
add(clock); add(messagePanel1,BorderLayout.SOUTH);
接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用validate方法,使容器重新布置其子组件。
thread.start();
让线程开始工作把。
完整代码
DisplayClock.java:
package Test; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; public class DisplayClock extends JFrame { public DisplayClock(){ //创建一个现在的时间 StillClock clock=new StillClock(); //获取当前的时间 clock.setCurrentTime(); //设置时间的显示格式 Thread thread = new Thread(){ public void run(){ while(true){ StillClock clock = new StillClock(); MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+ clock.getMinute()+":"+clock.getSecond()); //设置显示居中 messagePanel1.setCentered(true); //设置前景颜色 messagePanel1.setForeground(Color.black); //设置字体 messagePanel1.setFont(new Font("Courier",Font.BOLD,16)); add(clock); add(messagePanel1,BorderLayout.SOUTH); clock.setVisible(true); validate(); //接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用validate方法,使容器重新布置其子组件 try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } clock.setVisible(false); remove(clock); //在父容器中将其删除 clock.invalidate(); //使容器失效 } } }; thread.start(); //布局默认为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); //绘制时钟参数 int clockRadius=(int)(Math.min(getWidth(),getHeight())*0.8*0.5); int xCenter=getWidth()/2; int yCenter=getHeight()/2; //绘制一个圆 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); //绘制时针 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(){ //构造一个日历类设定当前日期和时间 Calendar calendar=new GregorianCalendar(); //设定时分秒 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的坐标 private int xCoordinate=20; //显示信息y的坐标 private int yCoordinate=20; //信息是否被显示在中心部位 private boolean centered; //水平和垂直的移动显示信息 private int interval=10; public int getXCoordinate() { return xCoordinate; } public void setXCoordinate(int xCoordinate) { this.xCoordinate = xCoordinate; repaint(); } //无参构造 public MessagePanel() { } //带参构造 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){ //设定字体 FontMetrics fm=g.getFontMetrics(); //设置显示字体 int stringWidth=fm.stringWidth(message); int stringAscent=fm.getAscent(); xCoordinate=getWidth()/2-stringWidth/2; yCoordinate=getHeight()/2+stringAscent/2; } g.drawString(message,xCoordinate,yCoordinate); } //让信息往左边移动 public void moveLeft(){ xCoordinate-=interval; repaint(); } //让信息往右边移动 public void moveRight(){ xCoordinate+=interval; repaint(); } //让信息向上移动 public void moveUp(){ yCoordinate+=interval; repaint(); } public void moveDown(){ yCoordinate-=interval; repaint(); } //固定写法,不必探究 @Override public Dimension getPreferredSize() { return new Dimension(200,30); } }
结束
写的有些粗糙,有需要的可以根据自己的需求进行更改,比如如何更加稳定的实现动态时钟,让时钟刻度更加精细(根据数学公式增加刻度线即可),希望可以帮助到你。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
问题内容: 我想提请使用Java网格(10×10),但我们必须使用来实现它的,这是我的计划至今 问题答案: 该代码有效。 只需删除25
问题内容: 我正在尝试用Java绘制曲线。一个简单的以(X,Y)开始,(X,Y)结束和曲线量的贝塞尔曲线就足够了。 我找不到在Swing中执行此操作的方法。如果不在Swing中,我可以使用一些简单的数学方法吗?我将如何在Swing中实现它? 编辑:我知道如何通过重写paint(Graphics g)方法绘制形状和线条。 问题答案: 您可以使用Java 2D Object Path2D.Double
本文向大家介绍Python使用Pygame绘制时钟,包括了Python使用Pygame绘制时钟的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Python使用Pygame绘制时钟的具体代码,供大家参考,具体内容如下 前提条件: 需要安装pygame 功能: 1.初始化界面显示一个时钟界面 2.根据当前的时间实现时针、分针、秒针的移动 运行结果: 以上就是本文的全部内容,希望对大家的学
主要内容:1 Swing绘制图形的介绍,2 Swing绘制图形的方法,3 Swing绘制图形的案例1 Swing绘制图形的介绍 java.awt.Graphics类提供了许多用于图形编程的方法。 2 Swing绘制图形的方法 方法 描述 public abstract void drawString(String str, int x, int y) 用于绘制指定的字符串。 public void drawRect(int x, int y, int width, int height) 绘制
本文向大家介绍Android绘制动态折线图,包括了Android绘制动态折线图的使用技巧和注意事项,需要的朋友参考一下 所谓动态折线图,就是折线图能随着手指的滑动进行动态绘制,这里很定会产生动画效果。基于这个效果,这里使用SurfaceView进行制图。 实现步奏如下: (1): 这里新建一个绘图ChartView,继承SurfaceView并实现SurfaceHolder.Callback ,
我试图画曼德布罗特集,其中的点是黑色的,其他的都是白色的。在这个初始版本中,我不希望能够放大,而只是创建一个静态图像。 我创建了一个ComplexNumber类,如下所示,用于处理平方运算和将复数相加。 这是我渲染GUI并实际计算Mandelbrot Set中的点的代码。 运行完这段代码后,我得到了下图。看起来曼德尔布罗特的布景有一点模糊,但随后被一吨黑色遮住了。我做错了什么? 更新的解决方案如下