我正在尝试用 JPanel 创建日历,但由于某种原因数组索引超出范围,我不知道为什么。有人可以帮忙吗?它在我的代码中没有显示为错误,但我不知道在哪里可能会误算行数。
public class Calendar {
JTable calendar;
GregorianCalendar cal;
JPanel[][] dates;
public Calendar()
{
cal = new GregorianCalendar();
cal.set(2024, 3, 1);
String[] days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
List<JPanel> mon = new ArrayList<JPanel>();
List<JPanel> tue = new ArrayList<JPanel>();
List<JPanel> wed = new ArrayList<JPanel>();
List<JPanel> thur = new ArrayList<JPanel>();
List<JPanel> fri = new ArrayList<JPanel>();
List<JPanel> sat = new ArrayList<JPanel>();
List<JPanel> sun = new ArrayList<JPanel>();
System.out.println(cal.get(GregorianCalendar.DAY_OF_WEEK));
while(cal.get(GregorianCalendar.MONTH) == 3)
{
int day = cal.get(GregorianCalendar.DAY_OF_WEEK);
switch(day)
{
case 2:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 2)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
mon.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
mon.add(new JPanel());
}
break;
case 3:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 3)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
tue.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
tue.add(new JPanel());
}
break;
case 4:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 4)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
wed.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
wed.add(new JPanel());
}
break;
case 5:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 5)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
thur.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
thur.add(new JPanel());
}
break;
case 6:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 6)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
fri.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
fri.add(new JPanel());
}
break;
case 7:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 7)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
sat.add(yub);
}
else if(cal.get(GregorianCalendar.DATE) == 1)
{
sat.add(new JPanel());
}
break;
case 1:
if(cal.get(GregorianCalendar.DAY_OF_WEEK) == 1)
{
JPanel yub = new JPanel();
JLabel meow = new JLabel(String.valueOf(cal.get(GregorianCalendar.DATE)));
yub.add(meow);
sun.add(yub);
}
break;
}
cal.roll(GregorianCalendar.DATE, true);
if(cal.get(GregorianCalendar.DATE) == 1)
{
break;
}
}
if(tue.size() != mon.size())
{
tue.add(new JPanel());
}
if(wed.size() != tue.size())
{
wed.add(new JPanel());
}
if(thur.size() != wed.size())
{
thur.add(new JPanel());
}
if(fri.size() != thur.size())
{
fri.add(new JPanel());
}
if(sat.size() != fri.size())
{
sat.add(new JPanel());
}
if(sun.size() != sat.size())
{
sun.add(new JPanel());
}
System.out.println(mon.size() + " " + tue.size() + " " + wed.size() + " " + thur.size() + " " + fri.size() +
" " + sat.size() + " " + sun.size());
tue.stream().forEach(x -> System.out.println(x.getComponentCount()));
JPanel[][] dates = {mon.toArray(new JPanel[mon.size()]), tue.toArray(new JPanel[tue.size()]),
wed.toArray(new JPanel[wed.size()]), thur.toArray(new JPanel[thur.size()]),
fri.toArray(new JPanel[fri.size()]), sat.toArray(new JPanel[sat.size()]),
sun.toArray(new JPanel[sun.size()])};
this.dates = dates;
calendar = new JTable(dates, days);
}
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at java.desktop/javax.swing.JTable$1.getValueAt(JTable.java:704)
at java.desktop/javax.swing.JTable.getValueAt(JTable.java:2706)
at java.desktop/javax.swing.JTable.prepareRenderer(JTable.java:5724)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2210)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2112)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1908)
at java.desktop/javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5271)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1643)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1618)
at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1556)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1060)
at java.desktop/java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at java.desktop/sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:75)
at java.desktop/sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:112)
at java.desktop/java.awt.Container.paint(Container.java:2003)
at java.desktop/java.awt.Window.paint(Window.java:3949)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:876)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:848)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1884)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at java.desktop/javax.swing.JTable$1.getValueAt(JTable.java:704)
at java.desktop/javax.swing.JTable.getValueAt(JTable.java:2706)
at java.desktop/javax.swing.JTable.prepareRenderer(JTable.java:5724)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2210)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2112)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1908)
at java.desktop/javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1083)
at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:907)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5271)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1643)
at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1618)
at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1556)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1060)
at java.desktop/java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at java.desktop/sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:75)
at java.desktop/sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:112)
at java.desktop/java.awt.Container.paint(Container.java:2003)
at java.desktop/java.awt.Window.paint(Window.java:3949)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:876)
at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:848)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1884)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
我尝试在转换为数组之前比较每个列表的大小,并确保它们都相同,但似乎认为某处有一个额外的行。它应该创建一个作为月份日历的表。
不要将组件放入模型中,这不是表的工作方式 - 相反,您用数据填充表模型并使用渲染器来自定义输出。有关更多详细信息,请参阅如何使用表格。
不要使用过时的
java.util.Calendar/Date
API,而是开始使用 java.time.*
API - 请参阅日期/时间记录了解更多详细信息。
您的表格模型的构建方式是错误的。日期数组实际上是
[row][column]
排序的。您将每一天放置在每一行中,而不是将每一天交错放置在每一行上。
在您当前的设置中,您应该使用类似...
JPanel[][] dates = new JPanel[5][days.length];
for (int x = 0; x < dates.length; x++) {
dates[x][0] = mon.get(x);
dates[x][1] = tue.get(x);
dates[x][2] = wed.get(x);
dates[x][3] = thur.get(x);
dates[x][4] = fri.get(x);
dates[x][5] = sat.get(x);
dates[x][6] = sun.get(x);
}
这仍然容易出错,因为您无法确保正确填写各个日期(始终有 5 个元素)。