欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java設(shè)計日歷可視化的詳細(xì)步驟記錄

 更新時間:2024年12月24日 09:01:26   作者:筱姌  
這篇文章主要給大家介紹了關(guān)于java設(shè)計日歷可視化的相關(guān)資料,通過自定義的CircleLabel類來突出顯示今天的日期,并使用BorderLayout布局管理窗口組件,文章詳細(xì)描述了各個類和方法的設(shè)計思想和實現(xiàn)邏輯,需要的朋友可以參考下

設(shè)計目標(biāo)

設(shè)計的這個日歷既可以捕捉當(dāng)天的日期,并且使用紅色圓圈圈起來以及實時具體時間,而且將月份和年份設(shè)計了下拉框,可以自行選擇具體的月份年份,也可以通過<和>兩個按鍵實現(xiàn)對月份的轉(zhuǎn)變,同時年份和月份的顯示會隨著按鍵轉(zhuǎn)變而轉(zhuǎn)變,本月日期用黑色標(biāo)記清楚,其他月份日期用灰色標(biāo)出。

實現(xiàn)功能

一、日歷展示功能

  • 可視化日歷:創(chuàng)建一個可視化的日歷窗口,展示特定月份的日歷布局,包括星期幾的標(biāo)題行和日期格子。
  • 月份切換:通過 “<” 和 “>” 按鈕可以切換到上一個月或下一個月的日歷。同時,也可以通過年和月的下拉框選擇特定的年份和月份來顯示相應(yīng)的日歷。
  • 突出顯示今天:在日歷中,用紅色圓形突出顯示當(dāng)天的日期,方便用戶快速識別。
  • 顯示月份名稱:在窗口頂部顯示當(dāng)前月份的中文名稱,如 “一月”“二月” 等。
  • 日期范圍調(diào)整:對于當(dāng)前月份之前的日期(上一個月的日期),以灰色字體顯示在日歷的開頭部分;對于當(dāng)前月份之后的日期(下一個月的占位符),也以灰色字體顯示在日歷的結(jié)尾部分。

二、年份選擇功能

年下拉框:創(chuàng)建一個包含當(dāng)前年份前后各 20 年的年份下拉框,用戶可以從下拉框中選擇特定的年份,選擇后會自動更新顯示相應(yīng)年份的日歷。

三、月份選擇功能

月下拉框:創(chuàng)建一個包含十二個中文月份名稱的下拉框,用戶可以選擇不同的月份來顯示對應(yīng)月份的日歷。

四、實時時間顯示功能

時間更新:使用定時器每秒鐘更新一次窗口標(biāo)題,顯示當(dāng)前的時間,格式為 “yyyy-MM-dd HH:mm:ss”,并帶有時區(qū)設(shè)置為 “GMT+8”。

五、窗口布局和定位功能

  • 窗口布局:使用BorderLayout布局將窗口分為頂部和中央兩部分,頂部放置年、月下拉框、按鈕和年份標(biāo)簽,中央放置日歷面板。
  • 窗口定位:在程序啟動時,自動計算窗口在屏幕中的位置,使其居中顯示。

設(shè)計類的思想

  • 可視化日歷應(yīng)用:CalendarMain類旨在創(chuàng)建一個可視化的日歷應(yīng)用程序,提供用戶交互功能,允許用戶通過年、月下拉框和按鈕切換不同的月份和年份,同時實時顯示當(dāng)前時間。
  • 模塊化設(shè)計:將不同的功能模塊分離,如年、月下拉框的創(chuàng)建和事件處理、日歷面板的生成、時間更新等分別封裝在不同的方法中,提高代碼的可讀性和可維護(hù)性。
  • 用戶交互性:通過提供直觀的用戶界面,包括按鈕和下拉框,使用戶能夠方便地瀏覽不同的日期。同時,通過自定義的圓形標(biāo)簽突出顯示今天的日期,增強(qiáng)用戶體驗。

CalendarMain 類

整體設(shè)計目標(biāo)

CalendarMain 類的主要目標(biāo)是創(chuàng)建一個具有圖形用戶界面(GUI)的日歷應(yīng)用程序。它允許用戶查看指定月份和年份的日歷信息,能夠切換月份,并且在窗口標(biāo)題中實時顯示當(dāng)前時間。

