基于Java的万年历(课设)

news2024/11/17 14:23:44

基于Java的万年历

资源链接:基于Java的万年历(课设)

文章目录

  • 基于Java的万年历
  • 1 绪论
  • 2 需求分析
  • 3 概要设计
    • 3.1 类间组合框架
    • 3.2 布局结构示意
    • 3.3 对各个类的概述
  • 4运行环境
  • 5 开发工具和编辑语言
  • 6 详细设计
    • 6.1 NiceCaelendar类
    • 6.2 NiceFrame类
    • 6.3 NiceClock类
    • 6.4 NiceMenubar类
    • 6.5 NicePanel类
    • 6.6 NiceBase类
    • 6.7 NiceAlarm类
    • 6.8 NiceTimer类
    • 6.9 NiceLabels类
  • 7 调试分析
    • 7.1 `0:-1:59问题`
    • 7.2 菜单条的颜色问题
    • 7.3 时差问题
    • 7.4 功能补充
  • 8 测试结果
    • 8.1 跳转功能
    • 8.2 换肤功能
    • 8.3 定时功能
    • 8.4 显示关于
  • 9 总结与展望

摘 要

Java编程语言自诞生十几年来,已经成功地运用在网络计算及移动等各个领域。对于开发者来说,它具有简单、面向对象、健壮、安全、结构中立、可移植和高效能等众多优点。此次我们用JAVA来设计一个万年历程序,该程序以网页形式运行,并且支持图形化界面,能以日历的形式显示日期与星期,用户能自己输入日期,支持查找日期,并且能够更新日期,是一个简单易用的小应用。

关键词:JAVA,图形化界面,万年历

1 绪论

Java的前身是Oak,它一开始只是被应用于消费性电子产品中。后来它的开发者们发现它还可以被用于更大范围的Internet上。l995年,Java语言的名字从0ak编程了Java。1997年J2SE1.1发布。1998年J2SE1.2发布,标志Java2的诞生。十多年来,Java编程语言及平台成功地运用在网络计算及移动等各个领域。Java的体系结构由Java语言、Java class、Java API、Java虚拟机组成。它具有简单、面向对象、健壮、安全、结构中立、可移植和高效能等众多优点。Java支持多线程编程,Java运行时系统在多线程同步方面具有成熟的解决方案。Java的平台标准有Java ME,Java SE和Java EE。Java发展到今天,它的卓越成就及在业界的地位毋庸置疑。目前在众多的支持Java的开发工具中主要的7JavaDevelopment Kit,NetBeans,Jcreator,JBuilder,JDeveloper和Eclipse等。其中Java Development Kit简称JDK是大多开发工具的基础。以上的每种开发工具都有优缺点,对于开发者来说,重要的是要根据自己的开发规模、开发内容和软硬件环境等因素来选择一种合适的开发工具。

2 需求分析

对于日期,1、3、5、7、8、10、12月有31天;4、6、9、11月有30天;闰年的2月有29天,平年有28天。每4年一个闰年,每100年一个闰年,每400年一个闰年。根据以上条件,给定任意的年份和月份,便可计算出当月的天数。

对于时间,将表盘分为12等份,每一份对应一小时;将表盘分为60等份,每一份对应一分钟;将表盘分为3600等份,每一份对应一秒钟。

每秒钟分针转过的角度:minute_angle=(minute+second/60)*360/60;

每秒钟时针转过的角度:hour_angle=(hour-12+minute/60)*360/12;

根据以上条件,便可以计算出任意时刻时分秒针在表盘上的具体位置,利用Graphics2D类在面板上绘制即可。

将标签和日期进行关联这样就可以将日期的具体信息显示出来,比如节假日、每日运势、黄道吉日等。

通过调用系统时间,制作一个计时装置,结合窗口和标签实现闹钟的功能。

通过设置时钟、日历、标签等的背景和背景图片可以实现更改界面风格,从而实现换肤功能。

再结合菜单、面板、标签、按钮,做出一个简单实用的可视化图形用户界面。

万年历是一个非常实用的小工具。然而在当代,万年历的功能已经不仅仅局限于看时间、查日期的功能了。为此,本系统加入了更加人性化的换肤功能,以及设置闹钟的功能。让小小的万年历全面接管时间!

3 概要设计

3.1 类间组合框架

为了实现代码复用、降低源程序各个模块内的耦合性以及方便修改源代码,将各个类按照层次自顶向下分层设计。利用对象组合的设计方法,让上层类组合下层类的对象,尽量将功能下沉。

