Java INDEXOUTOFBOUNDSExException插入行后,对表进行排序,然后删除行
在前面的一个问题()中,我指出我正在尝试创建一个“简单”的JTable,它使用TableModel将ArrayList绑定到使用TableModel的JTable。我的目标是——现在仍然是——保留java的所有内置JTable功能,这些功能允许单元格编辑、行排序和列重新排列。多亏了您的帮助,该功能现在可以正常工作了 我现在尝试添加插入和删除表行的功能。我在这里提供的(更新的)示例适用于。。。除了在特定的操作序列下,抛出“IndexOutOfBoundsException”。这是我的密码:Java INDEXOUTOFBOUNDSExException插入行后,对表进行排序,然后删除行,java,swing,Java,Swing,在前面的一个问题()中,我指出我正在尝试创建一个“简单”的JTable,它使用TableModel将ArrayList绑定到使用TableModel的JTable。我的目标是——现在仍然是——保留java的所有内置JTable功能,这些功能允许单元格编辑、行排序和列重新排列。多亏了您的帮助,该功能现在可以正常工作了 我现在尝试添加插入和删除表行的功能。我在这里提供的(更新的)示例适用于。。。除了在特定的操作序列下,抛出“IndexOutOfBoundsException”。这是我的密码: pac
package tableexample;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
public final class TableExample extends JFrame {
List<REItem> REList;
JTable tblREList;
JButton btnAddInsertRE, btnDeleteRE;
JScrollPane spMain;
JFrame frame;
Container pane;
public TableExample() {
// create and populate the ArrayList
REList = new ArrayList<>();
REList.add(new REItem("Template1", "Comment1"));
REList.add(new REItem("Template2", "Comment2"));
RETableModel retm = new RETableModel(REList); // Connect the List to the TableModel
// create GUI components
frame = new JFrame ("Table Example");
btnAddInsertRE = new JButton("Add/Insert");
btnDeleteRE = new JButton("Delete");
tblREList = new JTable(retm);
tblREList.setAutoCreateRowSorter(true);
spMain = new JScrollPane(tblREList);
// add button ActionListeners
btnAddInsertRE.addActionListener((ActionEvent evt) -> { btnAddInsertREActionPerformed(evt); });
btnDeleteRE.addActionListener((ActionEvent evt) -> { btnDeleteREActionPerformed(evt); });
// place GUI components and make the GUI visible
pane = frame.getContentPane();
pane.setLayout (null);
pane.add(btnAddInsertRE);
pane.add(btnDeleteRE);
pane.add(spMain);
btnAddInsertRE.setBounds (10, 10, 100, 25);
btnDeleteRE.setBounds (120, 10, 100, 25);
spMain.setBounds (10, 45, spMain.getPreferredSize().width, spMain.getPreferredSize().height);
frame.setSize(spMain.getWidth() + 40, spMain.getHeight() + 95);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} // end TableExample constructor
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
TableExample notUsed = new TableExample();
});
} //end main
private void btnAddInsertREActionPerformed(ActionEvent evt) {
// Add a FileSelection object to the ArrayList
int r = tblREList.getSelectedRow(); // get row selection, if any
if (r < 0) { // no row selected
REList.add(new REItem("NewTemplate", "NewComment")); // append new item to end
r = REList.size()-1; // get index to new item
} else { // else no row selected
REList.add(r, new REItem("NewTemplate", "NewComment")); // insert above selected row
} // row selected or not
spMain.setViewportView(tblREList); // repaint the updated table
tblREList.getSelectionModel().setSelectionInterval(r, r); // select the new row
}
private void btnDeleteREActionPerformed(ActionEvent evt) {
int[] selRows = tblREList.getSelectedRows(); // see if any rows are selected
if (selRows.length>0) { // at least one row is selected
for (int r=selRows.length-1; r>=0; r--) { // delete each row, from the bottom up,
REList.remove(r); // so that indexes are correct and
} // don't change with each delete
tblREList.clearSelection(); // clear the row selection data
spMain.setViewportView(tblREList); // repaint the updated table
} else { // else no row(s) selected
JOptionPane.showMessageDialog(null, "Must select at least one item to delete");
} // no row selected
} // end btnDeleteREActionPerformed
public final class REItem {
String template;
String comment;
public REItem(String tmp, String cmt) {
this.template = tmp;
this.comment = cmt;
}
} // end class REItem
public class RETableModel extends AbstractTableModel {
private List<REItem> reList = new ArrayList();
private final String[] columnNames = { "Template", "Comment" };
public RETableModel(List<REItem> list){
this.reList = list;
}
@Override
public String getColumnName(int column){
return columnNames[column];
}
@Override
public int getRowCount() {
return reList.size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int row, int column) {
switch (column) {
case 0: return reList.get(row).template;
case 1: return reList.get(row).comment;
}
return null; // default case
}
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
@Override
public Class<?> getColumnClass(int column){
switch (column){
case 0: return String.class;
case 1: return String.class;
}
return null; // default case
}
@Override
public void setValueAt(Object value, int row, int column) {
switch (column) {
case 0: reList.get(row).template = value.toString(); break;
case 1: reList.get(row).comment = value.toString(); break;
}
// uncommenting the below often causes IndexOutOfBoundsException: Invalid range exception
fireTableCellUpdated(row, column);
} // end setValueAt
} // end RETableModel
} // end class TableExample
包表示例;
导入java.awt.Container;
导入java.awt.event.ActionEvent;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JOptionPane;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.table.AbstractTableModel;
公共最终类TableExample扩展了JFrame{
重新列表;
JTable任务列表;
b按钮btnAddInsertRE,btnDeleteRE;
Jscorlpane spMain;
JFrame框架;
集装箱窗格玻璃;
公共表格示例(){
//创建并填充ArrayList
REList=newarraylist();
添加(新REItem(“模板1”、“注释1”);
添加(新REItem(“模板2”、“注释2”);
RETableModel retm=new RETableModel(REList);//将列表连接到TableModel
//创建GUI组件
框架=新的JFrame(“表格示例”);
btnAddInsertRE=新的JButton(“添加/插入”);
btnDeleteRE=新的JButton(“删除”);
tblREList=新JTable(retm);
tblREList.setAutoCreateRowSorter(真);
spMain=新的JScrollPane(tblREList);
//添加按钮ActionListeners
addActionListener((ActionEvent evt)->{btnAddInsertREActionPerformed(evt);});
addActionListener((ActionEvent evt)->{btnDeleteREActionPerformed(evt);});
//放置GUI组件并使GUI可见
pane=frame.getContentPane();
pane.setLayout(空);
窗格。添加(btnAddInsertRE);
窗格。添加(btnDeleteRE);
窗格。添加(spMain);
btnAddInsertRE.setBounds(10,10,100,25);
btnDeleteRE.setBounds(120,10,100,25);
spMain.setBounds(10,45,spMain.getPreferredSize().width,spMain.getPreferredSize().height);
frame.setSize(spMain.getWidth()+40,spMain.getHeight()+95);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//结束表示例构造函数
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(()->{
TableExample notUsed=新建TableExample();
});
}//末端总管
已执行私有无效BTNADDINSERTRACTION(ActionEvent evt){
//将FileSelection对象添加到ArrayList
int r=tblREList.getSelectedRow();//获取行选择(如果有)
如果(r<0){//未选择任何行
REList.add(new REItem(“NewTemplate”、“NewComment”);//将新项追加到末尾
r=REList.size()-1;//获取新项的索引
}else{//else未选择行
REList.add(r,new REItem(“NewTemplate”,“NewComment”);//在所选行上方插入
}//是否选择了行
spMain.setViewportView(tblREList);//重新绘制更新的表
tblREList.getSelectionModel().setSelectionInterval(r,r);//选择新行
}
private void btnDeleteREActionPerformed(ActionEvent evt){
int[]selRows=tblREList.getSelectedRows();//查看是否选择了任何行
如果(selRows.length>0){//至少选择了一行
对于(int r=selRows.length-1;r>=0;r--){//从下到上删除每一行,
REList.remove(r);//以便索引正确且
}//不随每次删除而更改
tblREList.clearSelection();//清除行选择数据
spMain.setViewportView(tblREList);//重新绘制更新的表
}else{//else未选择行
showMessageDialog(null,“必须至少选择一个要删除的项”);
}//未选择任何行
}//结束btnDeleteREActionPerformed
公共期末班{
字符串模板;
字符串注释;
公共REItem(字符串tmp、字符串cmt){
this.template=tmp;
this.comment=cmt;
}
}//结束类REItem
公共类RETableModel扩展了AbstractTableModel{
private List reList=new ArrayList();
私有最终字符串[]columnNames={“模板”,“注释”};
公共重设模型(列表){
this.reList=列表;
}
@凌驾
公共字符串getColumnName(int列){
返回columnNames[列];
}
@凌驾
public int getRowCount(){
返回reList.size();
}
@凌驾
public int getColumnCount(){
返回columnNames.length;
}
@凌驾
公共对象g