一个精美的java时钟 (自动换背景 秒针平滑移动)
部分核心代码:
- public void paint(Graphics g1) {
- // Graphics2D继承Graphics,比Graphics提供更丰富的方法
- Graphics2D g = (Graphics2D) g1;
- /** ***画圆形时钟的刻度,每6度便有一个刻度**** */
- for (int i = 0; i < 360; i = i + 6) {
- g.setColor(Color.gray);
- // 设置画笔的宽度为2
- g.setStroke(new BasicStroke(2));
- // 画刻度
- if (i % 90 == 0) {
- // 对于0,3,6,9点位置,使用一个大的刻度
- g.setColor(Color.pink);
- g.setStroke(new BasicStroke(7));// 画笔宽度为5
- // 当起点和终点一样时,画的就是点
- g.drawLine(
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS),
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS));
- } else if (i % 30 == 0) {
- // 如果角度处于小时的位置,而且还不在0,3,6,9点时,画红色的小刻度
- g.setColor(Color.orange);
- g.setStroke(new BasicStroke(3));// 画笔宽度为3
- g.drawLine(
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS),
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS));
- } else {
- // 其他位置就画小刻度
- g.setColor(Color.gray);
- g.drawLine(
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS),
- CIRCLE_X
- + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS),
- CIRCLE_Y
- + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS));
- }
- }
- /** ****** 画时钟的指针 ******** */
- // 画时针
- Line2D.Double lh = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X
- + Math.cos((arcHour - 90) * Math.PI / 180) * HOUR_LENGTH,
- CIRCLE_Y + Math.sin((arcHour - 90) * Math.PI / 180)
- * HOUR_LENGTH);
- // 设置画笔宽度和颜色
- g.setStroke(new BasicStroke(8));
- g.setColor(Color.pink);
- // 利用Graphics2D的draw方法画线
- g.draw(lh);
- // 画分针
- Line2D.Double lm = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X
- + Math.cos((arcMin - 90) * Math.PI / 180) * MIN_LENGTH,
- CIRCLE_Y + Math.sin((arcMin - 90) * Math.PI / 180)
- * MIN_LENGTH);
- g.setStroke(new BasicStroke(4));
- g.setColor(Color.orange);
- g.draw(lm);
- // 画秒针
- Line2D.Double ls = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X
- + Math.cos((arcSec - 90) * Math.PI / 180) * SEC_LENGTH,
- CIRCLE_Y + Math.sin((arcSec - 90) * Math.PI / 180)
- * SEC_LENGTH);
- g.setStroke(new BasicStroke(1));
- g.setColor(Color.lightGray);
- g.draw(ls);
- /** **** 画时钟背景,并将其透明处理 ******* */
- // 所有使用bufferedImageGraphics画的图像,都画在bufferedImage上,
- // drawImage方法的参数含义分别是:背景图片对象、目标位置第一个角的X、Y坐标、目标位置第二个角的X、Y坐标、
- // 源位置第一个角的X、Y坐标、源位置第二个角的X、Y坐标、图像对象改变时的通知接受者
- bufferedImageGraphics.drawImage(img[imageID], 0, 0, imageSize,
- imageSize, 0, 0, imageSize + 10, imageSize + 10, this);
- // 将背景图片透明化
- for (int j = 0; j < imageSize; j++) {
- for (int i = 0; i < imageSize; i++) {
- // 获得背景图像中(i, j)坐标的颜色值
- int pix = bufferedImage.getRGB(i, j);
- Color c = new Color(pix);
- int R = c.getRed();
- int G = c.getGreen();
- int B = c.getBlue();
- // 通过Color对象的alpha,使颜色透明。
- int newpix = new Color(R, G, B, alpha).getRGB();
- // 重新设置背景图像该象素点的颜色
- bufferedImage.setRGB(i, j, newpix);
- }
- }
- /** 以上画背景操作都是画在bufferedImage上的,这里要将bufferedImage画在ClockLabel **/
- // 将当前用户剪贴区 Clip 与椭圆区域相交,并将 Clip 设置为所得的交集
- g.clip(new Ellipse2D.Double(95, 45, imageSize, imageSize));
- g.setColor(Color.white);
- // 在用户剪贴区画bufferedImage
- g.drawImage(bufferedImage, 95, 45, this);
- }