2011-05-28 12 views
9

किसी तालिका में एक टेबलरॉर्टर जोड़ने के बाद और इसके संबंधित मॉडल को विशेष रूप से फ़ायरटेबलबैलेरोइन्सर्टेड कारण अपवादों पर जोड़ा जाता है। यह परीक्षण से स्पष्ट है कि GetRowCount() मॉडल रेंज के पीछे एक मूल्य लौटा रहा है। हालांकि यह मुझे समझ में नहीं आता है कि सॉर्टर या फ़िल्टर जोड़े जाने के बाद तालिका में मूल्य जोड़ने के लिए कैसे जारी रखें?मॉडल कारणों में मान जोड़ने वाले TableRowSorter जोड़ने के बाद java.lang.IndexOutOfBoundsException: अमान्य रेंज

एक उदाहरण के रूप में, मैं मेज पर कुछ भी जोड़ने से पहले पंक्ति फ़िल्टर सेट तो अपने मॉडल में निम्नलिखित कॉल के साथ तालिका में एक मूल्य जोड़ने:

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

rowcount आकार 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) कोडित और यह किसी भी अपवाद नहीं है। लेकिन टेबल में कुछ भी जोड़ा नहीं जाता है? इसलिए, मुझे पता है कि यह निश्चित रूप से आउटऑफबाउंड मुद्दे का कुछ प्रकार है। मैंने पूरे देखा है और उत्तर नहीं ढूंढ रहा है। अगर किसी को यह पता है कि यह काम करने का अनुमान है तो यह बहुत उपयोगी होगा। ऐसा लग रहा है कि आप अपने मॉडल में जाँच करता है, तो

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

+0

+1 @Whired है - अपने स्वयं के उत्तर में @ पॉल की टिप्पणी में टिप्पणी देखें: आपके भीतर एक ही त्रुटि। बीटीडब्लू, कभी मॉडल के _outside_ से एक मॉडल घटना आग नहीं। रुचि रखने वाले पक्षों को सूचित करने के लिए यह मॉडल की अनन्य ज़िम्मेदारी है ... – kleopatra

उत्तर

0

तो, अब के लिए:

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); 

यहाँ मेरी मॉडल के अंदर कोड है कि मॉडल के लिए मूल्य कहते हैं: यहाँ कोड है कि JPanel के अंदर सॉर्टर सेट है यदि आप वर्तमान में सॉर्टिंग मोड में हैं और यदि मामला है तो सॉर्टिंग मॉडल पर केवल कॉल अपडेट करें। अन्यथा सामान्य मॉडल आग अपडेट को कॉल करें सब कुछ अब तक काम करता प्रतीत होता है। मैं अभी भी इसे संभालने के बेहतर तरीकों के लिए खुला हूं हालांकि:

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

बस गलत - बंद एक के बाद, यह शून्य आधारित सूचकांक – kleopatra

2

आपके पास 1 त्रुटि से बाहर है। घटना फायरिंग के लिए सही कोड है:

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

अपना उत्तर संपादित करने पर विचार करें: आपके कोड में मिली त्रुटि ओपीएस कोड में अंतर्निहित त्रुटि के समान है :-) – kleopatra

+0

@ क्लेओपात्रा, अच्छा सुझाव, मैंने अपना संपादन किया है जवाब दें तो यह सिर्फ जवाब है। – Paul

3

मैं वापस चला गया और Kleopatra की टिप्पणी को देखने के बाद इस पर एक बेहतर नज़र डाली। मैं रोसॉर्टर बनाने के बाद अपना टेबल मॉडल बदल रहा था, लेकिन JTable को RowSorter को जोड़ने से पहले। यहां एक उदाहरण दिया गया है जो मेरी समस्या को दिखाता है।

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

+0

@ क्लेओपेट्रा आप सही हैं। मैंने आज वास्तविक कारण को ट्रैक किया और मैंने अपना जवाब अपडेट कर लिया है। –

+0

आप मूल भाग को हटाने पर विचार कर सकते हैं - गलत चीजें दिमाग में रहती हैं :-) – kleopatra

संबंधित मुद्दे