2011-05-28 33 views
9

添加一個TableRowSorter到表和任何相應的其相應的模型之後,在firetabletablerowsinserted原因的異常增加特異性。從測試中可以明顯看出,GetRowCount()正在返回超出模型範圍的值。然而,它沒有任何意義,我該如何繼續使用已加入分類器或過濾後的值添加到表?添加一個TableRowSorter添加值以引起java.lang.IndexOutOfBoundsException模型後:無效範圍

舉個例子,我設置行過濾器添加任何表在此之前的值添加到表在我的模型以下呼叫:

this.addRow(row, createRow(trans,row)); 
this.fireTableRowsInserted(this.getRowCount(), this.getRowCount()); 

行數是1型和異常的拋出:

java.lang.IndexOutOfBoundsException: Invalid range 
at javax.swing.DefaultRowSorter.checkAgainstModel(Unknown Source) 
at javax.swing.DefaultRowSorter.rowsInserted(Unknown Source) 
at com.gui.model 

如果我做同樣的步驟,如果沒有事先添加分揀機一切正常。我以爲,可能我需要通知分揀機可能已經進行了更改,並試圖模型以下,但仍然會返回一個例外:

this.addRow(row, createRow(trans,row)); 
this.fireTableStructureChanged() 
this.fireTableRowsInserted(this.getRowCount(), this.getRowCount()); 

我甚至試圖通知值已增加了模型內部分揀機調用火象下面前的模式,但它也將失敗:

this.addRow(row, createRow(trans,row)); 
if(sorter.getRowFilter() != null){ 
     //if a sorter exists we are in add notify sorter 
     sorter.rowsInserted(getRowCount(), getRowCount()); 
    } 
    this.fireTableRowsInserted(this.getRowCount(), this.getRowCount()); 

最後,我硬編碼的FireTableRowsInsterted(0,0),它不拋出任何異常。但沒有添加到表中?所以,我知道這絕對是某種類型的OutOfBounds問題。 我到處都找過,似乎無法找到答案。如果任何人有任何想法如何工作這是非常有益的。 這裏是代碼,設置裏面的JPanel分揀機:

messageTable.setRowSorter(null); 
    HttpTransactionTableModel m = getTransactionTableModel(); 
    final int statusIndex = m.getColIndex("status"); 
    RowFilter<Object,Object> startsWithAFilter = new RowFilter<Object,Object>() { 
      public boolean include(Entry<? extends Object, ? extends Object> entry) { 

       for(char responseCode:responseCodes) 
       { 
        if (entry.getStringValue(statusIndex).startsWith(Character.toString(responseCode))) { 
         return true; 
         } 
       } 


      // None of the columns start with "a"; return false so that this 
      // entry is not shown 
      return false; 
      } 
     }; 


     m.sorter.setRowFilter(startsWithAFilter); 
     messageTable.setRowSorter(m.sorter); 

這裏是我的模型內部代碼附加價值的模型:

