java – Jtable行删除
我正在用
java创建一个没有数据库的库系统程序.(直接用文件).
我在jtable中删除一行(从文件中删除)也有一个奇怪的问题. 有时当我在表格中选择一行并单击删除按钮时,更多的一行已被删除! 也是大多数时候它正常工作!! 我的代码: public final class UserPage extends JFrame implements ActionListener { private AllUser userModel; private JTable uTable; JButton deleteUser; int selectedRow; public UserPage() { titleUserCount(); userModel = new AllUser(); uTable = new JTable(userModel); add(new JScrollPane(uTable),BorderLayout.CENTER); add(buttonPanels(),BorderLayout.PAGE_START); this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); this.setSize(800,600); this.setLocation(300,60); this.setResizable(false); } public final JPanel buttonPanels() { JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); deleteUser = new JButton("Delete User"); deleteUser.addActionListener(this); buttonsPanel.add(deleteUser); return buttonsPanel; } public void titleUserCount() { AllUser userCount = new AllUser(); UserPage.this.setTitle("All User Information,Number Of user is : " + userCount.getRowCount()); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == deleteUser) { int selectedrow = uTable.getSelectedRow(); if (selectedrow >= 0) { userModel.RemoveRow(selectedrow); titleUserCount(); } else { JOptionPane.showMessageDialog(null,"No Row Selected"); } } } } 我的模特课: public class AllUser extends AbstractTableModel { UserInformation uiS = new UserInformation(); String[] col = {"ID","Fname","Lname","Gender","Date"}; ArrayList<UserInformation> Udata = new ArrayList<UserInformation>(); public AllUser() { BufferedReader br = null; try { FileReader fr = new FileReader("AllUserRecords.txt"); br = new BufferedReader(fr); String line; while ((line = br.readLine()) != null) { if (line.trim().length() == 0) { continue; } Udata.add(initializeUserInfos(line)); } } catch (IOException e) { } finally { if (br != null) { try { br.close(); } catch (IOException ioe) { } } } } private UserInformation initializeUserInfos(String str) { UserInformation Uinit = new UserInformation(); String[] CellArray = str.split(" "); Uinit.setID(CellArray[0]); Uinit.setFname(CellArray[1]); Uinit.setLname(CellArray[2]); Uinit.setGender(CellArray[3]); Uinit.setDate(CellArray[4]); return Uinit; } public void RemoveRow(int rowIndex) { if (RemoveUserFromFile(rowIndex)) { Udata.remove(rowIndex); fireTableRowsDeleted(rowIndex,rowIndex); } else { JOptionPane.showMessageDialog(null,"Unable to delete"); } } public boolean RemoveUserFromFile(int index) { File Mf = new File("AllUserRecords.txt"); File Tf = new File("Uoutput.txt"); try { BufferedReader Ubr = new BufferedReader(new FileReader(Mf)); PrintWriter Upw = new PrintWriter(new FileWriter(Tf)); String line; while ((line = Ubr.readLine()) != null) { if (line.trim().length() == 0) { continue; } if (!line.startsWith(String.valueOf(getValueAt(index,0)))) { Upw.println(line); } } Upw.close(); Ubr.close(); Mf.delete(); Tf.renameTo(Mf); return true; } catch (FileNotFoundException e1) { return false; } catch (IOException ioe) { return false; } } @Override public String getColumnName(int colu) { return col[colu]; } @Override public int getRowCount() { return Udata.size(); } @Override public int getColumnCount() { return col.length; } @Override public Object getValueAt(int rowIndex,int columnIndex) { UserInformation uinfoS = Udata.get(rowIndex); Object value = null; switch (columnIndex) { case 0: value = uinfoS.getID(); break; case 1: value = uinfoS.getFname(); break; case 2: value = uinfoS.getLname(); break; case 3: value = uinfoS.getGender(); break; case 4: value = uinfoS.getDate(); break; default: value = "..."; } return value; } @Override public void setValueAt(Object value,int rowIndex,int columnIndex) { UserInformation userInfo = Udata.get(rowIndex); switch (columnIndex) { case 0: userInfo.setID((String) value); break; case 1: userInfo.setFname((String) value); break; case 2: userInfo.setLname((String) value); break; case 3: userInfo.setGender((String) value); break; case 4: userInfo.setDate((String) value); break; } } } 用户信息类: public class UserInformation { private String Fname; private String Lname; private String ID; private String Gender; private String Date; public String getFname() { return Fname; } public void setFname(String fname) { this.Fname = fname; } public String getLname() { return Lname; } public void setLname(String lname) { this.Lname = lname; } public String getID() { return ID; } public void setID(String i_d) { this.ID = i_d; } public String getGender() { return Gender; } public void setGender(String gndr) { this.Gender = gndr; } public String getDate() { return Date; } public void setDate(String date) { this.Date = date; } @Override public String toString() { return ID + " " + Fname + " " + Lname + " " + Gender + " " + Date + "n"; } } 我的文字文件: 85 lo ii Female 2013/03/08 86 jkj nmn Female 2013/03/08 52 tyr fgfg Female 2013/03/08 7 dfdf wew Female 2013/03/08 47 zczc asa Female 2013/03/08 16 erw www Male 2013/03/08 83 gfg dsd Male 2013/03/08 解决方法
好吧,既然我没有你的所有代码,所以我正在进行一个虚拟程序,用于从JTable中删除记录以及相应的文件.观察MyTabeModel类中定义的removeRow方法.它还涵盖了从ArrayList删除记录后无法将数据写入文件(records.temp)的风险.
import javax.swing.table.*; import java.awt.event.*; import java.awt.*; import javax.swing.*; import java.util.*; import java.io.*; public class TableFocus extends JFrame { MyTableModel model1; JTable table1; public void createAndShowGUI() { setTitle("JTables"); Container c = getContentPane(); model1 = new MyTableModel(); table1 = new JTable(model1); table1.setColumnSelectionAllowed(false); table1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane jsTable1 = new JScrollPane(table1); c.add(jsTable1); JButton button = new JButton("Delete"); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { if (model1.getRowCount() > 0 && table1.getSelectedRow() != -1 ) { model1.deleteRow(table1.getSelectedRow()); } } }); add(button,BorderLayout.SOUTH); setSize(500,300); setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } private class MyTableModel extends AbstractTableModel { String columns[] ; ArrayList<ArrayList<String>> data; public MyTableModel() { columns = new String[] {"Roll No.","Name"}; prepareData(); } private void prepareData() { data = new ArrayList<ArrayList<String>>(); data.add(new ArrayList<String>(){{add("1");add("Michael");}}); data.add(new ArrayList<String>(){{add("2");add("Derake");}}); data.add(new ArrayList<String>(){{add("3");add("Archie");}}); } @Override public String getColumnName(int columnIndex) { return columns[columnIndex]; } @Override public int getRowCount() { return data.size(); } @Override public int getColumnCount() { return columns.length; } @Override public Object getValueAt(int row,int col) { return data.get(row).get(col); } @Override public void setValueAt(Object aValue,int colIndex) { data.get(rowIndex).set(colIndex,(String)aValue); fireTableCellUpdated(rowIndex,colIndex); } @Override public boolean isCellEditable(int row,int col) { return false; } public void deleteRow(int row) { ArrayList<String> temp = data.get(row);//backup of value in case of IOException while writing to file BufferedWriter bfr = null; try { data.remove(row); //Write here the logic for repopulating file with new records. bfr = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("records.temp"))); StringBuffer sBuffer = new StringBuffer(); for (ArrayList<String> list : data) { StringBuffer buf = new StringBuffer(); for (String val : list ) { buf.append(val+"t"); } buf.replace(buf.length() - 1,buf.length(),"n"); sBuffer.append(buf.toString()); } bfr.write(sBuffer.toString()); bfr.flush(); bfr.close(); fireTableRowsDeleted(row,row); } catch (Exception ex) { data.add(row,temp);//Rollback the delete from ArrayList ex.printStackTrace(); } finally { if (bfr != null) { try { bfr.close(); } catch (Exception ex){} } } } } public static void main(String[] args) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { TableFocus ths = new TableFocus(); ths.createAndShowGUI(); } }); } } UPDATE
在完成您的代码之后,我了解了删除多行的情况.情况是:如果文件中有多行,则从您要删除的记录的相同用户ID开始. 85 lo ii Female 2013/03/08 86 jkj nmn Female 2013/03/08 52 tyr fgfg Female 2013/03/08 86 jkj pqr Male 2013/03/08 7 dfdf wew Female 2013/03/08 47 zczc asa Female 2013/03/08 16 erw www Male 2013/03/08 83 gfg dsd Male 2013/03/08 这里userID 86包含在两行中(第2行和第4行).当您在JTable中选择第4行以删除该特定记录时,它会从您的文件中删除第2行和第4行.但在JTable中,第二行将继续显示,因为直到现在它都没有使用新文件刷新.只要用新文件刷新JTable,它就会显示从那里删除的行. while ((line = Ubr.readLine()) != null) //Reads the file till the end. { if (line.trim().length() == 0) { continue; } if (!line.startsWith(String.valueOf(getValueAt(index,0)))) //If line starts with 86 don't write it to new `Uoutput.txt`. so all lines starting with 86 will be ignored. { Upw.println(line);//Lines starting with 86 is not written. } } 我希望你现在有充分的理由知道为什么有时从JTable中删除一条记录会从你的文件中删除两行或两行以上. public void RemoveRow(int rowIndex) { UserInformation temp = Udata.get(rowIndex);//Keep it as back up so that you could reconsolidate it to ArrayList in case RemoveUserFromFile return false Udata.remove(rowIndex);//remove the element from Udata on temporary basis. if (RemoveUserFromFile(rowIndex)) { fireTableRowsDeleted(rowIndex,rowIndex); } else { Udata.add(rowIndex,temp);//re-insert temp in ArrayList as the file updation is failed. JOptionPane.showMessageDialog(null,"Unable to delete"); } } public boolean RemoveUserFromFile(int index) { File Mf = new File("AllUserRecords.txt"); File Tf = new File("Uoutput.txt"); PrintWriter Upw = null; try { Upw = new PrintWriter(new FileWriter(Tf)); for (UserInformation uino : Udata ) { Upw.print(uino.toString());//Don't use Upw.println because the toString() method of UserInformation class is already using n in last. } Upw.close(); Mf.delete(); Tf.renameTo(Mf); return true; } catch (FileNotFoundException e1) { return false; } catch (IOException ioe) { return false; } finally { if (Upw != null) { try { Upw.close(); } catch (Exception ex){} } } } 我希望现在能解决你的问题…… 注意:作为旁注.我想建议你在编写代码时坚持使用java命名约定.例如:类名始终以大写字母开头.变量名称始终以小写字母开头.常数(即最终变量)的所有字母都是大写的.还有很多其他的.看看oracle的official site. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |