java日历问题无法解决 swing 下拉框问题

//这是主Second文件
package yan;


import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import yan1.YearMonth;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.time.DayOfWeek;
import java.time.LocalDate;







public  class Second extends JFrame implements ActionListener{ 
        int year=2023;
        int month=4; 
        private int y=0; 
        private int x=0;
        private int n=0;
        private static int monthday;
        private int dayofweek;//
         JComboBox jComboBox_1=new JComboBox();
         JComboBox jComboBox_2=new JComboBox();
        Font an=new Font("华文楷体",Font.BOLD,25);
        
        
    public void Sec() {//建造窗体
        
        
        
        
        draw();
        year();
        month();
        weekword();
        getyearmonth();
        getweekday(); 
        function();
        
        
        
    }
    public void draw() { //建造界面和标题
        
        this.setLayout(null);
        setTitle("2022141461175_夏弋昕");
        setSize(800,800);
        setLocation(200, 100);
        
    }
    
    
    
   public void year() {//写出年
      
       for(int i=0;i<11;i++) {
       jComboBox_1.addItem(i+2013);
       jComboBox_1.setFont(an);
          
       }
       jComboBox_1.setBounds(100,10,100,70);
       jComboBox_1.setMaximumRowCount(4);
       this.add(jComboBox_1);
       
   }
    public void month() {//写出月
        for(int i=0;i<12;i++) {
        jComboBox_2.addItem(i+1);
        jComboBox_2.setFont(an);
        }
        
        jComboBox_2.setBounds(400,10,100,70);
        jComboBox_2.setMaximumRowCount(4);
        this.add(jComboBox_2);
    }
    public void weekword() {//写其他文字
        JLabel jLabel_1=new JLabel("年:");
        jLabel_1.setForeground(Color.blue);//设置文字1的颜色 setForeground
        jLabel_1.setFont(an);//设置文字1的字体   setFont
        jLabel_1.setBounds(10,10,100,100);//设置文字1的距离
        JLabel jLabel_2=new JLabel("月:");
        jLabel_2.setForeground(Color.blue);//设置文字1的颜色 setForeground
        jLabel_2.setFont(an);//设置文字1的字体   setFont
        jLabel_2.setBounds(300,10,400,100);//设置文字1的距离
        JLabel jLabel_3=new JLabel("  一    二   三    四    五    六    日");
        jLabel_3.setFont(an);
        jLabel_3.setBounds(30, 70, 700, 60);
        this.add(jLabel_1);
        this.add(jLabel_2);
        this.add(jLabel_3);
        
    }
    public void function() {//算日历
        
        getyearmonth();
        this.setLayout(null);
        for(int i=0;i<42;i++){
            x+=50;
            if(i>=dayofweek-1&&nnew JLabel(" "+n);
            jLabel_i.setBounds(x,100+y,100,100);
            
             this.add(jLabel_i);
             jLabel_i.setFont(an);
             setVisible(true);    


            }
             if((i+1)%7==0) {
                 y+=100;
                 x=0;
             }
             setVisible(true);    
        }
        
        YearMonth yearmonth= new YearMonth(year,month,dayofweek,monthday);
        
    }
    public void getyearmonth() {//得到下拉框中的值
         
        
          year= Integer.parseInt(jComboBox_1.getSelectedItem().toString());
         
              
             month=Integer.parseInt(jComboBox_2.getSelectedItem().toString());
         
         
           YearMonth yearmonth= new YearMonth(year,month,dayofweek,monthday);
        
    }
    public int mont(int a) {//计算月份天数
        int days = 0;
        switch(a) {
          case 1:days=31;break;
          case 2:days=28;break;
          case 3:days=31;break;
          case 4:days=30;break;
          case 5:days=31;break;
          case 6:days=30;break;
          case 7:days=31;break;
          case 8:days=31;break;
          case 9:days=30;break;
          case 10:days=31;break;
          case 11:days=30;break;
          case 12:days=31;break;
          }
            return days;

        }
       public void change() {//改变
           
           jComboBox_1.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                // TODO 自动生成的方法存根
                if(e.getStateChange()==ItemEvent.SELECTED) {

                    function();
                    
                }
            }
               
               
           });
          
       }
         public void getweekday() {
           
            LocalDate date=LocalDate.of(year,month, 1);
           DayOfWeek weekday=date.getDayOfWeek();
           dayofweek=weekday.getValue();
            monthday=mont(month);
          
           
         }
    public void clear() {
        this.removeAll();
        this.repaint();
    }
    
    
    public static void main(String[] args) {
        
         Second two=new Second();
         
         two.Sec();
         two.change();
         System.out.println(monthday);
        
         
         
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO 自动生成的方法存根
        
    }
