窗口类
package per.experiment5;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Window_time {
JLabel jlabel=new JLabel();
JFrame jframe;
JPanel jpanel;
Graphics g1;
public void win() {
jframe=new JFrame("时钟");
jframe.setSize(400, 400);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
jlabel.setHorizontalAlignment(JLabel.CENTER);//设置组件字体位置
jlabel.setForeground(Color.white);//设置组件字体颜色
jlabel.setFont(new Font("宋体",Font.BOLD,20));//设置组件字体
jpanel=new JPanel();
jpanel.setLayout(new BorderLayout());
jpanel.setPreferredSize(new Dimension(200,200));
jpanel.setBackground(Color.black);
jpanel.add(jlabel,BorderLayout.PAGE_END);
jframe.add(jpanel,BorderLayout.CENTER);
jframe.setVisible(true);
//!!!此处注意,getGraphics()方法必须是在组件可视化后才会成功,否则会返回null
//!!!并且g1在此调用,例如使用fillRect()方法会没有任何反应,查阅资料解释是也因为调用成功但时间太短,
//!!!系统会不断调用repaint()方法进行重绘,导致图像一闪而过,我的解决方案是将对g1的调用放在线程类的run()方法中进行不断循环
//!!!但对这种现象的原因还是不太能清楚明白,对解决方法的简易性也存在质疑,如果有更好的方法望告知
}
}
`
主类调用类
`public class Title1 {
public static void main(String[] args) {
new MyRunnable();
}
线程类:实现时钟功能
package per.experiment5;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Calendar;
import javax.swing.JPanel;
class MyRunnable implements Runnable{
public Graphics g;
public JPanel jpanel;
public MyRunnable() {
Thread t=new Thread(this);
t.start();
}
public void run() {
Window_time win1=new Window_time();
win1.win();
g=win1.g1;
jpanel=win1.jpanel;
g.setColor(Color.white);
int h_needle,m_needle,s_needle;
while(true) {try {
Thread.sleep(1000);
g.clearRect(0, 0, 1000, 1000);
g.setColor(Color.black);
g.fillRect(0, 0, 1000, 1000);
}catch(Exception e) {
e.getMessage();
}
Calendar calendar=Calendar.getInstance();//获取日期
h_needle=calendar.get(Calendar.HOUR);//获取当前小时
m_needle=calendar.get(Calendar.MINUTE);//获取当前分钟
s_needle=calendar.get(Calendar.SECOND);//获取当前秒
//时钟的圆盘
g.setColor(Color.white);
//12个大的刻度
for(int i=0;i<12;i++) {
int x1=(int)(192+100*Math.cos(Math.PI/6*i));//在Math.cos,sin方法中,Math.PI等于180°
int y1=(int)(142-100*Math.sin(Math.PI/6*i));
if(i%3!=0)
g.fillRect(x1,y1, 4, 4);
else if(i==3)g.fillRect(x1, y1, 4, 8);
else if(i==6)g.fillRect(x1, y1, 8, 4);
else if(i==9)g.fillRect(x1, y1-8, 4, 8);
else g.fillRect(x1-8, y1, 8, 4);
}
//60个小刻度
for(int i=0;i<60;i++) {
int x1=(int)(192+100*Math.cos(Math.PI/30*i));
int y1=(int)(142-100*Math.sin(Math.PI/30*i));
if(i%5!=0)//与大刻度相重时省略
g.fillRect(x1,y1, 2, 2);
}
//时钟指针
g.setColor(Color.orange);
g.drawLine(192, 142, (int)(192-50*Math.cos(Math.PI/30*h_needle*5+Math.PI/2)), (int)(142-50*Math.sin(Math.PI/30*h_needle*5+Math.PI/2)));//时针指针r设为50
g.setColor(Color.blue);
g.drawLine(192, 142, (int)(192-70*Math.cos(Math.PI/30*m_needle+Math.PI/2)), (int)(142-70*Math.sin(Math.PI/30*m_needle+Math.PI/2)));//分针r设为70
g.setColor(Color.red);
g.drawLine(192, 142, (int)(192-80*Math.cos(Math.PI/30*s_needle+Math.PI/2)), (int)(142-80*Math.sin(Math.PI/30*s_needle+Math.PI/2)));//秒针r设为80
//设置JLabel内容
String h_needle_s,m_needle_s,s_needle_s;
if(h_needle<10) { h_needle_s=0+String.valueOf(h_needle);}//当h_needle即小时值小于10时,在前面加上0,即0x格式
else {h_needle_s=String.valueOf(h_needle);}
if(m_needle<10) { m_needle_s=0+String.valueOf(m_needle);}
else { m_needle_s=String.valueOf(m_needle);}
if(s_needle<10) { s_needle_s=0+String.valueOf(s_needle);}
else { s_needle_s=String.valueOf(s_needle);}
win1.jlabel.setText("<html><body>"+" "+h_needle_s +" : "+m_needle_s+" : "+s_needle_s+"<br>"+calendar.get(Calendar.YEAR)+"年 "+
(calendar.get(Calendar.MONTH)+1)+"月 "+calendar.get(Calendar.DAY_OF_MONTH)+"日"+"<br>"+" <body></html>");
//calendar.get(Calendar.MONTH)方法获得的month是从0开始计数,应+1
//通过 "<html><body>"+s1+"<br>"+s2+"<body></html>",利用"<br>"实现对JLabel中的内容强制换行
}
}
}