成員變量設(shè)計思想

  • monthLabel:用于直觀地向用戶展示當(dāng)前所查看日歷的月份信息。通過 JLabel 來實現(xiàn),初始化為特定的月份字符串(如 "October 2023"),后續(xù)會根據(jù)用戶的操作(如切換月份)動態(tài)更新其顯示內(nèi)容。
  • yearLabel:與 monthLabel 類似,用于顯示當(dāng)前年份。同樣是 JLabel 類型,其顯示內(nèi)容會隨著用戶在年下拉框中的選擇或月份切換等操作而更新。
  • calendarPanel:這是整個日歷應(yīng)用程序的核心顯示區(qū)域,通過 JPanel 實現(xiàn),并設(shè)置為 GridLayout(7, 7) 的網(wǎng)格布局。該布局用于以一種規(guī)則的方式展示日歷中的星期標(biāo)題以及每個月的日期信息等內(nèi)容。
  • currentMonth 和 currentYear:分別用于記錄當(dāng)前所顯示日歷的月份索引(0 - 11 分別對應(yīng)一月到十二月)和年份信息。這兩個變量在程序運(yùn)行過程中會根據(jù)用戶的操作(如切換月份、選擇年份)不斷更新,以便準(zhǔn)確顯示相應(yīng)的日歷內(nèi)容。
  • currentTime:用于存儲當(dāng)前時間的字符串表示。通過定時器定期更新這個變量的值,并將其用于更新窗口標(biāo)題,以實現(xiàn)實時顯示當(dāng)前時間的功能。
  • yearComboBox 和 yearComboBox:這兩個下拉框組件分別用于用戶選擇年份和月份。yearComboBox 包含了從當(dāng)前年份前后各 20 年的年份選項,方便用戶在較大時間范圍內(nèi)選擇想要查看日歷的年份。monthComboBox 則包含了中文月份名稱數(shù)組中的各個月份名稱,使用戶能夠以更直觀的方式選擇月份。

構(gòu)造函數(shù)設(shè)計思想

  • 在 CalendarMain 的構(gòu)造函數(shù)中,首先進(jìn)行了一系列窗口基本設(shè)置:
    • 創(chuàng)建并初始化 monthLabel 和 yearLabel,設(shè)置窗口標(biāo)題、大小以及關(guān)閉操作等,為整個應(yīng)用程序的窗口外觀和基本行為奠定基礎(chǔ)。
    • 設(shè)置窗口布局為 BorderLayout,這種布局方式便于將不同功能的組件放置在窗口的不同區(qū)域(如頂部、中央等),使得界面布局更加清晰和有條理。
    • 通過獲取屏幕尺寸并計算,將窗口設(shè)置為在屏幕居中顯示,提供更好的用戶體驗。
  • 接著,獲取當(dāng)前時間的日歷對象,并從中提取當(dāng)前月份索引和年份信息,用于初始化 currentMonth 和 currentYear 變量,確保應(yīng)用程序一開始顯示的是當(dāng)前時間對應(yīng)的日歷信息。
  • 然后,分別創(chuàng)建并設(shè)置年下拉框和月下拉框:
    • 對于年下拉框 yearComboBox,通過循環(huán)添加從當(dāng)前年份前后各 20 年的年份選項,設(shè)置初始選中項為當(dāng)前年份,并為其添加動作監(jiān)聽器。當(dāng)用戶選擇不同年份時,監(jiān)聽器會觸發(fā)相應(yīng)的操作,更新 currentYear 變量并重新顯示日歷內(nèi)容。
    • 對于月下拉框 monthComboBox,創(chuàng)建包含中文月份名稱的數(shù)組,并將各個月份名稱添加到下拉框中,設(shè)置初始選中項為當(dāng)前月份對應(yīng)的中文名稱。同樣為其添加動作監(jiān)聽器,當(dāng)用戶選擇不同月份時,監(jiān)聽器會觸發(fā)更新 currentMonth 變量并重新顯示日歷的操作。
  • 之后,創(chuàng)建頂部面板 topPanel,并設(shè)置其布局為 FlowLayout,用于放置上一個月按鈕、年下拉框、月下拉框、年份標(biāo)簽以及下一個月按鈕等組件。為上一個月按鈕和下一個月按鈕分別添加動作監(jiān)聽器,點(diǎn)擊按鈕時會調(diào)用 changeMonth 方法來實現(xiàn)月份的切換操作。
  • 最后,創(chuàng)建用于顯示日歷內(nèi)容的 calendarPanel,將其添加到窗口的中央?yún)^(qū)域,并調(diào)用 displayCalendar 方法首次顯示日歷內(nèi)容。同時,創(chuàng)建一個定時器,每 1000 毫秒(1 秒)觸發(fā)一次 updateTime 方法,用于更新窗口標(biāo)題顯示的時間。