//这是封装文件
package yan1;

public class YearMonth {
     private int year;
     private int month;
     private int monthday;
     private int dayofweek;
     public YearMonth (){ 
     }
   
     
     
     
     
     public YearMonth (int year, int month,int dayofweek, int monthday){ 
         this.dayofweek=dayofweek;
         this.monthday=monthday;
         this.year=year;
         this.month=month;
     }
     public int getyear() {
         
         return year;
     }
     public void setyear(int year) {
         this.year=year;
     }
     public int getmonth() {
         
         return month;
     }
     public void setmonth(int month) {
         this.month=month;
     }
public int getdayofweek() {
         
         return dayofweek;
     }
     public void setdayofweek(int dayofweek) {
         this.dayofweek=dayofweek;
     }
     public int getmonthday() {
         
         return monthday;
     }
     public void setmonthday(int monthday) {
         this.monthday=monthday;
     }
     
     
     
     
     
     
     
     
}







想要实现下拉框选择的同时显示月份日历

img

img


但是只有最初的2013年1月的日历
再选择年份没用
新学java
如何解决

说明年份的下拉框没有出发相应的事件。已帮您解决:
修改后的代码:
增加一个全局的dayLabels数组,用于存储日期

   private List<JLabel>  dayLabels = new ArrayList<>();


修改建造窗体,之前的调用存在多次调用,去掉了一些不必要的调用:


 public void Sec() {//建造窗体
        
        
        
        
        draw();
        year();
        month();
        weekword();
 
       
        function();
        
        
        
    }

修改了算日历的函数,这里主要是x和y、n每次要重新初始化为0,其次要把上次的日期从界面删除掉:

 public void function() {//算日历
        
        getyearmonth();
        getweekday(); 
        for(int i =0;i<dayLabels.size();i++) {
            this.remove(dayLabels.get(i));
        }
        dayLabels.clear();
        n = 0;
        x = 0;
        y = 0;
   
        for(int i=0;i<42;i++){
            x+=50;
            if(i>=dayofweek-1&&n<monthday) {  
                n++;
            JLabel jLabel_i=new JLabel(" "+n);
            jLabel_i.setBounds(x,100+y,100,100);
         
             this.add(jLabel_i);
             jLabel_i.setFont(an);
             setVisible(true);    
             dayLabels.add(jLabel_i);

            }
             if((i+1)%7==0) {
                 y+=100;
                 x=0;
             }
             setVisible(true);    
        }
       
        
//        YearMonth yearmonth= new YearMonth(year,month,dayofweek,monthday);
        
    }

修改下拉框的监听事件,增加月份的下拉监听:

 public void change() {//改变
           
           jComboBox_1.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                // TODO 自动生成的方法存根
                if(e.getStateChange()==ItemEvent.SELECTED) {
                    
                    function();
                    
                }
            }
               
               
           });
           jComboBox_2.addItemListener(new ItemListener() {

               @Override
               public void itemStateChanged(ItemEvent e) {
                   // TODO 自动生成的方法存根
                   if(e.getStateChange()==ItemEvent.SELECTED) {
                   
                       function();
                       
                   }
               }
                  
                  
              });
          
       }

最后的效果:

img

该回答引用ChatGPT
这个问题看起来是需要根据选择的年份和月份来显示对应的日历。但是看代码,下拉框选择后并没有调用 `function()` 方法重新计算日历,导致一直显示的是最初的2013年1月的日历。

