- 浏览: 57905 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zeyuphoenix:
问题14:
对于emp中同一部门低于自己工资至少3人的员工,列 ...
SQL面试题(十) -
zeyuphoenix:
问题13:
对于emp中低于自己工资至少5人的员工,列出其部门 ...
SQL面试题(十) -
zeyuphoenix:
问题12:
对于emp中工资高于本部门平均水平,人数多与1人的 ...
SQL面试题(十) -
zeyuphoenix:
问题11:
对于emp,列出各个部门中平均工资高于本部门平均水 ...
SQL面试题(十) -
zeyuphoenix:
问题10:
对于工资高于本部门平均水平的员工,列出部门号,姓名 ...
SQL面试题(十)
Java的指针时钟
Java的指针时钟最基础的原理和数字时钟其实差不多,也是利用Swing的Timer计时,每隔一定时间重新绘制组件,最后重写paintComponent方法来更新界面.和之前介绍的时钟一样,为了保证时钟的正确启动和终止,需要重写组件的addNotify和removeNotify方法,在方法内加入Timer的启动和终止;最后也要重写组件getPreferredSize方法使组件的大小自动适应.
首先看最终的效果:
<!--[if gte vml 1]> <![endif]-->
<!--[if gte vml 1]> <![endif]-->
工程的目录:
<!--[if gte vml 1]> <![endif]-->
其中timespinner包是时间的微调组件,这儿只是为了显示用的,和指针时钟无关,先不介绍了.
Clock包则是显示指针时钟的包,指针时钟的组件类是AnalogClock,它继承于Clock类,处理和数字时钟的基本一致,先看Clock的:
/**
* This bean to define basic properties and behaviors of a clock, concrete
* instances will be implemented by <code>DigitalClock</code> and others.
*/
publicabstractclass Clock extends JComponent {
属性也是:
/**
* Font rendering context - assumes no default transform, anti-aliasing
* active and fractional metrics allowed.
*/
publicstaticfinal FontRenderContext frc = new FontRenderContext(null,
true, true);
/**
* The calendar instance for this clock.
*/
protected Calendar calendar;
/**
* @see #getBgImage()
*/
protected Image bgImage;
和数字时钟完全一样,提供基本属性和文本显示和绘制的信息容器.
再看AnalogClock:
/**
* To implement a analog-type clock.
*/
publicclass AnalogClock extends Clock implements ActionListener {
它有两个属性:
/**
* Parts to construct this clock.
*/
private Parts parts = null;
/**
* A timer to run in a independent thread.
*/
private Timer timer = null;
一个是定时刷新时间的Timer,一个是时钟的样式.
具体方法有,
1.复写addNotify和removeNotify方法控制Timer的启动和终止.
/**
* @see java.awt.Component#addNotify()
*/
@Override
publicvoid addNotify() {
super.addNotify();
timer.start();
}
/**
* @see java.awt.Component#removeNotify()
*/
@Override
publicvoid removeNotify() {
timer.stop();
super.removeNotify();
}
2.复写getPreferredSize方法使组件自动适应大小.
/**
*/
@Override
public Dimension getPreferredSize() {
Dimension size = getSize();
size.width = parts.getSize().width;
size.height = parts.getSize().height + MARGIN;
return size;
}
3.复写paintComponent使修正外观
@Override
publicvoid paintComponent(Graphics g) {
4.实现Timer必须的actionPerformed方法,做定时任务
/**
* Do transformation based on current precise time when display.
*/
@Override
publicvoid actionPerformed(ActionEvent e) {
主要操作是取得当前时间,更新组件:
parts.doTransform(hour, minute, second, millisecond);
repaint();
// Resize this clock in time
setSize(getPreferredSize());
还有最主要的构造函数,组件的外观通过它传入,
/**
* Constructor:<br>
* Creates an analog-type clock by using given parts.
*/
public AnalogClock(Parts parts) {
并且把Timer初始化:
timer = new Timer(1000, this);
到现在为止,和时间设置相关的已经完成,剩下的就是传入组件的表现Parts,使画面呈现了.
指针时钟的呈现主要使用了Parts、RotateParts、BasicParts和MyParts四个类,它们是继承关系.
其中Parts是最基本的,它主要描绘指针时钟最外层的边框、指针时钟颜色和大小,,并且提供了虚的 doTransform方法供子类实现绘制;
RotateParts在Parts的基础上提供了圆心和半径把数字时钟最外层的圆的属性提供出来,并提供了画刻度的方法,没有具体的绘制;
BasicParts是主要的绘制类,它完成了指针时钟显示的大部分工作,提供时钟上的数字和时分秒指针以及指针的变换器这些基本属性,并提供了绘制数字和指针在组件上的方法,简单的继承它就可以实现一个指针时钟了,只是不够美观;
MyParts是继承于BasicParts的类,它主要目的是把指针时钟做的更美观,并且定义时钟的基本大小,颜色等,提供了更好的绘制钟面上数字和指针的方法.
现在依次详细看看这些类:
首先是最基本的Parts
/**
* To represent all modules which a analog-type clock consists of.
*/
publicabstractclass Parts extends JComponent {
再看看它的属性:
/**
* Coloring scheme for the parts.
*/
protected BasicColor colors;
/**
* Size of this parts.
*/
protected Dimension size;
/**
* Clock face.
*/
protected Shape dial;
分别控制时钟的各个颜色,大小,和外观样式.
然后是方法,它提供一个虚方法给具体类实现:
/**
* Changes positions of hour hand, minute hand, second hand and * decisecond hand based on current time.
*/
publicabstractvoid doTransform(int hour, int minute, int second,
int millisecond);
这个方法主要是按给定的时间值得出指针在时钟上的位置和角度.
接着是RotateParts类:
/**
* This class defines a classical clock behavior by using rotation pattern, *as we all know in common sense.
*/
publicabstractclass RotateParts extends Parts {
再看看它的属性:
/**
* X coordinate of the center.
*/
protectedfloatx;
/**
* Y coordinate of the center.
*/
protectedfloaty;
/**
* Radius of the clock face.
*/
protectedfloatradius;
分别给定了指针时钟的圆的圆心和半径,没有提供绘制方面的属性.
然后是方法,它提供了几个给定时间值换算为时钟位置的方法:
/**
* a rotation instance from 12 o'clock direction.
*/
public AffineTransform getTransform() {
return AffineTransform.getRotateInstance(0, x, y);
}
这个方法是提供默认的指针的位置,即绕圆心(0,0)点旋转0度,即12点位置.
接着
/**
* Sets rotation algorithm by given value.
*/
publicvoid setToRotation(AffineTransform af, double value, int grad) {
af.setToRotation(value * (2 * Math.PI / grad), x, y);
}
这个方法根据给定的具体值(这里可以理解为当前具体时间的时、分或者秒)和总的时间划分(12或者60)算出需要旋转的角度,然后绕圆心(x,y)旋转.
最后是
/**
* Gets a rotation transform by given parameters.
*/
public AffineTransform getRotateInstance(int grad, int seq) {
return getRotateInstance(x, y, grad, seq);
}
/**
* Get a rotation transform by given parameters.
*/
publicstatic AffineTransform getRotateInstance(float x, float y, int grad, int seq) {
return AffineTransform.getRotateInstance((2 * Math.PI / grad) * seq, x, y);
}
这个是根据指定的值和总值以及中心点取得映射变换的实例.
接着就是重要的BasicParts类了
/**
* To implement a classical analog-type clock face, except definitely *describing the hands shape.<br>
*/
publicabstractclass BasicParts extends RotateParts {
它是钟表刻度的继承,继承它就可以实现自己的指针钟表了.
先看它的属性:
/**
* Hour hand.
*/
protected Shape hourHand;
/**
* Minute hand.
*/
protected Shape minuteHand;
/**
* Second hand.
*/
protected Shape secondHand;
/**
* Hour hand behavior controller.
*/
protected AffineTransform hourTransform;
/**
* Minute hand behavior controller.
*/
protected AffineTransform minuteTransform;
/**
* Second hand behavior controller.
*/
protected AffineTransform secondTransform;
这6个属性提供时分秒三个时针的形状和绘制映射类,通过它们可以对钟表进行绘制.
/**
* Moves all parts, to leave some margin.
*/
protectedtransient AffineTransform trans;
这个属性是在对时分秒指针绘制时提供变换的.
/**
* Arabic time punctualities.
*/
publicstaticfinal String[] ARABIC = { "12", "1", "2", "3", "4", "5", "6","7", "8", "9", "10", "11" };
/**
* Roman time punctualities.
*/
publicstaticfinal String[] ROMAN = { "XII", "I", "II", "III", "IV", "V","VI", "VII", "VIII", "IX", "X", "XI" };
这两个常量是提供表盘的刻度显示的,也可以自己定义一个12位的数组代替.
再看它的构造函数
/**
* Constructor: Joins every parts in a entire analog-type clock.
*/
protected BasicParts(Shape dial, Shape hourHand, Shape minuteHand,
Shape secondHand, String[] numbers, BasicColor colors)
throws Exception {
需要传入外围图形、时分秒图形、刻度数字和各部分颜色.当然可以传入new GeneralPath()
在以后再具体描绘它们.
/**
* Initializes hand transformation.
*/
protectedvoid initTransform() {
hourTransform = getTransform();
minuteTransform = getTransform();
secondTransform = getTransform();
}
这个是初始化时分秒绘制映射类的.默认让它们都指向12点方向.
/**
* Default algorithm for hands's action trace.
*/
@Override
publicvoid doTransform(int hour, int minute, int second, int millisecond) {
if (hourTransform != null && minuteTransform != null
&& secondTransform != null) {
setToRotation(hourTransform,
hour + (minute + second / 60.0) / 60.0, 12);
setToRotation(minuteTransform, minute + second / 60.0, 60);
setToRotation(secondTransform, second, 60);
}
}
这个是父类的虚函数的实现,根据给定值旋转指定角度呈现给画面.
/**
* Draws a number at 12 o'clock.
*/
protectedvoid drawNumber(Graphics g, String number, Font font) {
BasicColor c = (BasicColor) colors;
AttributedString num = new AttributedString(number);
if (font != null) {
num.addAttribute(TextAttribute.FONT, font);
}
drawNumber(g, num, x, y - radius, c.numbers);
}
/**
* Draws a number at 12 o'clock.
*/
publicstaticvoid drawNumber(Graphics g, AttributedString number, float x, float y, Color color) {
if (number != null) {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(color);
g2.drawString(number.getIterator(), x, y);
}
}
是按指定的属性在表盘上画刻度的.
最后是重要的paintComponent方法了
@Override
publicvoid paintComponent(Graphics g) {
它按照属性了上面取得的绘制映射类进行绘制
首先是绘制外围界面:
g2.setPaint(c.dail);
g2.fill(trans.createTransformedShape(dial));
g2.setPaint(Color.BLACK);
g2.draw(trans.createTransformedShape(dial));
然后绘制时分秒指针:
// Draw hour hand
g2.setPaint(c.hourHand);
g2.fill(trans.createTransformedShape(hourTransform
.createTransformedShape(hourHand)));
分秒基本和时的一样.
最后要看的类就是自己实现的MyParts类了,其实这里简单实现一个SimpleParts也可以的只是界面比较难看,如下图:
<!--[if gte vml 1]> <![endif]-->
所以需要做漂亮点还是要自己去写一部分代码的.
先看继承关系
/**
* A piece of sample code to show how to develop a nice-looking analog-type
* clock by using this API.
*/
publicfinalclass MyParts extends BasicParts {
首先还是看它的属性:
/**
* Radius of the clock face.
*/
protectedfloatradius;
这个是定义钟表的半径.
/**
* 12 hour ticks.
*/
protected Shape tick;
/**
* Other 48 minute ticks not at time punctualities.
*/
private GeneralPath smallTick;
这2个是定义钟表的刻度,分别代表比较明显的12个整点刻度,和其它48个不明显的刻度.
/**
* X coordinate of left top corner.
*/
privatestaticfloatxNW = 0;
/**
* Y coordinate of left top corner.
*/
privatestaticfloatyNW = 0;
/**
* Width of the square.
*/
privatestaticfloatwidth = 170;
这2个属性分别代表距离中心的坐标和表的外围大小.
/**
* Additional margin size in proportion of radius by percentage.
*/
privatestaticfloatmarginOfRadius = 0.1f;
这个属性代表空白区域的百分比.
然后是方法,先看画刻度的方法:
/**
* Draws ticks.
*/
publicstaticvoid drawTicks(Graphics g, Shape tick, int tickNumber,
float x, float y, AffineTransform trans, Color color) {
首先得到最基本的指针位置,默认指向12点位置:
AffineTransform at = AffineTransform.getRotateInstance(0, x, y);
然后取得偏移的角度:
at = RotateParts.getRotateInstance(x, y, tickNumber, p);
最后是绘制:
g2.fill(trans.createTransformedShape(at
.createTransformedShape(tick)));
再看绘制指针的方法:
/**
* Generate hour hand and minute hand shape.
*/
privatevoid createHand(Shape hand, float x, float y, float radius,
float widthPercent, float lengthPercent, float marginPercent,
float firstWidthPercent, float firstLengthPercent,
float secondWidthPercent, float secondLengthPercent) {
这个是绘制时针和分针的,形状是尾部粗尖端细
h.moveTo(x, y);
h.curveTo(x - radius * (widthPercent / 2) * (firstWidthPercent / 2), y- radius * marginPercent * (firstLengthPercent / 2), x – radius * (widthPercent / 2) * (secondWidthPercent / 2), y – radius * marginPercent * (secondLengthPercent / 2), x, y – radius * lengthPercent);
/**
* Generates concrete hand shape.
*/
publicstaticvoid createHand(Shape hand, float x, float y, float radius, float widthPercent, float lengthPercent, float marginPercent) {
这个是绘制秒针的,粗细均匀,比较简单
h.moveTo(x - radius * (widthPercent / 2), y + radius * marginPercent);
h.lineTo(x + radius * (widthPercent / 2), y + radius * marginPercent);
再看绘制表上数字的方法
/**
* An algorithm to locate time punctualities numbers on a round clock *face
*/
privatevoid drawNumbers(Graphics g, String[] numbers, float marginPercent, Font font) {
以3点举例,先算角度:
float cZero1 = (float) Math.cos((2 * Math.PI / 12) * 3);
再把数字转为属性串,取得宽度:
num = new AttributedString(numbers[p]);
num.addAttribute(TextAttribute.FONT, font);
layout = new TextLayout(numbers[p], font, Clock.frc);
float width = layout.getBounds().getBounds().width;
然后算出坐标:
float px = (float) (x + trans.getTranslateX() + radius
* (1 + marginPercent) * sin);
最后调用父类绘制方法绘制:
super.drawNumber(g, num, px, py, color);
接着是初始化方法,它把指针和表盘大小,位置都进行了初始化:
/**
* To initialize some parameters and every parts shape.
*/
protectedvoid initialize() {
首先算圆心和半径:
x = xNW + width / 2;
y = yNW + width / 2;
radius = width / 2 - 5;
然后画时针:
设定各个百分比位置,然后调用时针方法
float hWidthOfRadius = 0.08f;
float hLengthOfRadius = 0.7f;
createHand(hourHand, x, y, radius, hWidthOfRadius, hLengthOfRadius,
hMarginOfRadius, fstWidthOfRadius, fstLengthOfRadius,
sndWidthOfRadius, sndLengthOfRadius);
其它指针也是类似画出.
最后是复写paintComponent方法,当属性变更时重新绘制指针时钟:
/**
* Paint ticks and time punctualities.
*/
@Override
publicvoid paintComponent(Graphics g) {
在里面进行了指针数字和刻度绘制方法的调用
// Draw 12 numbers by using specific font
drawNumbers(g, numbers, marginOfRadius, new Font("Ravie", Font.BOLD + Font.ITALIC, 8));
// Draw 12 hour ticks, here use SimpleParts
drawTicks(g, tick, max, x, y, trans, c.tick);
// Draw 48 minute ticks, here use SimpleParts
drawTicks(g, smallTick, 60, x, y, trans, c.tick);
这个绘制类就完成了.
到此为止,所有的指针时钟的创立工作全部完成.
最后通过
/**
* This method shows how to create a user defined analog-type clock
*/
private AnalogClock getColorfulClock() {
if (colorfulClock == null) {
try {
colorfulClock = new AnalogClock(new MyParts());
} catch (Exception e) {
e.printStackTrace();
}
}
returncolorfulClock;
}
就可以使用了.
相关推荐
【Java指针时钟】是一种使用Java编程语言实现的模拟时钟程序,它展示了时间的基本元素:小时、分钟和秒。这个程序通过图形用户界面(GUI)显示时钟的表盘,时针、分针和秒针分别表示当前时间的状态。在Java中,这种...
在Java编程语言中,创建一个带有指针的时钟是一个典型的图形用户界面(GUI)编程任务,这通常涉及到Swing或JavaFX库。这个项目"Java实现带指针的时钟"显然使用了Java的GUI功能来模拟一个圆形时钟,并且能够同步显示...
java 实现绘制指针时钟 和多线程服务器java 实现绘制指针时钟 和多线程服务器java 实现绘制指针时钟 和多线程服务器java 实现绘制指针时钟 和多线程服务器java 实现绘制指针时钟 和多线程服务器java 实现绘制指针...
总结一下,基于Java Swing的指针时钟项目涵盖了以下知识点: 1. Java Swing组件使用,如`JFrame`和`JPanel` 2. `Graphics2D`绘图 3. 时间处理和数学运算 4. `java.util.Timer`和`java.util.TimerTask`的定时任务 5....
Java图形时钟是一种利用Java编程语言创建的可视化应用程序,它能模拟现实世界中的钟表,显示当前的时间。在这个项目中,开发者使用了Eclipse作为集成开发环境(IDE),结合Java的多媒体功能,来构建这个图形时钟。...
Java图形界面时钟是一种利用Java编程语言开发的GUI(图形用户界面)应用程序,它能够模拟现实世界中的机械钟,展示当前的时间。在这个程序中,开发者通过设计和实现一个美观的界面,增强了用户的视觉体验,使其在...
使用Java的Graphics2D API,可以实现复杂的图形绘制,包括时钟的圆形背景、刻度、指针等。Graphics2D允许精确控制线条、颜色和形状,以模拟真实的时钟界面。 5. **类的继承**: 报告中提到的`TestClock`类继承自`...
在IT领域,指针时钟是一种常见的用户界面元素,它模拟了传统机械钟表的显示方式,用指针来指示当前的时间。在这个“shizhong.zip”压缩包中,包含了一个名为“shizhong.txt”的文件,我们可以推测这可能是关于一个...
4. **角度和坐标转换**:在绘制时钟指针时,需要将时间转换为角度。例如,12小时制的时钟,每小时对应30度,每分钟对应0.5度。然后,根据这些角度计算出指针在画布上的起点和终点坐标。 5. **颜色和填充**:`...
总的来说,创建一个"指针式时钟"涉及Java GUI编程、图形绘制、时间和角度的数学计算等多个知识点。通过这个项目,开发者不仅可以学习到SWING的基本用法,还能提升对图形界面实时更新的理解。提供的文档"指针式时钟....
Java真图时钟是一个基于Java编程语言实现的模拟时钟应用。这个项目展示了如何在Java中利用图形用户界面(GUI)来创建一个实时更新的时钟。以下是对这个项目涉及的知识点的详细解释: 1. **Java GUI**:Java GUI...
在Java编程语言中,动态时钟效果的实现主要依赖于`javax.swing.Timer`类和图形用户界面(GUI)组件。`javax.swing.Timer`是Java Swing库中的一个关键类,用于在指定的时间间隔内触发事件。它非常适合创建动画效果,...
这个面板将包含时钟的数字或指针组件,你可以选择使用`JLabel`来显示数字时间。 4. **更新时间**: 为了使时钟实时更新,我们需要创建一个定时器任务,每隔一秒(或其他自定义间隔)更新时间显示。`java.util....
通过设计一个包含指针和数字显示的多功能时钟,学生可以巩固Java基础知识,如图形用户界面(GUI)的构建,事件处理,线程管理等。同时,该设计也有助于提升学生的问题解决能力和代码调试技巧。 二、设计要求 设计...
在本实验中,我们将设计一个动态时钟程序,利用Java的多线程特性来模拟时钟的指针移动。这个程序的核心在于理解和运用Java线程的相关知识点,包括线程的创建、调度、同步以及生命周期管理。以下是关于这些知识点的...
Java动态时钟是一种常见的编程练习,它通过使用Java Swing库来创建一个实时更新时间的可视化时钟。在本文中,我们将深入探讨如何使用Java Swing入门,以及如何利用Java的绘图功能来实现一个动态时钟。 Java Swing是...
### Java桌面时钟程序知识点解析 #### 一、程序概述 本程序是一个使用Java语言编写的桌面时钟Applet小程序。Applet是一种可以嵌入到网页中的小型应用程序,早期广泛应用于浏览器环境中。此程序主要实现了在桌面上...
在Java编程语言中,开发一个圆形时钟,也就是模拟现实世界中的钟表,涉及到许多核心概念和技术。这个"Java圆形时钟,钟表源码"项目是一个很好的学习平台,可以帮助初学者深入理解Java时间处理、图形用户界面(GUI)...
Java Swing 提供了 javax.swing.Timer 类,用于执行周期性的任务,例如更新时钟的指针位置。在这个项目中,开发者可能使用了Timer来每秒或每分钟触发一次事件,更新时间显示。 4. **图像缓存**: 描述中提到的...