CircleLabel 類(內(nèi)部靜態(tài)類)

整體設(shè)計目標(biāo)

CircleLabel 類是一個自定義的標(biāo)簽類,繼承自 JLabel。其主要設(shè)計目標(biāo)是在日歷應(yīng)用程序中,針對表示當(dāng)天日期的標(biāo)簽進(jìn)行特殊繪制,使其呈現(xiàn)出圓形邊框的效果,以便用戶能夠更直觀地識別當(dāng)天日期。

成員變量設(shè)計思想

  • isToday:這個布爾類型的變量用于標(biāo)記該標(biāo)簽所表示的日期是否為今天。通過這個變量,在繪制標(biāo)簽時可以根據(jù)其值來決定是否繪制紅色圓形邊框,從而實現(xiàn)對今天日期的特殊標(biāo)識。

構(gòu)造函數(shù)設(shè)計思想

  • 在構(gòu)造函數(shù) CircleLabel(String text, boolean isToday) 中:
    • 首先調(diào)用父類 JLabel 的構(gòu)造函數(shù),設(shè)置文本居中顯示,確保日期文本在標(biāo)簽內(nèi)的顯示效果良好。
    • 然后初始化 isToday 變量,將傳入的參數(shù)值賦給它,以便后續(xù)繪制操作能夠根據(jù)這個值進(jìn)行相應(yīng)的處理。
    • 最后設(shè)置標(biāo)簽的字體為 Arial,普通樣式,字號為 20,統(tǒng)一了日期標(biāo)簽的字體格式,使整個日歷的顯示更加規(guī)范和美觀。

paintComponent 方法設(shè)計思想

  • 該方法重寫了父類 JLabel 的 paintComponent 方法。
  • 首先,調(diào)用父類的 paintComponent 方法進(jìn)行默認(rèn)繪制,保證標(biāo)簽的基本顯示內(nèi)容(如日期文本)能夠正常顯示。
  • 然后,根據(jù) isToday 變量的值來決定是否進(jìn)行特殊繪制:如果 isToday 為 true,則將繪制圖形的上下文轉(zhuǎn)換為 Graphics2D,并設(shè)置抗鋸齒渲染提示,使繪制的圓形更平滑。接著,通過獲取標(biāo)簽的寬度和高度,計算出合適的圓形直徑以及圓心坐標(biāo),設(shè)置繪制顏色為紅色,最后繪制出紅色圓形邊框,從而實現(xiàn)了對今天日期的特殊標(biāo)識效果。

displayCalendar 方法設(shè)計思想

  • 該方法的主要目的是根據(jù)當(dāng)前的 currentYear 和 currentMonth 變量的值,準(zhǔn)確地在 calendarPanel 上顯示相應(yīng)月份的日歷信息。
  • 首先,清除 calendarPanel 上的所有組件,為重新顯示新的日歷內(nèi)容做好準(zhǔn)備。
  • 然后,創(chuàng)建當(dāng)前月份的日歷對象和上一個月的日歷對象,用于獲取相關(guān)的日歷信息,如當(dāng)前月的第一天是星期幾、當(dāng)前月和上一個月的總天數(shù)等。
  • 接著,更新 monthLabel 和 yearLabel 的顯示內(nèi)容,使其準(zhǔn)確反映當(dāng)前所查看的月份和年份信息。
  • 之后,添加星期標(biāo)題行,通過循環(huán)將星期的中文簡稱(如 “一”、“二” 等)添加到 calendarPanel 上作為日歷的標(biāo)題行。
  • 再根據(jù)獲取到的當(dāng)前月的第一天是星期幾以及當(dāng)前月和上一個月的總天數(shù)等信息,分三步添加日歷中的日期信息:
    • 添加上一個月的空白日期(灰色顯示):通過循環(huán),根據(jù)當(dāng)前月第一天是星期幾的信息,計算出需要添加上一個月的哪些空白日期,并將這些日期以灰色顯示的方式添加到 calendarPanel 上。
    • 添加當(dāng)前月的日期:通過循環(huán)遍歷當(dāng)前月的所有日期,對于每個日期,判斷其是否為今天,如果是則使用 CircleLabel 類創(chuàng)建帶有圓形邊框標(biāo)識的標(biāo)簽,否則使用普通的 JLabel 創(chuàng)建標(biāo)簽,然后將這些標(biāo)簽添加到 calendarPanel 上。
    • 填充后續(xù)的空白日期(灰色顯示):根據(jù)日歷布局的規(guī)則以及當(dāng)前月的總天數(shù)和第一天是星期幾等信息,計算出需要填充的后續(xù)空白日期,并將這些日期以灰色顯示的方式添加到 calendarPanel 上。
  • 最后,重新驗證和重繪 calendarPanel,確保新添加的組件能夠正確顯示在窗口中,并且顯示效果良好。

changeMonth 方法設(shè)計思想

  • 該方法用于實現(xiàn)月份的切換功能。當(dāng)用戶點(diǎn)擊上一個月按鈕或下一個月按鈕時,會傳入正負(fù) 1 的參數(shù)值來表示切換到上一個月或下一個月。
  • 根據(jù)傳入的參數(shù)值對 currentMonth 變量進(jìn)行相應(yīng)的調(diào)整:如果 currentMonth 小于 0,說明要切換到上一年的 12 月份,此時將 currentMonth 設(shè)為 11,同時將 currentYear 減 1;如果 currentMonth 大于 11,說明要切換到下一年的 1 月份,此時將 currentMonth 設(shè)為 0,同時將 currentYear 增 1。
  • 然后,更新年下拉框和月下拉框的選中項,使其與新的 currentYear 和 currentMonth 相匹配。
  • 最后,調(diào)用 displayCalendar 方法重新顯示日歷內(nèi)容,以反映出月份切換后的新情況。

main 方法設(shè)計思想

  • 在 main 方法中,使用 SwingUtilities.invokeLater 方法來確保在事件分發(fā)線程(EDT)中創(chuàng)建和顯示窗口。這是因為 Swing 組件必須在 EDT 中進(jìn)行創(chuàng)建和操作,以避免出現(xiàn)線程相關(guān)的問題。
  • 在 invokeLater 方法內(nèi)部,創(chuàng)建了 CalendarMain 類的一個實例,并設(shè)置其可見,從而啟動了整個日歷應(yīng)用程序,使得用戶可以通過圖形界面查看日歷信息、切換月份以及看到實時更新的時間顯示。