public void update(Observable o, Object evt) { 
    if (evt instanceof ObservableEvent<?>) { 

     ObservableEvent<?> event = (ObservableEvent<?>) evt; 

     if (event.getElement() instanceof HttpTransaction) { 

      HttpTransaction trans = (HttpTransaction) event.getElement(); 

      // handle adding of an element 
      if (event.getAction() == PUT) { 

       if (includeTransaction(trans)) { 

        // handle request elements 
        if (trans.getRequest() != null && idMap.get(trans.getID()) == null) { 

         idMap.put(trans.getID(), count++); 
         // transactionManager.save(trans); 
         int row = idMap.get(trans.getID()); 
         this.addRow(row, createRow(trans,row)); 
         if(sorter.getRowFilter() != null){ 
          sorter.rowsInserted(getRowCount(), getRowCount()); 
         } 
         this.fireTableRowsInserted(this.getRowCount(), this.getRowCount()); 

        } 
+3

'this.fireTableRowsInserted(this.getRowCount(),this.getRowCount());' - 關閉的一個,它的零基指數 – Whired 2012-06-04 18:21:26

+0

+1 @Whired - 好斑點:-) – kleopatra 2012-08-17 15:19:44

回答

0

所以,現在看起來,如果你在你的模型檢查如果您目前處於排序模式,並且如果是這種情況,則只能在排序模型上調用更新。否則,調用普通模型火災更新一切似乎工作到目前爲止。我仍然開放更好的方法來處理這個問題,但:1個錯誤

      if(sorter.getRowFilter() != null){ 
          sorter.modelStructureChanged(); 
          } 
          else 
         this.fireTableRowsInserted(this.getRowCount(), this.getRowCount()); 
+0

完全錯誤 - 在@Paul的評論中看到他自己的回答:在你的同樣的錯誤。順便說一句,從來沒有從模型的外側發起模型事件。這是模型的獨家責任通知有關方面... – kleopatra 2012-08-17 15:14:42

2

您有一個出來。正確的代碼發射事件是:

this.fireTableRowsInserted(this.getRowCount()-1, this.getRowCount()-1); 
+0

考慮編輯答案:你在你的代碼中發現的錯誤是一樣的OP代碼的底層錯誤:-) – kleopatra 2012-08-17 15:12:27

+0

@kleopatra,好建議,我已經編輯我的回答,所以這只是答案。 – Paul 2013-05-09 20:57:00

3

我回去,並在看到kleopatra的評論後有一個更好的看看。我改變我的TableModel創建一個RowSorter的經過,但附加了RowSorter的到JTable之前。這是一個顯示我遇到問題的例子。

import javax.swing.*; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableRowSorter; 
import java.util.ArrayList; 
import java.util.List; 

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

    public TestTableMain() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       buildAndShowMainFrame(); 
      } 
     }); 
    } 

    private void buildAndShowMainFrame() { 
     JFrame frame = new JFrame(); 
     JScrollPane scrollPane = new JScrollPane(); 

     TestTableModel model = new TestTableModel(); 
     JTable table = new JTable(model); 

     TableRowSorter<TestTableModel> rowSorter = new TableRowSorter<>(model); 
     rowSorter.setRowFilter(null); 

     model.add("First added item."); 
     /* The RowSorter doesn't observe the TableModel directly. Instead, 
     * the JTable observes the TableModel and notifies the RowSorter 
     * about changes. At this point, the RowSorter(s) internal variable 
     * modelRowCount is incorrect. There are two easy ways to fix this: 
     * 
     * 1. Don't add data to the model until the RowSorter has been 
     * attached to the JTable. 
     * 
     * 2. Notify the RowSorter about model changes just prior to 
     * attaching it to the JTable. 
     */ 

     // Uncomment the next line to notify rowSorter that you've changed 
     // the model it's using prior to attaching it to the table. 
     //rowSorter.modelStructureChanged(); 
     table.setRowSorter(rowSorter); 

     scrollPane.setViewportView(table); 
     frame.setContentPane(scrollPane); 

     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 

     model.add("Second added item."); 
    } 

    private class TestTableModel extends AbstractTableModel { 
     private List<String> items = new ArrayList<>(); 

     public TestTableModel() { 
      for(int i=0;i<5;i++) { 
       add("Item " + i); 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return items.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 1; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return items.get(rowIndex); 
     } 

     public void add(String item) { 
      items.add(item); 
      fireTableRowsInserted(items.size() - 1, items.size() - 1); 
     } 
    } 
} 
+1

根本就是錯誤的 - 從來沒有嘗試第二猜測正常的內部更新。相反,嘗試在你的代碼中找到錯誤,而不是隨機添加東西;-) – kleopatra 2012-08-17 15:10:17

+0

@kleopatra你說得對。我今天追查了實際的原因,並且更新了我的答案。 – 2012-08-17 22:29:39

+0

你可能會考慮刪除原來的部分 - 錯誤的東西往往會牢牢記住:-) – kleopatra 2012-08-18 07:11:17

相關問題