各个类之间的组合关系如图所示:

在这里插入图片描述

图3-1 类之间的组合关系

3.2 布局结构示意

万年历的主框架在一个NiceFrame里,通过继承JFrame而来。包含NiceMenubar、NicePanel、Panel_Left三大模块。

NiceMenuba包含Start、Function、Help三个菜单;当用户点击菜单项的时候,对应的部分会做出反馈并显示在面板上。

Panel_Left上边放NIceClock,下边放NiceLabels;NiceLabels包含三个标签,通过监听日历的点击事件显示内容。

NicePanel使用BorderLayout布局,分为Panel_North、Panel_Center、Panel_South三个部分;Panel_Center负责通过调用NiceBase获得计算出的日历格式,并显示在面板上。

各模块的窗口布局如图所示:

在这里插入图片描述

图3-2 布局示意图

3.3 对各个类的概述

在这里插入图片描述

图3-3 程序UML图

NiceCalendar类,包含程序的入口,对窗口的基本设置,如窗口大小、图标、名称等。

public class NiceCalendar{
NiceFrame NF; 
} 

NiceFrame类,继承JFrame类,是程序的主框架负责窗口的整体布局。

public class NiceFrame extends JFrame{
NiceClock NC; 
  NiceMenubar NM;  
  JPanel Panel_Left;
}

NiceClock类,继承JPanel,实际上是一个面板,通过重载paintComponent方法,利用Graphics2D将时钟绘制在面板上。

class NiceClock extends JPanel{
ImageIcon I; 
NiceClock(ImageIcon I){}
public void paintComponent(GraphicsG){}  
}

NiceMenuBar类,继承了JMenuBar;组合了NiceClock,实现对时钟的换肤功能;实现ActionListener接口,对菜单项进行事件监听。定义的changeSkin方法对全局更改背景颜色。

public class NiceMenubar extends JMenuBar implements ActionListener{
  NicePanel NP;
  NiceClock NC;
NiceMenubar(NiceClock NC){}
public void actionPerformed(ActionEvent e){}
public void changeSkin(Color C){}
}

NiceSkip类,继承JFrame,引用NicePanel,主要功能是在Skip按钮按下后,调用NicePanel的refresh方法刷新日历。

public class NiceSkip extends JFrame implements ActionListener{
   NicePanel NP;
void Skip(NicePanel NP){}
public void actionPerformed(ActionEvent e){}
}

NicePanel类,组合了NiceBase和NiceLabels,负责日历的绘制与刷新,在标签上显示日期、节日、占卜。

pJAublic class NicePanel extends JPanel implements ActionListener {
  NiceBase NB;
  NiceLabels NL;
void refresh(){}
public void actionPerformed(ActionEvent e) {}
}

NiceBase类,提供日历的计算方法,接收指定的年份和月份,并返回一个当月日历的数组。

public class NiceBase{
  //String day[];
  pricate int year;
  private int month;
public void setYear(int year){} 
public int getYear(){}
public void setMonth(int month){}
public int getMonth(){} 
public String[] getCalendar(){}
}

NiceLabels类,包含三个标签,用来显示节日、占卜、闹钟。

public class NiceLabels extends JPanel{ 
Color C;
Random R;
String getTips(){}
void getRemind(int num){}
}

NiceAlarm类,继承JFramen类,是一个弹出窗口,接收TextField输入的时间,并调用NiceTimer类计时。

public class NiceAlarm extends JFrame implements ActionListener{
NiceLabels NL;
}

NiceTimer类,接收时间,根据系统当前时间进行倒计时。

Public class NiceTimer{
  NiceLabels NL; 
  int goalHour;
  int goalMinute;
public void run() {}
}

根据需求分析,能够得出需要哪些功能、哪些类。定义这些类,构建类之间的组合关系,为之后的详细设计奠定基础。系统中各个类都是一个整体,使用组合的方法,当需要使用某个标签、按钮的时候仅仅去调用即可,降低代码的耦合性。

在使用Java的Calendar类获取当前日期的时候,需要进行换算。因为国外的星期的第一天是Sunday,而中国一周的第一天是Monday,这就是文化差异。为了规避差异,需要将Calendar.get(Calendar.DAY_OF_WEEK)-1;还有时差的问题:使用System.currentTimeMillis(); 获取的系统时间解析后得到的时间与我国的时间不一致,这是因为我国所处的时区是东八区,因此需要加上八个时区才可以,这在换算的时候应该考虑到。

4运行环境

Java Development Kit 8

Windows 10

Intel® Core™ i5-10300H

2.50GHz CPU主频

8GB RAM

256GB SSD

5 开发工具和编辑语言

IntelliJ IDEA 2022.1.3

Java

6 详细设计

6.1 NiceCaelendar类

在这里插入图片描述

图6-1 NiceClendar UML图

设置窗口属性,提供程序的入口方法。

public class NiceCalendar{                
  public static void main(String[] args){ //main方法 //程序入口
    NiceFrame NF = new NiceFrame();    //Window//组合
    NF.setBounds(200,200,1200,600);  //设置窗口大小 //1200X600
    Image image =                  // 将图片转换为Image对象        Toolkit.getDefaultToolkit().createImage("logo.jpg"); 
    NF.setIconImage(image);       //设置窗口图标
    NF.setTitle("Nice Calendar");      //title //窗口标题
    NF.setVisible(true); //let the window visible //窗口可见
}; // main结束
} // NiceCalendar类的结束

6.2 NiceFrame类

在这里插入图片描述

图6-2 NiceFrame UML图

JFrame类型的窗口,将窗口分为菜单、左上、左下、右四个部分。菜单放NiceMenuBar;左上放NiceClock;左下放NiceLabels;右放NicePanel。

NiceClock NC = new NiceClock(new ImageIcon("WHITE.jpg")); // 背景
NiceMenubar NM = new NiceMenubar(NC);     // 组合NiceMenu
JPanel Panel_Left = new JPanel(new GridLayout(2, 1));   // 设置布局
/*set layout //设置布局 将面板分成上下两等*/
public NiceFrame(){  // 构造器
setVisible(true);                // 可见
setDefaultCloseOperation(DISPOSE_ON_CLOSE);      // 处理
Panel_Left.add(NC);              // 添加NiceClock
Panel_Left.add(NM.NP.NL);          // 添加NiceLabels
setLayout(new GridLayout(1, 2));           // 设置布局
  setJMenuBar(NM);                  // 添加菜单栏
add(Panel_Left);             // 添加Panel_Left
add(NM.NP);            // 添加NicePanel
 NM.NP.refresh();                  // 显示默认日历
} // 构造函数结束

在这里插入图片描述

图6-3 NiceClock UML图

6.3 NiceClock类

NiceClock类,继承JPanel类,通过重写父类的printComponent方法将表盘绘制在面板上。绘制过程包括:打开抗锯齿、放入背景图片、计算表盘半径、绘制数字、绘制刻度、绘制时针、绘制分针。

public void paintComponent(Graphics G){ //draw components
    Graphics2D G2D = (Graphics2D)G;
    G2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);     //抗锯齿 使指针显示逼真
G2D.setColor(Color.RED); //前景颜色
    G2D.drawImage(I.getImage(),0,0,getWidth(),getHeight(),
I.getImageObserver()); //set background
int x_Width = this.getWidth() / 2; //get the width of panel
    int y_Width = this.getHeight() / 2; //get the height of panel
    int radius = (int) (Math.min(this.getWidth(), this.getHeight()) * 0.8 * 0.5); //calculate the radius of clock
    for(int i = 0; i < 12; i++){ 
      double angle = Math.PI / 180 * i * (360 / 12); 
      int x = (x_Width - 4) + (int)((radius - 12) * Math.cos(angle)); 
      int y = (y_Width + 4) + (int)((radius - 12) * Math.sin(angle)); 
      int j = i + 3;
      if (j > 12) 
        j = j - 12; 
      G2D.drawString(Integer.toString(j), x, y); //add numbers to clock       
    }
       AffineTransform old = G2D.getTransform();    
/*transform 2D coordinates to another*/
    for (int i = 0; i < 60; i++){ 
       int w = i % 5 == 0 ? 6 : 3;  //判断刻度的大小
       G2D.fillRect(x_Width - 2, 28, w, 3);      //绘制刻度
       G2D.rotate(Math.toRadians(6), x_Width, y_Width);
       } // add marks to clock
    G2D.setTransform(old);
    Calendar C = Calendar.getInstance();
    int hour = C.get(Calendar.HOUR_OF_DAY);
    int minute = C.get(Calendar.MINUTE);
    int second = C.get(Calendar.SECOND);

double hour_angle = (hour - 12 + minute / 60d) * 360d / 12d;

G2D.rotate(Math.toRadians(hour_angle), x_Width, y_Width);

int x_hour_array[] = { x_Width, x_Width + 9, x_Width, x_Width - 9 };

 int y_hour_array[] = { 65, y_Width, y_Width + 10, y_Width };

 G2D.drawPolygon(x_hour_array, y_hour_array, x_hour_array.length);//绘制时针

G2D.setTransform(old);
   

double minute_angle = (minute + second / 60d) * 360d / 60d;

 G2D.rotate(Math.toRadians(minute_angle), x_Width, y_Width);

 int x_minute_array[] = { x_Width, x_Width + 6, x_Width, x_Width - 6 };//分针长度

int y_minute_array[] = { 45, y_Width, y_Width + 12, y_Width };     

 G2D.drawPolygon(x_minute_array, y_minute_array, x_minute_array.length);

//绘制分针

 G2D.setTransform(old);

 }

 NiceClock(ImageIcon I){

    this.I = I;      //接收背景图片

  }

6.4 NiceMenubar类

在这里插入图片描述

图6-4 NiceMenubar UML图

NiceMenubar类,负责控制万年历所有的功能。起到承上启下的关键作用。changeSkin方法通过设置各个按钮、标签的背景颜色完成换肤功能。其中,日历中的42个按钮用for循环遍历设置。

public void changeSkin(Color C){    // 设置各种背景
    NP.NL.setBackground(C);
    NP.Button_Current.setBackground(C);
    NP.Button_Current.setBackground(C);
    NP.Button_lastYear.setBackground(C);
    NP.Button_nextYear.setBackground(C);
    NP.Button_lastMonth.setBackground(C);
    NP.Button_nextMonth.setBackground(C);
    NP.Panel_South.setBackground(C);
    NP.Panel_North.setBackground(C);
    NP.Panel_Center.setBackground(C); 
    NP.Label_Year.setBackground(C);
    NP.Label_Month.setBackground(C);
    NP.Label_Calendar.setBackground(C); 
    for(int i = 0; i < 42; i ++){
      NP.Button_Day[i].setBackground(C);
    }

  } // 换肤结束

} // NiceMenubar类结束

6.5 NicePanel类

在这里插入图片描述

图6-5 NicePanel UML图

NicePanel类,用for循环将按钮加入到面板里并设置按钮颜色和字体。refresh方法用来重新获取日历并显示。

NicePanel(){
    setLayout(new BorderLayout());       // 边界布局
    Label_Calendar.setFont(new Font("Arove", 1, 30)); 
    Label_Calendar.setForeground(Color.RED);                          
    Panel_Center.setLayout(new GridLayout(7, 7));   // 布局:7X7网格
    for(int i = 0; i < 7; i++){        // 将week[]添加到面板
      Label_Week[i] = new JLabel(Week[i], JLabel.CENTER);               
      Label_Week[i].setFont(new Font("Arvo", 1, 20));
      Label_Week[i].setForeground(Color.GREEN);
      Label_Week[i].setBackground(NL.C);
      Panel_Center.add(Label_Week[i]);
    }                       
    for(int i = 0; i < 42; i++){       //add day[]添加到面板
      Button_Day[i] = new JButton("None");
      Button_Day[i].setBorder(BorderFactory.createLineBorder(Color.WHITE));
      Panel_Center.add(Button_Day[i]);                    
    } 
}

void refresh(){
    String day[] = NB.getCalendar();
    String month;
    for(int i = 0; i<42; i++){                        
      Button_Day[i].setForeground(Color.CYAN);
      Button_Day[i].setFont(new Font("Arove", 1, 22));
      Button_Day[i].setText(day[i]); 
    }
    switch(NB.getMonth()){
      case 1:month = " 一月 ";break;
      case 2:month = " 二月 ";break;
      case 3:month = " 三月 ";break;
      case 4:month = " 四月 ";break;
      case 5:month = " 五月 ";break;
      case 6:month = " 六月 ";break;
      case 7:month = " 七月 ";break;
      case 8:month = " 八月 ";break;
      case 9:month = " 九月";break;
      case 10:month = " 十月 ";break;
      case 11:month = " 十一月 ";break;
      case 12:month = " 十二月 ";break;
      default:month = " NULL ";
    }
    Label_Year.setText(" "+ NB.getYear() +" ");
    Label_Month.setText(month);
  }

6.6 NiceBase类

在这里插入图片描述

图6-6 NiceBase UML图

NiceBase类,包括设置年月的方法和获取年月的方法以及获取日历按钮数字的方法。

public void setYear(int year){      //设置年份
    if(year < 2119 && year > 1919)           
    this.year = year;                       
 }                          
 public int getYear(){           //返回年份
    return year;                        
 }          
 
 public void setMonth(int month){      //设置月份
    if(month < 0)       
    this.month = month + 12;
    else if(month > 12)   
    this.month = month -12; 
    else
    this.month = month;                  
 }                               
 public int getMonth(){          //返回月份
    return month;
  }                               

  public String[] getCalendar(){       //绘制日历
    String a[] = new String[42];
    Calendar C = Calendar.getInstance();
    C.set(year, month - 1, 1);        //月份以0为基数
    int D = C.get(Calendar.DAY_OF_WEEK)-1;
    
    int day = 0;
    if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12)
      day = 31; // 1 3 5 7 8 10 12他们每月有31天
      
    else if(month == 4||month == 6||month == 9||month == 11)
      day = 30; // 4 6 9 11他们一个月有30天
      
    else if(month == 2){
      if(((year % 4 == 0)&&(year % 100!= 0))||(year % 400 == 0))
        day = 29; // 有时29,否则28
      else
        day = 28; 
    } 
    for(int i = D, n = 1; i < D + day; i++){
      a[i] = String.valueOf(n);
      n++;
    }
    return a;
  }
}

6.7 NiceAlarm类

在这里插入图片描述

图6-7 NiceAlarm UML图

NiceAlarm类,当set按钮被按下时,转到NiceTImer类去执行。

public void actionPerformed(ActionEvent e){
    
    if(e.getSource() == Textfield_H){
      NL.Label_Alarm.setText("Alarm: "+ 
      Textfield_H.getText() +":"+ Textfield_M.getText());
      
    }
    if(e.getSource() == Textfield_M){
      NL.Label_Alarm.setText("Alarm: "+ 
      Textfield_H.getText() +":"+ Textfield_M.getText());
    }
    if(e.getSource() == Button_Set){
      
      this.dispose();
      new NiceTimer(Integer.valueOf(Textfield_H.getText()),
      Integer.valueOf(Textfield_M.getText()), NL).run();
      
    }

  }

6.8 NiceTimer类

在这里插入图片描述

图6-8 NiceTimer UML图

NiceTimer类,run方法每秒获取一次当前时间,并与目标时间计算后得出差值显示到终端。

public void run() {
    int currentSecond;
    int currentMinute;
    int currentHour;
    
    do{
      long currentTime = System.currentTimeMillis();  // 获取当前时间

      currentTime = currentTime / 1000;
      currentSecond = (int) (currentTime % 60);     // 获得第二
      currentTime = currentTime / 60;
      currentMinute = (int) (currentTime % 60);     // 获取分钟
      currentTime = currentTime / 60;   
      currentHour = (int) (currentTime % 24);      // 获取小时数
      
      if (goalMinute-currentMinute > 0)
      System.out.println("闹钟: "+ (goalHour-currentHour) +" : "+
      (goalMinute-currentMinute-1) +" : "+ (59-currentSecond));
      
      try {
        Thread.sleep(1000);        // 系统暂停一秒钟
      }
      catch (InterruptedException e){
        e.toString();
      } 
    }while (goalHour*100+goalMinute > currentHour*100+currentMinute);
    
    NL.Label_Alarm.setText("闹钟:时间到!"); // 时间到

  }

}

6.9 NiceLabels类

在这里插入图片描述

图6-9 NiceLabels UML图

NiceLabels类,主要功能是设置标签内容,getTips()方法和getRemind()方法可以返回对应日期的占卜和节日。

String getTips(){
   int i = R.nextInt(10);
   String S[] = new String[10];
   S[0] = "小贴士:既不好也不坏";
   S[1] = "小贴士:不喝酒/不旅行/不参加葬礼";
   S[2] = "小贴士:参观/贸易/理发/旅行";
   S[3] = "小贴士:禁止砍伐/结婚/洗澡";
   S[4] = "小贴士:不要祈祷/建造/种植";
   S[5] = "小贴士:无所事事/倒霉的一天";
   S[6] = "小贴士:祈祷/结婚/洗澡/旅行";
   S[7] = "小贴士:不结婚/不游泳/装饰";
   S[8] = "小贴士:禁止建造/禁止交易/砍伐树木";
   S[9] = "小贴士:一切顺利";

   return S[i];
}
void getRemind(int num){
   switch(num){
     case 11: Label_Remind.setText("提醒:1月1日元旦");break;
     case 214: Label_Remind.setText("提醒:2月14日情人节");break;
     case 38: Label_Remind.setText("提醒:3月8日妇女节");break;
     case 41: Label_Remind.setText("提醒:4月1日愚人节");break;
     case 422: Label_Remind.setText("提醒:4月22日地球日");break;
     case 51: Label_Remind.setText("提醒:五一劳动节");break;
          case 54: Label_Remind.setText("提醒:五四青年节");break;
          case 57: Label_Remind.setText("提醒:五七回华诞");break;
     case 61: Label_Remind.setText("提醒:6月1日儿童节");break;
     case 71: Label_Remind.setText("提醒:七一建党纪念日");break;
          case 81: Label_Remind.setText("提醒:8月1日建军节");break;
          case 96: Label_Remind.setText("提醒:9月6日我的生日");break;
     case 910: Label_Remind.setText("提醒:9月10日教师节");break;
     case 101: Label_Remind.setText("提醒:10月1日国庆节");break;
     case 1128: Label_Remind.setText("提醒:11月28日感恩节");break;
     case 1224: Label_Remind.setText("提醒:12月24日平安夜");break;
     case 1225: Label_Remind.setText("提醒:12月25日圣诞节");break;
     default: Label_Remind.setText("提醒:NULL");
   }

  }

}

7 调试分析

7.1 0:-1:59问题

在计时器功能里,倒数时间显示在terminal终端,但是在计时结束的时候显示的不是0 : 0 : 0,而是0 : -1 : 59。后来找其中的原因,发现是因为:

计时函数使用的是do-while循环,即先输出计时数字,再判断是否计时结束。这样会导致每次计时都会多输出一秒,也就是0 : 0 : 0的下一秒,0 : -1 : 59。

解决办法是避免最后一轮额外循环的输出,用一个判断语句进行限定:if(goalMinute-currentMinute >= 0){}

在这里插入图片描述

图6-1 0:-1:59问题

在这里插入图片描述

图6-2 修复后的效果

7.2 菜单条的颜色问题

在换肤功能中,功能的实现原理是改变背景颜色。对于标签、按钮来说,使用setBackground()方法即可实现,但是菜单条却不行。虽然菜单条的颜色不是很影响皮肤效果,但是若能该变,显示效果会更好。于是我在网上寻找解决办法,有的说必须重载void paintComponent(Graphics G)方法、有的说可以使用setBackground()但是都不合适,最终有一位网友提到了这个方法,特别有效getComponent().setBackground()于是这个问题就被顺利解决了。

7.3 时差问题

在计时器功能里,为使时间同步,需要调用System.currentTimeMillis()方法获取当前毫秒数,然后对其进行解析,方法如下:

currentTime = currentTime / 1000;

currentSecond = (int) (currentTime % 60);      // 获得第二

currentTime = currentTime / 60;

currentMinute = (int) (currentTime % 60);        // 获取分钟

currentTime = currentTime / 60;   

currentHour = (int) (currentTime % 24);       // 获取小时数

但是,据此得到的小时数却有问题,经过几轮调试后发现,总是与当前时间相差8个小时。后来听过思考,应该是因为北京时间处于东八区,而获取的时间是标准时间。解决办法是将用户输入的时间减去8,换算成标准时间再使用。

7.4 功能补充

如果有时间的话,应当再添加一个可以让用户自定义日期提醒的功能,这样用户就可以添加生日、会议等自定义事项,人机交互更加自由。

还要有登录功能,搭配数据库,可以实时保存用户自定义提醒事项和闹钟的数据。

8 测试结果

8.1 跳转功能

Fuction菜单下有闹钟、跳转、上一年、下一年、上个月、下个月等功能。测试Function菜单下的跳转功能,跳转到2023年10月1日。

在这里插入图片描述

图8-1 跳转前,窗口输入

在这里插入图片描述

图8-2 跳转后,日期改变

8.2 换肤功能

测试菜单下的皮肤功能。

有安静的白色、柔和黄色、纯黑色、黄昏的深色四种皮肤可选,选择黄昏的深色和纯黑色进行测试。

在这里插入图片描述

图8-3 黄昏的深色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SdU5BqAf-1688105247808)(images/image-20230630140039785.png)]

图8-4 纯黑色

8.3 定时功能

测试功能菜单下的闹钟功能。当前时间20:53, 定一个闹钟,20:53提醒。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XgtQTU0z-1688105247809)(images/image-20230630140059539.png)]

图8-5 定时前,窗口输入

在这里插入图片描述

图8-6 运行时,终端显示倒计时

在这里插入图片描述

图8-7 时间到,显示时间到!

8.4 显示关于

帮助菜单提供关于开发者的一些信息。其中自述文件显示软件的使用说明、关于显示开发者的个人信息。

