当我使用setAutoCreateRowSorter()时,我的JTable得到一个无效范围异常。如果我删除setAutoCreateRowSorter,问题就会消失,但我无法对表进行排序。另外,如果我尝试直接设置分拣机:
myTable.setRowSorter(new TableRowSorter(model));
我仍然得到同样的错误。
这与我认为可以传达这个问题的SSCCE非常接近。
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class MyTestTable extends javax.swing.JFrame {
private MyTestAbstractTableModel model = new MyTestAbstractTableModel();
private int selectedRow = -1;
public void setList(ArrayList arrayList) {
model.setList(arrayList);
}
public MyTestTable() {
initComponents();
myTable.setModel(model);
myTable.setAutoCreateRowSorter(true); // Error here
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
myTable = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
myTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Select", "First name", "Last name"
}
) {
Class[] types = new Class [] {
java.lang.Boolean.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
jScrollPane1.setViewportView(myTable);
javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(187, 187, 187)
.addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(243, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(91, 91, 91)
.addComponent(jScrollPane1,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(154, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
ArrayList<MyTest> myTestList = new ArrayList<>();
MyTest myEntry = new MyTest(false, "Joe");
myTestList.add(myEntry);
MyTestTable myTestTable = new MyTestTable();
myTestTable.setList(myTestList);
myTestTable.setVisible(true);
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable myTable;
// End of variables declaration
public class MyTestAbstractTableModel extends AbstractTableModel {
private String[] columnNames = {"Select", "First Name"};
private ArrayList<MyTest> myTestList = new ArrayList<>();
public void setList(ArrayList<MyTest> myList) {
this.myTestList = myList;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return myTestList.size();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int row, int column) {
Object value = null;
MyTest myTest = myTestList.get(row);
switch (column) {
case 0:
value = myTest.getSelected();
break;
case 1:
value = myTest.getFirstName();
}
return value;
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object value, int row, int column) {
MyTest myTest = myTestList.get(row);
switch (column) {
case 0:
if (value instanceof Boolean)
myTest.setSelected((boolean)value);
break;
case 1:
myTest.setFirstName((String)value);
}
fireTableCellUpdated(row, column); // Exception points to here
}
}
public static class MyTest {
private Boolean selected;
private String firstName;
public MyTest() {
}
public MyTest(Boolean selected, String firstName) {
this.selected = selected;
this.firstName = firstName;
}
public boolean getSelected() {
return selected;
}
public void setSelected(Boolean selected) {
this.selected = selected;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
}
单击表格上的复选框时会出现问题。这与我认为可以传达这个问题的SSCCE非常接近。如果我带走分拣机,问题就不会持续存在。
这是错误:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
at javax.swing.DefaultRowSorter.rowsUpdated(DefaultRowSorter.java:896)
at javax.swing.DefaultRowSorter.rowsUpdated(DefaultRowSorter.java:915)
at javax.swing.JTable.notifySorter(JTable.java:4264)
at javax.swing.JTable.sortedTableChanged(JTable.java:4118)
at javax.swing.JTable.tableChanged(JTable.java:4395)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(AbstractTableModel.java:275)
at MyTestTable$MyTestAbstractTableModel.setValueAt(MyTestTable.java:151)
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.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:368)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:233)
at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(DefaultCellEditor.java:385)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:308)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6535)
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 javax.swing.plaf.basic.BasicTableUI$Handler.repostEvent(BasicTableUI.java:948)
at javax.swing.plaf.basic.BasicTableUI$Handler.mouseReleased(BasicTableUI.java:1164)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290)
at java.awt.Component.processMouseEvent(Component.java:6535)
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:4525)
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)
这部分特别向我说明:
at MyTestTable$MyTestAbstractTableModel.setValueAt(MyTestTable.java:151)
This post是我能找到的最接近我问题的东西,但没有回答。如何在不收到此错误的情况下实现表格分类器?