解决方法:

1. 在 `change()` 方法中,添加对选择月份下拉框的监听,当月份改变时,调用 `function()` 方法重新计算日历。

java
public void change() {
...

jComboBox_2.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
n = 0; // 重新计算日历前需要将 n 置为 0
clear(); // 先清除原来的内容
function(); // 重新计算日历
}
}
});
}


2. 在 `function()` 方法中,调用 `getweekday()` 和 `getyearmonth()` 方法重新计算当前选择的年、月份的天数和第一天是周几。

java
public void function() {
clear(); // 清空原来的内容

getyearmonth(); // 获取当前选择的年、月份
getweekday(); // 计算当月第一天是周几
...
}


这样,当选择年份和月份后,就能正确地显示对应的日历了。完整代码如下:



// 主文件 Second.java
package yan;

import yan1.YearMonth;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.time.DayOfWeek;
import java.time.LocalDate;

public class Second extends JFrame implements ActionListener {
int year = 2023;
int month = 4;
private int y = 0;
private int x = 0;
private int n = 0;
private static int monthday;
private int dayofweek;
JComboBox jComboBox_1 = new JComboBox<>();
JComboBox jComboBox_2 = new JComboBox<>();
Font an = new Font

clear()后就没有界面了

引用chatGPT作答,要在Java中实现下拉框选择月份后显示该月份的日历,可以使用Java Swing GUI库中的JComboBox组件和JLabel组件。下面是一个简单的实现示例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MonthCalendar extends JFrame implements ActionListener {
    private JComboBox<String> monthCombo;
    private JLabel[] dateLabels;

    public MonthCalendar() {
        setTitle("Month Calendar");
        setSize(300, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建下拉框,并设置选项
        monthCombo = new JComboBox<>();
        monthCombo.addActionListener(this);
        for (int i = 1; i <= 12; i++) {
            monthCombo.addItem(String.format("%02d", i));
        }
        JPanel topPanel = new JPanel();
        topPanel.add(new JLabel("Month: "));
        topPanel.add(monthCombo);
        add(topPanel, BorderLayout.NORTH);

        // 创建日历部分
        JPanel calendarPanel = new JPanel(new GridLayout(6, 7));
        dateLabels = new JLabel[42];
        for (int i = 0; i < 42; i++) {
            dateLabels[i] = new JLabel("", SwingConstants.CENTER);
            calendarPanel.add(dateLabels[i]);
        }
        updateCalendar();
        add(calendarPanel, BorderLayout.CENTER);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        updateCalendar();
    }

    private void updateCalendar() {
        // 获取选择的年月
        String monthStr = monthCombo.getSelectedItem().toString();
        int year = 2023; // 假设年份为2023
        int month = Integer.parseInt(monthStr);

        // 计算该月第一天是星期几
        int firstDayOfWeek = LocalDate.of(year, month, 1).getDayOfWeek().getValue();

        // 计算该月有多少天
        int daysInMonth = YearMonth.of(year, month).lengthOfMonth();

        // 更新日历中的日期显示
        int index = 0;
        for (int i = 1; i <= daysInMonth; i++) {
            dateLabels[index + firstDayOfWeek - 1].setText(String.valueOf(i));
            index++;
        }
        for (int i = index + firstDayOfWeek - 1; i < 42; i++) {
            dateLabels[i].setText("");
        }
    }

    public static void main(String[] args) {
        MonthCalendar frame = new MonthCalendar();
        frame.setVisible(true);
    }
}

上述代码中,MonthCalendar类继承自JFrame类,实现了ActionListener接口,用于处理下拉框选择事件。在构造函数中,首先创建一个JComboBox组件用于选择月份,然后创建一个JPanel用于显示日历。日历部分使用了一个6x7的GridLayout布局,包含了42个JLabel组件用于显示日期。在updateCalendar()方法中,根据选择的年月计算该月的第一天是星期几以及该月有多少天,然后更新日历中的日期显示。注意,为了方便起见,上述代码中假设年份为2023,实际情况应该根据需要进行修改。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^