0.前言
这几天努力往下读java,java还是蛮有趣的。分享一个图形类的案例:绘制静止的时钟,之后我使用了比较愚蠢的方法让时钟动起来,如果明天不想休息的话,会使用监听器的方式改写一下。代码总体比较简单,就懒得写注释了,反正也是书上的案例。此外,MessagePannel类也一并附上。
1.TestStillClock类(主函数入口)
import javax.swing.*;
import java.awt.*;
public class TestStillClock extends JFrame {
public StillClock clock;
MessagePanel message;
public TestStillClock()
{
setLayout(new BorderLayout());
clock = new StillClock();
message = new MessagePanel(clock.getHour()+":"+clock.getMin()+":"+clock.getSec());
message.setCentered(true);
message.SetTransit(0,10);
message.setForeground(Color.BLUE);
message.setFont(new Font("Courier",Font.BOLD,16));
add(clock);
add(message,BorderLayout.SOUTH);
}
public void renew()
{
clock.setCurrentTime();
message.setMessage(clock.getHour()+":"+clock.getMin()+":"+clock.getSec());
}
public static void main(String[] args) {
//为什么可以随窗口大小改变是因为我们从窗口得到长宽
TestStillClock frame = new TestStillClock();
frame.setTitle("DisplayClock");
frame.setSize(300,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
while(true )
{
frame.renew();
}
}
}
2.MessagePanel类
import javax.swing.*;
import java.awt.*;
public class MessagePanel extends JPanel {
private String message = "Welcome to Java";
private int xCoordinate = 20;
private int yCoordinate = 20;
private boolean centered;
private int interval=10;
private int xTran=0;
private int yTran=0;
public MessagePanel(){};
public MessagePanel(String m){
this.message = m;
}
public String getMessage() {
return message;
}
public void setMessage(String m)
{
this.message=m;
repaint();
}
public int getxCoordinate(){
return xCoordinate;
}
public void setxCoordinate(int x){
this.xCoordinate=x;
repaint();
}
public int getyCoordinate(){
return yCoordinate;
}
public void setyCoordinate(int y){
this.yCoordinate=y;
repaint();
}
public boolean isCentered()
{
return centered;
}
public void setCentered(boolean f)
{
this.centered=f;
repaint();
}
public int getInterval(){
return interval;
}
public void setInterval(int i)
{
this.interval = i;
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(centered)
{
FontMetrics fm = g.getFontMetrics();
int sw = fm.stringWidth(message);
int sa = fm.getAscent();
xCoordinate = getWidth()/2-sw/2+xTran;
yCoordinate = getHeight()/2-sa/2+yTran;
}
g.drawString(message,xCoordinate,yCoordinate);
}
public void SetTransit(int x,int y)
{
xTran=x;
yTran=y;
}
public void moveLeft()
{
xCoordinate-=interval;
repaint();
}
public void moveRight()
{
xCoordinate+=interval;
repaint();
}
public void moveUp()
{
yCoordinate-=interval;
repaint();
}
public void moveDown(){
yCoordinate+=interval;
repaint();
}
public void move(int x,int y)
{
xCoordinate+=x;
yCoordinate+=y;
repaint();
}
public Dimension getPreferredSize()
{
return new Dimension(200,30);
}
}
3.StillClock类
import javax.swing.*;
import java.awt.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class StillClock extends JPanel {
private int hour;
private int min;
private int sec;
public StillClock(){
setCurrentTime();
}
public StillClock(int h,int m,int s)
{
hour=h;
min=m;
sec=s;
}
public int getHour(){
return hour;
}
public int getMin(){
return min;
}
public int getSec(){
return sec;
}
public void setHour(int h){
hour=h;
repaint();
}
public void setMin(int m)
{
min=m;
repaint();
}
public void setSec(int s)
{
sec=s;
repaint();
}
public void setCurrentTime(){
Calendar calendar = new GregorianCalendar();
hour = calendar.get(Calendar.HOUR_OF_DAY);
min = calendar.get(Calendar.MINUTE);
sec = calendar.get(Calendar.SECOND);
repaint();
}
public 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;
//DrawCircle
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);
//Draw second hand
int sLength = (int)(clockRadius*0.8);
int xSecond = (int)(xCenter+sLength*Math.sin(sec*(2*Math.PI/60)));
int ySecond = (int)(yCenter-sLength*Math.cos(sec*(2*Math.PI/60)));
g.setColor(Color.RED);
g.drawLine(xCenter,yCenter,xSecond,ySecond);
//Draw min hand
int mLength = (int)(clockRadius*0.65);
int xMin = (int)(xCenter+mLength*Math.sin((min+sec/60.0)*(2*Math.PI/60)));
int yMin = (int)(yCenter-mLength*Math.cos((min+sec/60.0)*(2*Math.PI/60)));
g.setColor(Color.BLUE);
g.drawLine(xCenter,yCenter,xMin,yMin);
//Draw hour sec
int hLength = (int)(clockRadius*0.5);
int xHour = (int)(xCenter+hLength*Math.sin((hour%12+min/60.0)*(2*Math.PI/12)));
int yHour = (int)(yCenter-hLength*Math.cos((hour%12+min/60.0)*(2*Math.PI/12)));
g.setColor(Color.GREEN);
g.drawLine(xCenter,yCenter,xHour,yHour);
}
public Dimension getPreferredSize()
{
return new Dimension(200,200);
}
}
4.监听器的改进
很简单的使用Timer并添加监听器进行改进。仅有主函数更新,其余不变。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestAnimationClock extends JFrame {
public StillClock clock;
MessagePanel message;
public TestAnimationClock()
{
setLayout(new BorderLayout());
clock = new StillClock();
message = new MessagePanel(clock.getHour()+":"+clock.getMin()+":"+clock.getSec());
message.setCentered(true);
message.SetTransit(0,10);
message.setForeground(Color.BLUE);
message.setFont(new Font("Courier",Font.BOLD,16));
add(clock);
add(message,BorderLayout.SOUTH);
Timer timer = new Timer(250,new TimerListener());
timer.start();
}
private class TimerListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
clock.setCurrentTime();
clock.repaint();
message.setMessage(clock.getHour()+":"+clock.getMin()+":"+clock.getSec());
message.repaint();
}
}
public static void main(String[] args) {
//为什么可以随窗口大小改变是因为我们从窗口得到长宽
TestAnimationClock frame = new TestAnimationClock();
frame.setTitle("DisplayClock");
frame.setSize(300,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
5.效果图与碎碎念

本来想用Java重新写一下之前的图片浏览器权当练手的,但是被Java的布局管理器搞的头昏脑涨,现在虽然壳子搭完了但是已经没有写的欲望了。
如此想想,还是python的Tkinter好用,简单清晰。
ps:最近又开始玩法环了,呜呜呜,我的梅琳娜。