[英]IndexOutOfBoundsException using ArrayList
用户可以选择一个月。 我为包含月份列表的ComboBox设置了一个侦听器ItemListener
。 我有一个设定的条件,如果用户选择“二月”的天列表,最多只能有29天, “四月”,“六月” ,依此类推,则ComboBox上将有30天。 但是,当我选择“ 2月”时,它可以正常工作,但是当我选择另一个月时,我会收到一个错误消息。
IndexOutOfBoundsException: Index: 30, Size: 29
我知道发生此错误是因为另一个月份的索引为30。我有点困惑,应该删除ArrayList或ComboBox的内容吗? 有什么帮助我该如何消除呢?
private ItemHandler handler = new ItemHandler();
ArrayList<String> daysList = new ArrayList<String>();
String[] daysObj = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"};
DefaultComboBoxModel daysModel = new DefaultComboBoxModel(daysObj);
public AddEmployee()
{
setMonths();
setDays();
cbMonths.addItemListener(handler);
}
private void setDays()
{
for(int i = 0; i < daysObj.length; i++)
{
daysList.add(daysObj[i]);
}
cbDays.setModel((ComboBoxModel)daysModel);
}
private class ItemHandler implements ItemListener
{
int removeDays[] = {29,30};//array
int remove[] = {30};
@Override
public void itemStateChanged(ItemEvent e)
{
if(e.getSource() == cbMonths)//Check where combobox occured.
{
if(cbMonths.getSelectedItem().equals("February"))
{
for(int i = removeDays.length-1; i >= 0; i--)
{
daysList.remove(removeDays[i]);//Remove given array from ArrayList using removeDays[]
System.out.println("NEW ELEMENT: "+daysList);
}
for(String s : daysList)//Update ArrayList
{
cbDays.addItem(s);
System.out.println("NEW LIST OF ARRAY: "+s);
}
}
else if(cbMonths.getSelectedItem().equals("April") || cbMonths.getSelectedItem().equals("June") ||
cbMonths.getSelectedItem().equals("September") || cbMonths.getSelectedItem().equals("November"))
{
for(int i = remove.length-1; i >= 0; i--)
{
daysList.remove(remove[i]);
System.out.println(daysList);
}
for(String a : daysList)//Update ArrayList
{
cbDays.addItem(a);
System.out.println("NEW LIST OF ARRAY: "+a);
}
}
}
}
我尝试了方法removeAllItems()
但它似乎不起作用。 cbDays.removeAllItems();
与其每次用户选择另一个月(这很难读取且容易出错),都执行复杂的计算,而是更好地初始化一些涵盖所有情况的静态模型。 然后,您的StateChaged处理程序只需选择正确的模型。 下面的示例基于新的java 8 datetime API:
private static String[] initDays( int number )
{
String[] result = new String[ number];
for ( int i = 0; i < result.length; i++ )
{
result[i] = "" + ( i+1);
}
return result;
}
private static final String[] days28 = initDays( 28);
private static final String[] days29 = initDays( 29);
private static final String[] days30 = initDays( 30);
private static final String[] days31 = initDays( 31);
private static final ComboBoxModel<String> model28 = new DefaultComboBoxModel<>(days28);
private static final ComboBoxModel<String> model29 = new DefaultComboBoxModel<>(days29);
private static final ComboBoxModel<String> model30 = new DefaultComboBoxModel<>(days30);
private static final ComboBoxModel<String> model31 = new DefaultComboBoxModel<>(days31);
private static final Set<Month> month30 = EnumSet.of(
Month.FEBRUARY,
Month.APRIL,
Month.JUNE,
Month.SEPTEMBER,
Month.NOVEMBER
);
private static final Set<Month> month31 = EnumSet.of(
Month.JANUARY,
Month.MARCH,
Month.MAY,
Month.JULY,
Month.AUGUST,
Month.OCTOBER,
Month.DECEMBER
);
private JComboBox<String> cbMonths = new JComboBox<>();
private JComboBox<String> cbDays = new JComboBox<>();
public void itemStateChanged(ItemEvent e)
{
if(e.getSource() == cbMonths)//Check where combobox occured.
{
if(cbMonths.getSelectedItem().equals("February"))
{
Month selectedMonth = Month.valueOf( cbMonths.getItemAt( cbMonths.getSelectedIndex() ) );
if ( month31.contains( selectedMonth ) )
{
cbDays.setModel( model31 );
}
else if ( month30.contains( selectedMonth ) )
{
cbDays.setModel( model30 );
}
else
{
if ( Year.isLeap( Instant.now().getLong( ChronoField.YEAR ) ) )
{
cbDays.setModel( model29 );
}
else
{
cbDays.setModel( model28 );
}
}
}
}
}
进一步的增强可能是使用由Month枚举直接键入的cbMonth,并提供一个单元格渲染器,该渲染器在用户的语言环境中显示月份。
通过setDays()
初始化后, daysList
包含31个元素。 选择February
,将删除索引为29
和30
两个元素:
daysList.remove(removeDays[i])
daysList
现在有29
元素。 选择另一个月后,将删除索引为30
一个元素
daysList.remove(remove[i]);
但是dayslist
只有29个元素,因此抛出IndexOutOfBoundsException
。
因此,一种解决方案可能是每次触发itemStateChanged
重新初始化daysList
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.