updateTime 方法設(shè)計思想

  • 該方法的主要目的是更新窗口標(biāo)題顯示的時間。
  • 首先,創(chuàng)建一個 SimpleDateFormat 格式器,設(shè)置其格式為 "yyyy-MM-dd HH:mm:ss",并將其時區(qū)設(shè)置為 "GMT+8"(東八區(qū),符合中國等多數(shù)地區(qū)的時間標(biāo)準(zhǔn))。
  • 然后,通過調(diào)用 SimpleDateFormat 的 format 方法,將當(dāng)前日期和時間(通過 new java.util.Date() 獲?。└袷交癁橹付ǜ袷降淖址⑵浯鎯Φ?nbsp;currentTime 變量中。
  • 最后,將窗口標(biāo)題更新為 "日歷" + currentTime,實現(xiàn)了在窗口標(biāo)題中實時顯示當(dāng)前時間的功能。

getMonthName 方法設(shè)計思想

  • 該方法的主要目的是根據(jù)月份索引(0 - 11)獲取對應(yīng)的中文月份名稱。
  • 通過創(chuàng)建一個包含中文月份名稱的數(shù)組,然后根據(jù)傳入的月份索引從數(shù)組中獲取相應(yīng)的中文月份名稱并返回,為在其他方法(如 changeMonth 方法中更新月下拉框選中項)中提供了方便的獲取中文月份名稱的方式。

設(shè)計原理

.窗口布局和組件創(chuàng)建:

  • 使用JFrame作為主窗口,設(shè)置標(biāo)題、大小、關(guān)閉操作和布局。通過BorderLayout布局將窗口分為頂部和中央兩部分,頂部放置年、月下拉框和按鈕,中央放置日歷面板。
  • 創(chuàng)建JLabel作為月份和年份標(biāo)簽,以及JPanel作為頂部面板和日歷面板。使用FlowLayout布局管理頂部面板,GridLayout布局管理日歷面板。
  • 創(chuàng)建年、月下拉框,并添加相應(yīng)的動作監(jiān)聽器,以便在用戶選擇不同的年份和月份時更新日歷顯示。

2.日歷生成:

  • 使用GregorianCalendar類獲取當(dāng)前時間和特定月份的日歷信息。通過計算當(dāng)前月的第一天是星期幾以及該月的總天數(shù),生成日歷的布局。
  • 對于上一個月和下一個月的空白日期,使用灰色字體顯示上一個月的日期或下一個月的占位符。對于當(dāng)前月的日期,使用自定義的圓形標(biāo)簽突出顯示今天的日期。

3.用戶交互和時間更新:

  • 為上一個月和下一個月按鈕添加動作監(jiān)聽器,實現(xiàn)月份的切換功能。在切換月份時,更新當(dāng)前月份和年份,并重新顯示日歷。
  • 使用Timer類創(chuàng)建定時器,每秒鐘觸發(fā)一次時間更新操作,更新窗口標(biāo)題顯示的當(dāng)前時間。

功能實現(xiàn)

設(shè)計源碼

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.awt.RenderingHints;

// 定義主類 CalendarMain,繼承自 JFrame 以創(chuàng)建可視化窗口
public class CalendarMain extends JFrame {
    // 月份標(biāo)簽,用于顯示當(dāng)前月份
    private final JLabel monthLabel;
    // 年份標(biāo)簽,用于顯示當(dāng)前年份
    private final JLabel yearLabel;
    // 日歷面板,用于顯示日歷內(nèi)容
    private final JPanel calendarPanel;
    // 當(dāng)前月份的索引
    private int currentMonth;
    // 當(dāng)前年份
    private int currentYear;
    // 當(dāng)前時間的字符串表示
    private static String currentTime;

    // 年下拉框組件
    private JComboBox<Integer> yearComboBox;
    // 月下拉框組件
    private JComboBox<String> monthComboBox;

    public CalendarMain() {
        // 創(chuàng)建月份標(biāo)簽,初始顯示為 "October 2023"
        monthLabel = new JLabel("October 2023");
        // 設(shè)置窗口標(biāo)題為 "日歷"
        setTitle("日歷");
        // 設(shè)置窗口大小為 500x450 像素
        setSize(500, 450);
        // 設(shè)置窗口關(guān)閉操作,當(dāng)關(guān)閉窗口時退出程序
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 設(shè)置窗口布局為 BorderLayout(邊框布局)
        setLayout(new BorderLayout());

        // 獲取屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int screenWidth = screenSize.width;
        int screenHeight = screenSize.height;
        // 計算窗口在屏幕中的位置,使其居中顯示
        int x = (screenWidth - getWidth()) / 2;
        int y = (screenHeight - getHeight()) / 2;
        setLocation(x, y);

        // 獲取當(dāng)前時間的日歷對象
        Calendar calendar = new GregorianCalendar();
        // 獲取當(dāng)前月份的索引
        currentMonth = calendar.get(Calendar.MONTH);
        // 獲取當(dāng)前年份
        currentYear = calendar.get(Calendar.YEAR);

        // 創(chuàng)建年下拉框
        yearComboBox = new JComboBox<>();
        // 循環(huán)添加從當(dāng)前年份前后各 20 年的年份選項到年下拉框
        for (int i = currentYear - 20; i <= currentYear + 20; i++) {
            yearComboBox.addItem(i);
        }
        // 設(shè)置年下拉框的初始選中項為當(dāng)前年份
        yearComboBox.setSelectedItem(currentYear);
        // 為年下拉框添加動作監(jiān)聽器,當(dāng)選擇年份變化時更新當(dāng)前年份并重新顯示日歷
        yearComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                currentYear = (Integer) yearComboBox.getSelectedItem();
                displayCalendar();
            }
        });

        // 創(chuàng)建月下拉框
        monthComboBox = new JComboBox<>();
        // 創(chuàng)建包含中文月份名稱的數(shù)組
        String[] monthNames = new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
        // 循環(huán)添加中文月份名稱到月下拉框
        for (int i = 0; i < 12; i++) {
            monthComboBox.addItem(monthNames[i]);
        }
        // 設(shè)置月下拉框的初始選中項為當(dāng)前月份對應(yīng)的中文名稱
        monthComboBox.setSelectedItem(monthNames[currentMonth]);
        // 為月下拉框添加動作監(jiān)聽器,當(dāng)選擇月份變化時更新當(dāng)前月份并重新顯示日歷
        monthComboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                currentMonth = monthComboBox.getSelectedIndex();
                displayCalendar();
            }
        });

        // 創(chuàng)建頂部面板,用于放置年、月下拉框和按鈕等
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new FlowLayout());

        // 創(chuàng)建上一個月按鈕,點(diǎn)擊時調(diào)用 changeMonth(-1) 方法切換到上一個月
        JButton prevButton = new JButton("<");
        prevButton.addActionListener(e -> changeMonth(-1));
        topPanel.add(prevButton);

        // 將年下拉框添加到頂部面板
        topPanel.add(yearComboBox);
        // 將月下拉框添加到頂部面板
        topPanel.add(monthComboBox);

        // 創(chuàng)建年份標(biāo)簽(這里暫時保留原有的年份標(biāo)簽顯示方式)
        yearLabel = new JLabel();
        topPanel.add(yearLabel);

        // 創(chuàng)建下一個月按鈕,點(diǎn)擊時調(diào)用 changeMonth(1) 方法切換到下一個月
        JButton nextButton = new JButton(">");
        nextButton.addActionListener(e -> changeMonth(1));
        topPanel.add(nextButton);

        // 將頂部面板添加到窗口的北側(cè)(BorderLayout.NORTH)
        add(topPanel, BorderLayout.NORTH);

        // 創(chuàng)建一個 6 行 7 列的網(wǎng)格布局的面板,用于顯示日歷內(nèi)容
        calendarPanel = new JPanel(new GridLayout(7, 7));
        // 將日歷面板添加到窗口的中央(BorderLayout.CENTER)
        add(calendarPanel, BorderLayout.CENTER);

        // 顯示日歷內(nèi)容
        displayCalendar();
        // 創(chuàng)建一個定時器,每 1000 毫秒(1 秒)觸發(fā)一次更新時間的操作
        Timer timer = new Timer(1000, this::updateTime);
        timer.start();
    }

    // 自定義的圓形標(biāo)簽類,繼承自 JLabel
    private static class CircleLabel extends JLabel {
        // 表示是否為今天的標(biāo)志
        private boolean isToday;

        public CircleLabel(String text, boolean isToday) {
            // 調(diào)用父類構(gòu)造方法,設(shè)置文本居中顯示
            super(text, SwingConstants.CENTER);
            this.isToday = isToday;
            // 設(shè)置字體為 Arial,普通樣式,字號為 20
            setFont(new Font("Arial", Font.PLAIN, 20));
        }

        @Override
        protected void paintComponent(Graphics g) {
            // 調(diào)用父類的 paintComponent 方法進(jìn)行默認(rèn)繪制
            super.paintComponent(g);
            // 如果是今天,則繪制紅色圓形
            if (isToday) {
                Graphics2D g2d = (Graphics2D) g;
                // 設(shè)置抗鋸齒渲染提示,使繪制的圓形更平滑
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                int width = getWidth();
                int height = getHeight();
                int diameter = Math.min(width, height);
                int x = (width - diameter) / 2;
                int y = (height - diameter) / 2;

                // 設(shè)置繪制顏色為紅色
                g2d.setColor(Color.RED);
                // 繪制圓形
                g2d.drawOval(x, y, diameter, diameter);
            }
        }
    }

    private void displayCalendar() {
        // 清除日歷面板上的所有組件
        calendarPanel.removeAll();

        // 創(chuàng)建當(dāng)前月份的日歷對象
        Calendar calendar = new GregorianCalendar(currentYear, currentMonth, 1);
        // 創(chuàng)建上一個月的日歷對象
        Calendar prevMonth = new GregorianCalendar();
        if (currentMonth == 0) {
            // 如果當(dāng)前月份是一月,則上一個月為去年的十二月
            prevMonth.set(currentYear - 1, 11, 1);
        } else {
            // 否則,上一個月為當(dāng)前月份減一
            prevMonth.set(currentYear, currentMonth - 1, 1);
        }

        // 更新月份標(biāo)簽為當(dāng)前月份的長名稱
        monthLabel.setText(calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, getLocale()));
        // 更新年份標(biāo)簽為當(dāng)前年份
        yearLabel.setText(String.valueOf(currentYear));

        // 添加星期標(biāo)題行
        String[] days = {"一", "二", "三", "四", "五", "六", "天"};
        for (String day : days) {
            // 創(chuàng)建星期標(biāo)題標(biāo)簽并添加到日歷面板
            calendarPanel.add(new JLabel(day, SwingConstants.CENTER));
        }

        // 獲取當(dāng)前月的第一天是星期幾(星期日為 1,星期六為 7)
        int startDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (startDay == 0) startDay = 7;
        // 獲取當(dāng)前月的總天數(shù)
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        // 獲取上一個月的總天數(shù)
        int prevDaysInMonth = prevMonth.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 獲取當(dāng)前日期的日歷對象
        Calendar todayCalendar = new GregorianCalendar();
        int todayDay = todayCalendar.get(Calendar.DAY_OF_MONTH);
        int todayMonth = todayCalendar.get(Calendar.MONTH);
        int todayYear = todayCalendar.get(Calendar.YEAR);

        // 添加上一個月的空白日期(灰色顯示)
        for (int i = startDay - 1; i >= 1; i--) {
            JLabel label = new JLabel(String.valueOf(prevDaysInMonth - i + 1), SwingConstants.CENTER);
            label.setForeground(Color.GRAY);
            label.setFont(new Font("Arial", Font.PLAIN, 20));
            calendarPanel.add(label);
        }

        // 添加當(dāng)前月的日期
        for (int i = 1; i <= daysInMonth; i++) {
            boolean isToday = (i == todayDay) && (currentMonth == todayMonth) && (currentYear == todayYear);
            // 創(chuàng)建日期標(biāo)簽,如果是今天則用圓形標(biāo)簽顯示
            calendarPanel.add(new CircleLabel(String.valueOf(i), isToday));
        }

        // 填充后續(xù)的空白日期(灰色顯示)
        for (int i = 1; i <= 42 - daysInMonth - (startDay - 1); i++) {
            JLabel dayLabel = new JLabel(String.valueOf(i), SwingConstants.CENTER);
            dayLabel.setForeground(Color.GRAY);
            dayLabel.setFont(new Font("Arial", Font.PLAIN, 20));
            calendarPanel.add(dayLabel);
        }

        // 重新驗證和重繪日歷面板
        calendarPanel.revalidate();
        calendarPanel.repaint();
    }

    // 切換月份的方法,delta 為正負(fù) 1 表示切換到上一個月或下一個月
    private void changeMonth(int delta) {
        currentMonth += delta;
        if (currentMonth < 0) {
            currentMonth = 11;
            currentYear--;
        } else if (currentMonth > 11) {
            currentMonth = 0;
            currentYear++;
        }
        // 更新年下拉框的選中項
        yearComboBox.setSelectedItem(currentYear);
        // 更新月下拉框的選中項
        monthComboBox.setSelectedItem(getMonthName(currentMonth));
        // 重新顯示日歷
        displayCalendar();
    }

    public static void main(String[] args) {
        // 使用 SwingUtilities.invokeLater 確保在事件分發(fā)線程中創(chuàng)建和顯示窗口
        SwingUtilities.invokeLater(() -> {
            CalendarMain app = new CalendarMain();
            app.setVisible(true);
        });
    }

    // 更新時間的方法,每秒鐘更新一次窗口標(biāo)題顯示的時間
    private void updateTime(ActionEvent e) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+8"));
        currentTime = sdf.format(new java.util.Date());
        setTitle("日歷" + currentTime);
    }

    // 根據(jù)月份索引獲取中文月份名稱的方法
    private String getMonthName(int monthIndex) {
        String[] monthNames = new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
        return monthNames[monthIndex];
    }
}

