2013-02-11 217 views
1

我有一個jtable保留書籍文件記錄和sho它們。更改Jtable單元格值

我創建了一個「借用」jbutton,當點擊一個不借用的行時,該行的「借入狀態」應該變爲「是」。

我使用此代碼,但沒有改變!

public class user_AllBooks extends AbstractTableModel{ 
BookInformation book_info=new BookInformation(); 
String[] columns=new String[]{"Book Name","Book Date", "Book ID","Borrow Status"}; 
ArrayList<BookInformation> bData=new ArrayList<BookInformation>(); 

public user_AllBooks(){ 
    try{ 
     BufferedReader br=new BufferedReader(new FileReader("AllBookRecords.txt")); 
     String line; 
     while((line = br.readLine()) != null){ 
      bData.add(initializeBookData(line)); 
     } 
     br.close(); 
    } 
    catch(IOException ioe){ 

    } 
} 

public BookInformation initializeBookData(String myline){ 
    BookInformation book_infos=new BookInformation(); 
    String[] celledLine=myline.split("  "); 
    book_infos.setBookName(celledLine[0]); 
    book_infos.setBookDate(celledLine[1]); 
    book_infos.setBookID(celledLine[2]); 
    book_infos.setBorrowStatus(celledLine[3]); 
    return book_infos; 
} 

@Override 
public String getColumnName(int col){ 
    return columns[col]; 
} 

@Override 
public int getRowCount() { 
    if(bData != null){ 
     return bData.size(); 
    } 
    else{ 
     return 0; 
    } 
} 

@Override 
public int getColumnCount() { 
    return columns.length; 
} 

@Override 
public Object getValueAt(int rowIndex, int columnIndex) { 
    BookInformation bookInf=bData.get(rowIndex); 
    Object value; 

    switch(columnIndex){  
     case 0: 
      value=bookInf.getBookName(); 
      break; 
     case 1: 
      value=bookInf.getBookDate(); 
      break; 
     case 2: 
      value=bookInf.getBookID(); 
      break; 
     case 3: 
      value=bookInf.getBorrowStatus(); 
      break; 
     default : 
      value="..."; 
    } 
    return value;  
} 
} 

二等:

public class user_AllBooksM extends JFrame implements ActionListener{ 
user_AllBooks uAllBooks=new user_AllBooks(); 
final JTable bTable=new JTable(uAllBooks); 
JButton borrowButton; 
public user_AllBooksM(){ 
    setTitle("All Books"); 
    exitButton=new JButton("Exit"); 
    borrowButton=new JButton("Borrow"); 
    borrowButton.addActionListener(this); 
    JPanel Bpanel=new JPanel(); 
    Bpanel.setLayout(new FlowLayout()); 
    JScrollPane sp=new JScrollPane(bTable); 
    Bpanel.add(sp); 
    Bpanel.add(borrowButton); 
    this.add(Bpanel); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setBounds(300, 60, 550, 550); 
    this.setResizable(false); 
    this.setVisible(true); 
} 

@Override 
public void actionPerformed(ActionEvent event) { 
     borrowInitialize(bTable.getSelectedRow()); 
} 

public void borrowInitialize(int row){ 
    if(uAllBooks.getValueAt(row, 3).equals("yes")) { 
     JOptionPane.showMessageDialog(null, "This Book Was Borrowed"); 
    } 
    else{ 
     uAllBooks.setValueAt("Yes", row, 3); 
     uAllBooks.fireTableRowsUpdated(row, row); 
    } 
} 

public static void main(String[] args){ 
    new user_AllBooksM(); 
} 

} 

感謝。

+0

您沒有重寫'user_AllBooks'中的'setValueAt'。您應該 – 2013-02-11 18:49:26

回答

5

要覆蓋setValueAt你應該使用:

@Override 
public void setValueAt(Object value, int row, int col) 
{ 
    BookInformation book_infos = bData.get(row); 
    if (col==0) 
    book_infos.setBookName((String)value); 
    else if (col==1) 
    book_infos.setBookDate((String)value); 
    else if (col==2) 
    book_infos.setBookID((String)value); 
    else if (col==3) 
    book_infos.setBorrowStatus((String)value); 
    fireTableCellUpdated(row,col); 
} 

user_AllBooks

+0

應該沒有必要在setValueAt中調用fireTableDataChanged,因爲普通的可編輯表將爲您執行此操作。可能更好地使用setBorrowed方法 – MadProgrammer 2013-02-11 19:03:54

+0

@MadProgrammer:我添加了這個方法來確保更改的值肯定會反映在表中。是不必要的電話? – 2013-02-11 19:07:27

+0

這種方法是否適合setBorrow或不? – Sajad 2013-02-11 19:07:30

3

您已重寫getValueAt方法。所以它總是從你的陣列列表中返回值。

public Object getValueAt(int rowIndex, int columnIndex) { 
    BookInformation bookInf=bData.get(rowIndex); 

所以,你需要實現setValueAt方法也是在你的表格模型,以便更改bData ArrayList的實際數據。

另請注意,bTable.getSelectedRow()將根據視圖給出所選行。在模型中,如果對錶進行排序,則索引可能會有所不同。

3

內定義這個方法你可以使用TableModel#setValueAt,但你也將成爲負責更新的表,它打破了MCV模型。

相反,您可以將setBorrowed方法添加到user_AllBooks類中。

public void setBorrowed(int row, boolean borrowed) { 
    BookInformation book = bData.get(row); 
    book.setBorrowedState(borrowed); 
    fireTableCellUpdated(row, 3); 
} 
+1

-1,這是setValueAt()方法的工作。首先它更新包含模型數據的數據結構。然後TableModel負責在單元格內容發生變化時通知表格。 TableModel通過調用fireTableCellUpdated(...)方法來完成此操作,這與您在此處完成的操作相同。這可以被認爲是一個調用setValueAt(借用,行,3)的便利方法。 – camickr 2013-02-11 23:03:55

+0

@camickr謝謝你至少告訴我爲什麼我是一個沖洗袋;) - 很感激。我看了一下'DefaultTableModel',它確實使用'fireTableCellUpdated'。我關心的是(我希望你能幫助我),當使用'AbstractTableModel'時,我從來沒有必要調用它,因爲表似乎會自動更新它自己。發射另一個事件是否有點矯枉過正,可能導致雙重打印? (當然,在大多數情況下,它是一個單元格,只是對另一個視點感興趣) – MadProgrammer 2013-02-12 00:30:38

+0

使用setValueAt(...)方法將編輯器中的數據保存到模型中。然後編輯器從表中刪除,導致單元被重新繪製。因此,即使setValueAt(...)方法未觸發更新事件,您仍然可以使用新值重繪表。但是,當數據發生變化時,通知視圖肯定是模型的責任。雙重重繪是由JTable實現編輯代碼的方式引起的。 – camickr 2013-02-12 02:34:16