测试帮助菜单下的关于提示

在这里插入图片描述

图8-8 关于开发者

9 总结与展望

通过这次课程设计,加深了我们对面向对象程序设计的理论、方法和基础知识的理解,同时我们也掌握使用Java语言进行面向对象设计的基本方法,并且提高运用面向对象知识分析实际问题、解决实际问题的能力。更进一步地认识到在Java语言中不可以任意实现内部类对外部类中的变量的访问,除非为final型,另外,在编写程序的过程中,对java编译器的使用也是必不可少的,他可以帮助我们更迅速更直观的知道很多的类与对应的方法,如Canlender中的getInstance方法,该方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化,以及大量的add和set方法的使用。在以后的时间里我们会利用课余时间来继续学习Java语言,争取能够较好地掌握它并且能够达到运用自如的境界。这次课程设计,使我对本门课程有了更深一步的理解,《JAVA程序设计》并不是简单的计算机语言,它能够延伸到更宽更广的领域。
资源链接:基于Java的万年历(课设)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享一个优秀的动态数据源开源库-dynamic-datasource-spring-boot-starter

分享一个优秀的动态数据源开源库-dynamic-datasource-spring-boot-starter 1.1 前言1.2 动态数据源开源库简介1.3 特性1.4 用法示例1.4.1 添加依赖1.4.2 配置数据源1.4.3 使用 DS 注解切换数据源 1.5 最佳实践 1.1 前言 在我们的Java后端研发工作中, 有时候由于业务的快速迭代…

Unity 热力图效果实现 笔记

Unity 热力图效果实现 笔记 参考文献连接&#xff1a; 1、人体热力图shader graph实现&#xff08;URP&#xff09; 超链接&#xff1a; https://www.youtube.com/watch?vKlMON4Dzq_0&t51s shader forge 翻译通用管线下 连接点实现方案&#xff1a; 2、碰撞热力图实现…

青岛大学_王卓老师【数据结构与算法】Week03_08_线性表的链式表示和实现8_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–第…

Python打包工具 Pyinstaller使用教程(将.py以及Python解释器和相关库打包可执行文件)

文章目录 pyinstaller历史背景工作原理使用方法简介使用方法详解&#xff08;请仔细阅读help文档中文翻译&#xff09;help文档help文档中文翻译 简单使用示例1. 编译打包2. 拷贝到目标系统3. 运行&#xff08;遇到问题&#xff09; 如何使用xxx.spec文件重新编译配置项示例配置…

千字提炼商业智能BI精髓,言简意赅

商业智能BI的发展和数据的增长有很强的关联性&#xff0c;而当前人工智能、大数据、云计算、物联网、互联网等技术和应用都对数据的增长有促进作用&#xff0c;所以商业智能BI也就伴随着数据的增长&#xff0c;在各行各业的企业中开始发挥作用。 商业智能&#xff08;Business…

uniapp 移动端 后台返回数据流 查看PDF

使用步骤&#xff1a; 1.官网下载地址pdf.js 2.在项目的根目录新建hybrid文件夹&#xff0c;将下载的pdf.js压缩包解压后&#xff0c;复制到hybrid下的html文件夹中 3.在page文件夹下新建一个filePreview.vue页面&#xff0c;页面代码如下&#xff1a; <template><…

C#核心知识回顾——5.结构体和类区别、抽象类和接口、核心知识图解

1.结构体和类区别 结构体和类最大的区别是在存储空间上的&#xff0c;因为结构体是值&#xff0c;类是引用&#xff0c;因此他们的存储位置一个在栈上&#xff0c;一个在堆上。 结构体和类在使用上很类似&#xff0c;结构体甚至可以用面向对象的思想来形容一类对象。 结…

SQL题型:根据逗号拆分列

例1&#xff1a; 表&#xff1a; 要实现的结果&#xff1a; 代码&#xff1a; select a.id as hyId,substring_index(substring_index(a.ch_ry_mc, ,,b.help_topic_id 1 ),,, - 1) AS CH_RY_ID FROM rsgl_hygl_hyxx a JOIN mysql.help_topic b ON b.help_topic_id < ( l…

Acwing.835 Trie字符串统计 (trie数据结构)

题目 维护一个字符串集合&#xff0c;支持两种操作: 1."Ix"向集合中插入一个字符串x; 2."Qx”询问一个字符串在集合中出现了多少次。 共有N个操作&#xff0c;输入的字符串总长度不超过 1 0 5 10^5 105&#xff0c;字符串仅包含小写英文字母。 输入格式 第一…

ChatGPT 和爬虫有什么区别?

ChatGPT是一种基于人工智能的对话模型&#xff0c;它通过训练大量的文本数据来生成自然语言回复。它可以用于实现智能对话系统&#xff0c;能够理解用户的输入并生成相应的回复。ChatGPT的目标是模拟人类对话&#xff0c;使得对话更加流畅和自然。 而爬虫是一种用于自动化地从…

linux 操作系统内核态用户态

1. 32位系统一个进程最多有多少堆内存 对 32 位操作系统而言&#xff0c;它的寻址空间是4G&#xff08;2的32次方&#xff09;&#xff0c;Linux把它分为两部分&#xff1a;最高的1G(虚拟地址从0xC0000000到0xffffffff)用做内核本身&#xff0c;成为“内核空间”&#xff0c;而…

ESP32-C2(8684) AT固件程序

ESP32C2 AT固件使用 ESP32 C2模组&#xff0c;如图1-1所示 图1-1 ESP32 C2模组 ESP32 C2开发板&#xff0c;如图1-2所示 图1-2 ESP32 C2开发 方案亮点 1、完整的 WiFi 子系统&#xff0c;符合 IEEE 802.11b/g/n 协议&#xff0c;具有 Station 模式、SoftAP 模式、SoftAP Stat…

SAP BW/HANA 数据源创建示例

操作实例 在ABAP中创建&#xff1a; 1、RSO2——创建数据源——明明规则&#xff1a;ZZZ/BZ/HY_PP/MM/SD/FI_数据表名 如果表数据中存在货币或者数量关联不是本表需要走RFC提取 根据RFC提取&#xff1a; 函数组—ZBW_GROUP_FI 创建RFC&#xff1a;ZBW_FUN_ZCOT007E 代码&a…

(css)在网页上添加Live 2D网页二次元可动小人

(css)在网页上添加Live 2D网页二次元可动小人 效果&#xff1a; 代码&#xff1a; <script src"js/L2Dwidget.min.js"></script> <script src"js/L2Dwidget.0.min.js"></script> <script>L2Dwidget.init({"model&quo…

git学习使用笔记

一、git组成结构图 工作空间&#xff1a;用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分&#xff0c;从其它计算机克隆仓库时&#xff0c;拷贝的就是这里的数据。本地索引&#xff1a;保存了下次将提交的文件列表信息&#xff0c;一般在 Git 仓库目录中。有…

【三维生成】Make-it-3D:diffusion+NeRF从单张图像生成高保真三维物体(上交微软)

题目: Make-It-3D: High-Fidelity 3D Creation from A Single Image with Diffusion Prior Paper: https://arxiv.org/pdf/2303.14184.pdf Code: https://make-it-3d.github.io/ 文章目录 前言一、方法1.第一阶段 Coarse Stage: Single-view 3D Reconstruction1.参考点的像素损…

制造企业实施MES系统受到的影响因素有哪些?

实施MES系统会遇到哪些影响因素&#xff1f;或者说企业实施MES系统的交付率为什么低&#xff1f; 我觉得关键点在于&#xff1a;在当前MES产品化程度普遍不高的大环境下&#xff0c;对项目及管理软件本身认知过于简单&#xff0c;且缺失有经验行业人才&#xff0c;是当前大部分…

机器学习复习5

机器学习复习 1 - 下面是你在课程中看到的代码&#xff0c;在哪种情况下你会使用二值交叉熵损失函数&#xff1f; model.compile(lossBinaryCrossentropy()) A. 回归任务(预测一个数字的任务) B. BinaryCrossentropy()不应该被用于任何任务 C. 有3个或更多类(类别)的分类任务 D…

力扣题库刷题笔记12--整数转罗马数字

1、题目如下&#xff1a; 2、个人Python代码实现&#xff1a; 3、题解Python代码实现&#xff1a; 与题解的差异主要在字典的设计以及题解第22行取余赋值的代码实现&#xff08;个人是使用转换成字符串&#xff0c;然后根据位数确定对应字符&#xff0c;相对来讲笨比了许多&…

【业务功能篇36】Springboot+activiti7 工作流引擎

业务场景&#xff1a;前段时间总结的有一个告警工单流程&#xff0c;我们都是直接自己建表&#xff0c;状态节点&#xff0c;操作节点&#xff0c;都是自定义设计的&#xff0c;而到后面会有很多的工单流程&#xff0c;比如创建一个遗留问题电子流&#xff0c;指定处理人进行分…