我正在开发一个应该能够在JTable中添加和删除行的自定义组件。
通过使用此功能(例如,添加4行,删除这些行,添加新行并尝试选择它)我得到以下异常:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3 >= 1
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:664)
at cnhi_controltower.FDSchedule$ScheduleTable$1.setValueAt(FDSchedule.java:110)
at javax.swing.JTable.setValueAt(JTable.java:2741)
at javax.swing.JTable.editingStopped(JTable.java:4723)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)
at javax.swing.AbstractCellEditor.stopCellEditing(AbstractCellEditor.java:85)
at javax.swing.plaf.basic.BasicTableUI$Handler.mousePressed(BasicTableUI.java:1010)
at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:280)
at java.awt.Component.processMouseEvent(Component.java:6532)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6300)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4891)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4522)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
有人可以帮我这个吗?我到处寻找但无法找到解决方案。 似乎将错误的参数传递给TableModel的setValueAt(Object,int,int)方法。
这是我的代码:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JSpinner.DateEditor;
import java.text.*;
import com.fairdynamics.components.*;
import java.awt.event.*;
/**
* FDSchedule
*/
public class FDSchedule extends JPanel{
private ScheduleTable sc;
private CommandPanel p;
private final List<Object[]> intervals = new LinkedList();
/**
* Default constructor
*/
public FDSchedule() {
super(new BorderLayout());
sc = new ScheduleTable();
JScrollPane sp = new JScrollPane(sc);
add(sp,BorderLayout.CENTER);
sc.addRow();
p = new CommandPanel();
add(p,BorderLayout.EAST);
}
private class ScheduleTable extends JTable{
private String[] cols;
DefaultTableModel model;
public ScheduleTable(){
String[] cols = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun","Start","End"};
model = new DefaultTableModel(cols,0){
@Override
public void setValueAt(Object aValue, int row, int column) {
super.setValueAt(aValue, row, column);
Object[] i = intervals.get(row);
if(aValue instanceof Boolean){
i[column] = (boolean)aValue;
}else if(aValue instanceof Date){
i[column] = (Date)aValue;
}
}
};
setModel(model);
getColumn("Start").setCellRenderer(new TimeRenderer());
getColumn("Start").setCellEditor(new SpinnerEditor());
getColumn("End").setCellRenderer(new TimeRenderer());
getColumn("End").setCellEditor(new SpinnerEditor());
}
@Override
public Class<?> getColumnClass(int column) {
if(column<7){
return Boolean.class;
}else{
return Date.class;
}
}
public void addRow(){
Object[] o = {true,true,true,true,true,false,false,new Date(),new Date()};
intervals.add(o);
model.addRow(o);
}
public void removeSelectedRows(){
int[] rows = getSelectedRows();
Arrays.sort(rows);
for(int i=rows.length-1; i>=0; i--){
int row = rows[i];
int modelRow = convertRowIndexToModel( row );
model.removeRow(modelRow);
intervals.remove(row);
}
}
}
class TimeRenderer extends DefaultTableCellRenderer{
private final DateFormat f = new SimpleDateFormat("HH:mm");
@Override
protected void setValue(Object value) {
super.setValue(value);
setText((value == null) ? "" : f.format(value));
}
}
class SpinnerEditor extends AbstractCellEditor implements TableCellEditor {
protected JSpinner spinner;
private SpinnerDateModel model;
public SpinnerEditor() {
model = new SpinnerDateModel();
model.setCalendarField(Calendar.HOUR_OF_DAY);
spinner = new JSpinner(model);
spinner.setEditor(new JSpinner.DateEditor(spinner , "HH:mm"));
}
public Component getTableCellEditorComponent(JTable table, Object value,boolean isSelected, int row, int column) {
spinner.setValue(value);
return spinner;
}
public Object getCellEditorValue() {
SpinnerModel sm = spinner.getModel();
return sm.getValue();
}
}
private class CommandPanel extends JPanel{
public CommandPanel(){
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
JButton b = new JButton("Add");
b.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
sc.addRow();
}
});
add(b);
b = new JButton("Remove");
b.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
sc.removeSelectedRows();
}
});
add(b);
}
}
}
答案 0 :(得分:0)
可能与这个旧的Java bug有关:http://bugs.java.com/view_bug.do?bug_id=4730055
尝试在removeSelectedRows:
的末尾添加它model.fireTableDataChanged();