總結(jié) 

到此這篇關(guān)于java設(shè)計日歷可視化的文章就介紹到這了,更多相關(guān)java日歷可視化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java9 集合工廠方法解析

    Java9 集合工廠方法解析

    這篇文章主要介紹了Java9 集合工廠方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java輸入輸出流方式(文件的復(fù)制)

    Java輸入輸出流方式(文件的復(fù)制)

    Java中的輸入輸出流主要用于數(shù)據(jù)的讀取和寫入,在文件復(fù)制中,我們首先創(chuàng)建輸入流和輸出流對象,然后打開源文件和目標(biāo)文件,接著,通過循環(huán)讀取源文件中的數(shù)據(jù),并將其寫入目標(biāo)文件中,最后,關(guān)閉輸入輸出流以釋放資源
    2025-02-02
  • Maven 打包項目到私服 (deploy)的配置方法

    Maven 打包項目到私服 (deploy)的配置方法

    這篇文章主要介紹了Maven 打包項目到私服 (deploy)的配置方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Spring Boot 中的 @Field 注解的原理解析

    Spring Boot 中的 @Field 注解的原理解析

    本文詳細(xì)介紹了 Spring Boot 中的 @Field 注解的原理和使用方法,通過使用 @Field 注解,我們可以將 HTTP 請求中的參數(shù)值自動綁定到 Java 對象的屬性上,簡化了開發(fā)過程,提高了開發(fā)效率,感興趣的朋友跟隨小編一起看看吧
    2023-07-07
  • SpringCloudStream原理和深入使用小結(jié)

    SpringCloudStream原理和深入使用小結(jié)

    Spring?Cloud?Stream是一個用于構(gòu)建與共享消息傳遞系統(tǒng)連接的高度可擴(kuò)展的事件驅(qū)動型微服務(wù)的框架,本文給大家介紹SpringCloudStream原理和深入使用,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Java17中record替代Lombok部分功能使用場景探究

    Java17中record替代Lombok部分功能使用場景探究

    這篇文章主要介紹了使用Java17中的record替代Lombok的部分功能,本文來為大家小小的總結(jié)下,我們可以在哪些地方,利用record來替換Lombok
    2024-01-01
  • jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)

    jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)

    這篇文章主要介紹了jxls2.4.5如何動態(tài)導(dǎo)出excel表頭與數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Spring Security加密和匹配及原理解析

    Spring Security加密和匹配及原理解析

    我們開發(fā)時進(jìn)行密碼加密,可用的加密手段有很多,比如對稱加密、非對稱加密、信息摘要等,本篇文章給大家介紹Spring Security加密和匹配及原理解析,感興趣的朋友一起看看吧
    2023-10-10
  • Spring Boot之搞定mongoTemplate的知識小結(jié)

    Spring Boot之搞定mongoTemplate的知識小結(jié)

    這篇文章主要介紹了Spring Boot之搞定mongoTemplate的知識小結(jié),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • java使用鏈表實現(xiàn)約瑟夫環(huán)

    java使用鏈表實現(xiàn)約瑟夫環(huán)

    這篇文章主要為大家詳細(xì)介紹了java使用鏈表實現(xiàn)約瑟夫環(huán),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評論