2009-12-10 9 views
5

मुझे कोई समस्या है और उम्मीद है कि कोई जानता है कि क्या गलत हो रहा है और मुझे यह बताएं कि मैं इस चीज़ को काम करने के लिए अभी क्या खो रहा हूं सुझाव दिया।स्विंग प्रश्न/जेटीआर/कस्टम पेड़ मॉडल

मेरे पास एक जेट्री है जो एक कस्टम ट्रीमोडेल ("डब्लूआरटीएम मॉडल", नीचे देखें) पर आधारित है। इस मॉडल का डेटा संरचना एक रूट ऑब्जेक्ट का निर्माण करने के लिए उपयोग की जाएगी जिसमें कुछ फ़ील्ड शामिल हैं और इसके अलावा नीचे दी गई "ArrayListModel" द्वारा समर्थित एक सूची है। जब मैं इसे WRTreeModel का उपयोग कर बनाता हूं तो पेड़ ठीक दिखता है। मैं नोड्स को विस्तार और पतन करने में सक्षम हूं जो वस्तुओं में निहित सूचियों और फ़ील्ड का प्रतिनिधित्व करते हैं। मैं इन सूचियों का विस्तार और पतन कर सकता हूं और उनकी सामग्री को भी देख सकता हूं।

अब मैं सूचियों में से किसी एक बच्चे को हटाना चाहता हूं - जैसा कि मुझे पहले से ही पता है - इसे ArrayListModel की निकालने विधि को कॉल करने वाले मॉडल से इसे हटाकर करें। WRTreeModel को उस निकालने के बारे में जागरूक करने के लिए, पहली बात यह है कि उसकी आग को कॉल करना अंतराल हटाया गया तरीका कहा जाता है, अब तक इतना अच्छा है।

WRTreeModels में भीतरी वर्ग ArrayModelListener intervalRemoved विधि fireTreeNodesRemoved की कॉल जो फिर एक TreeEvent जो सभी पंजीकृत TreeModelListeners को भेजा जाता है बनाता है तैयार करता है (और इसलिए JTree जो अपने आप automaticall जब यह मॉडल से कनेक्ट होने पर पंजीकृत करता है)।

अब मैं उम्मीद करता हूं कि पेड़ परिवर्तन को प्रतिबिंबित करता है और नए राज्य को दिखाने के लिए आंतरिक और दृश्य प्रतिनिधित्व को अद्यतन करता है। दुर्भाग्यवश ऐसा लगता है कि ऐसा नहीं लगता है। कुछ हुआ है। लेकिन जब मैं नोड पर क्लिक करता हूं तो मैंने कुछ इवेंट हैंडलर-अपवादों को फेंक दिया है। स्पष्ट रूप से कुछ वास्तव में भ्रमित हो गया।

मुझे पता है कि फ्लाई पर ऐसे प्रश्न का उत्तर देना आसान नहीं है लेकिन मैं वास्तव में तेज़ उत्तर की सराहना करता हूं। यदि कोई कस्टम पेड़ मॉडल (डिफ़ॉल्ट डिटटेबल ट्रीनोड या किसी भी दिए गए कार्यान्वयन आधारित वर्ग पर नहीं) और ईवेंट जेड्री कार्यों के संचालन और अद्यतन के उपयोग की व्याख्या करने वाली वेबसाइटों को जानता है, तो यह भी मददगार होगा।

साथ सादर

,

थॉमस कला


public class ArrayListModel<E> extends ArrayList<E> implements ListModel { 

... 

public E remove(int index) { 
    fireIntervalRemoved(index, index); 
    E removedElement = super.remove(index); 
    return removedElement; 
    } 

... 

} 

public class WRTreeModel extends LogAndMark implements TreeModel { 


    class ArrayModelListener implements ListDataListener { 

    ... 

    @Override 
    public void intervalRemoved(ListDataEvent e) { 
     int[] indices = new int[e.getIndex1() - e.getIndex0() + 1]; 
     for (int i = e.getIndex0(); i < e.getIndex1(); i++) 
     indices[i - e.getIndex0()] = i; 
     fireTreeNodesRemoved(e.getSource(), getPathToRoot(e.getSource()), indices,  ((ArrayListModel<?>)e.getSource()).subList(e.getIndex0(), e.getIndex1()+1).toArray()); 
    } 

    ... 

    } 

    public Object[] getPathToRoot(Object child) { 
    ArrayList<Object> ret = new ArrayList<Object>(); 
    if (child == null) 
     return ret.toArray(); 
    ret.add(root); 
    if (child == root) 
     return ret.toArray(); 
    int childType = 0; 
    if (child instanceof List<?> && ((List) child).get(0) instanceof Einleitungsstelle) { 
     childType = 1; 
    } 
    if (child instanceof Einleitungsstelle) { 
     childType = 2; 
    } 
    if (child instanceof List<?> && ((List) child).get(0) instanceof Messstelle) { 
     childType = 3; 
    } 
    if (child instanceof Messstelle) { 
     childType = 4; 
    } 
    if (child instanceof List<?> && ((List) child).get(0) instanceof  Ueberwachungswert) { 
     childType = 5; 
    } 
    if (child instanceof Ueberwachungswert) { 
     childType = 6; 
    } 
    if (child instanceof List<?> && ((List) child).get(0) instanceof  Selbstueberwachungswert) { 
     childType = 7; 
    } 
    if (child instanceof Selbstueberwachungswert) { 
     childType = 8; 
    } 
    switch (childType) { 
    // List of ESTs 
    case 1: { 
     ret.add(child); 
     break; 
    } 
    // EST 
    case 2: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     ret.add(child); 
     break; 
    } 
    // List of MSTs 
    case 3: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
     if (child == einleitungsstelle.getListOfMST()) { 
      ret.add(einleitungsstelle); 
      break; 
     } 
     } 
     ret.add(child); 
     break; 
    } 
    // MST 
    case 4: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
      if (child == einleitungsstelle.getListOfMST()) { 
      ret.add(einleitungsstelle.getListOfMST()); 
      break; 
      } 
     } 
     ret.add(child); 
     break; 
    } 
    // List of UEWs 
    case 5: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
     ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST(); 
     if (child == listOfMST) { 
      ret.add(listOfMST); 
      for (Messstelle messstelle : listOfMST) { 
      if (child == messstelle.getListOfUEW()) { 
       ret.add(messstelle.getListOfUEW()); 
       break; 
      } 
      } 
      break; 
     } 
     } 
    break; 
    } 
    // UEW 
    case 6: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
     ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST(); 
     if (child == listOfMST) { 
      ret.add(listOfMST); 
      for (Messstelle messstelle : listOfMST) { 
      if (child == messstelle.getListOfUEW()) { 
       ret.add(messstelle.getListOfUEW()); 
       break; 
      } 
      } 
      break; 
     } 
     } 
     ret.add(child); 
     break; 
    } 
    // List of SUEWs 
    case 7: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
     ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST(); 
     if (child == listOfMST) { 
      ret.add(listOfMST); 
      for (Messstelle messstelle : listOfMST) { 
      if (child == messstelle.getListOfSUEW()) { 
       ret.add(messstelle.getListOfSUEW()); 
       break; 
      } 
      } 
      break; 
     } 
     } 
     break; 
    } 
    // SUEW 
    case 8: { 
     List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST(); 
     ret.add(listOfEST); 
     // Find the EST containing the List of MSTs the child referes to 
     for (Einleitungsstelle einleitungsstelle : listOfEST) { 
      ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST(); 
      if (child == listOfMST) { 
      ret.add(listOfMST); 
      for (Messstelle messstelle : listOfMST) { 
      if (child == messstelle.getListOfSUEW()) { 
       ret.add(messstelle.getListOfSUEW()); 
       break; 
      } 
      } 
      break; 
     } 
     } 
     ret.add(child); 
     break; 
     } 
     default: 
     ret = null; 
    } 
    return ret.toArray(); 
    } 
    } 

... 

    protected void fireTreeNodesRemoved(Object changed, Object path[], int  childIndecies[], Object children[]) { 
     TreeModelEvent event = new TreeModelEvent(this, path, childIndecies, children); 
     synchronized (listeners) { 
     for (Enumeration e = listeners.elements(); e.hasMoreElements();) { 
     TreeModelListener tml = (TreeModelListener) e.nextElement(); 
     tml.treeNodesRemoved(event); 
     } 
     } 
    } 

... 

} 
+0

पता नहीं है कि यह और मदद की है, लेकिन जब मैं पतन करने की कोशिश करता हूं और फिर हटाए गए नोड के पैरेंट नोड का विस्तार करता हूं तो मुझे निम्न अपवाद मिलता है: थ्रेड में अपवाद "एडब्ल्यूटी-इवेंट क्यूयू -0" java.lang। NullPointerException \t javax.swing.plaf.basic.BasicTreeUI.ensureRowsAreVisible (BasicTreeUI.java:1881) \t पर javax.swing.plaf.basic.BasicTreeUI.toggleExpandState पर (BasicTreeUI.java:2208) \t javax.swing पर। plaf.basic.BasicTreeUI.handleExpandControlClick (BasicTreeUI.java:2191) \t javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl पर (BasicTreeUI.java:2149) \t पर ... और –

+0

पर सभी समस्याएं परिभाषा से जरूरी हैं :-) मैं एक प्रश्न में "समय दबाव" का उल्लेख नहीं करता। और आपका प्रश्न रहने और दूसरों की मदद करने के लिए है जब आप इसके बारे में लंबे समय से भूल गए हैं। यह और अधिक canonical बनाता है। – raoulsson

उत्तर

2

आप नोड हटाने की कार्यवाही करने और जरूरत बाद में TreeModelListener.treeNodesRemoved घटना घटना डिस्पैच थ्रेड पर फायरिंग। ऐसा करने से आपके हटाने और घटना फायरिंग बताता JTree नियंत्रण के बीच में पेड़ (जो श्रोताओं जोड़ा गया है) मॉडल है कि अद्यतन करने के लिए EDT का उपयोग कर स्विंग से बचाता है

SwingUtilities.invokeLater(
    new Runnable() 
    { 
    public void run() 
    { 
     //Delete and event firing logic goes here. 
     ... 
    } 
    } 
); 

:

इस प्रयोग करने के लिए बदल गया है।

+0

वह और इसके अलावा एक Tree.updateUI() को निम्न विस्तार के साथ पथ के साथ पथ (पथ) हटाए गए तत्व माता-पिता वास्तव में वह काम करते हैं जो मैं चाहता था। धन्यवाद उस संकेत के लिए बहुत कुछ! बीटीडब्लू: स्विंगउटीसिटीज.वोकोकलेटर का उपयोग करने लगता है, यह इतना आम है कि कोई भी कभी नहीं सोचता कि दूसरों को अपना ईवेंट और यूआई सामान अंदर रखना भूल जाता है। मेरे विचार को दूर करने के लिए –

+0

+1। –

+0

@ करल: धन्यवाद :-) –

0

क्योंकि हम जल्दी मैं अपने कोड पर अभी तक देखा नहीं किया है में हैं। आपका विवरण लगता है जैसे आप सब कुछ सही तरीके से कर रहे हैं और इसके बारे में सोचा है कि क्या आवश्यक है।

मेरा अनुमान है कि आपने ऐसा नहीं माना होगा: क्या यह वृक्ष मॉडल इवेंट डिस्पैच थ्रेड (उर्फ स्विंग वर्कर थ्रेड) में हो रहा है? यदि परिवर्तन किसी अन्य धागे से आता है तो संभावना है कि इसे ठीक से संसाधित नहीं किया जाएगा।

बिल्कुल अंधेरे में एक स्टैब, ज़ाहिर है।

+0

मुझे लगता है कि यह सही धागे में हो रहा है। जब मैं fireTreeNodes में ब्रेकपॉइंट होने पर डीबग करता हूं तो रीडवर्ड विधि यह एडब्ल्यूटी-इवेंट क्यूई थ्रेड में रुक जाती है। जो सही लगता है। –

+0

आप सही हैं। ऊपर दिए गए उत्तर को देखें जो कि सुझाव दिया गया है, और वास्तव में यह एक आकर्षण की तरह काम करता है :-) –

+0

उत्कृष्ट! मुझे खेद है कि मैं भी जल्दी में था (एक बैठक के लिए जमानत करनी थी) और उसे फिक्स की सिफारिश करने का मौका नहीं मिला। –

0

ऐसा लगता है कि आपके पास अंतराल में एक-एक-एक बग है।

आप इंडेक्स सरणी में अंतिम मान प्रारंभ नहीं कर रहे हैं। यह 0 से स्वचालित हो जाएगा।

@Override 
public void intervalRemoved(ListDataEvent e) { 
    int[] indices = new int[e.getIndex1() - e.getIndex0() + 1]; 
    for (int i = e.getIndex0(); i < e.getIndex1(); i++) 
    indices[i - e.getIndex0()] = i; 
    fireTreeNodesRemoved(e.getSource(), getPathToRoot(e.getSource()), indices,  ((ArrayListModel<?>)e.getSource()).subList(e.getIndex0(), e.getIndex1()+1).toArray()); 
} 

बजाय प्रयास करें "मैं < = e.getIndex1()":

for (int i = e.getIndex0(); i <= e.getIndex1(); i++) { 
    indices[i - e.getIndex0()] = i; 
} 
+0

आप इसके साथ बिल्कुल सही हैं। विधि विवरण में वही कहा गया है। मैंने तय किया कि हालांकि मेरी समस्या पर इसका कोई प्रभाव नहीं पड़ा क्योंकि सूची तत्व जिसे मैं निकालने का प्रयास करता हूं वह पहला है और इसलिए सूचकांक 0 ठीक है। –

0

विधि नाम fireIntervalRemoved है, इसलिए दूर करने के बाद यह बुला की कोशिश:

public E remove(int index) { 
    E removedElement = super.remove(index); 
    fireIntervalRemoved(index, index); 
    return removedElement; 
} 

यह मैंने किया है, और हमेशा काम किया (शायद कुछ जांच जोड़ा)।
(खेद है कि मैं कुछ याद किया,/analise करने के लिए समय मिलता हमारा इस तरह अपने कोड का परीक्षण ...)

+0

क्या मुझे अपने TreeEvent के निर्माण के लिए हटाए गए तत्व को जानने की आवश्यकता नहीं है? यदि मैं तत्व को हटाने के बाद fireIntervalRemoved (अनुक्रमणिका, अनुक्रमणिका) को कॉल करता हूं तो मैं इसे और नहीं प्राप्त कर सकता। यही कारण है कि मैंने सूची से वास्तविक निकालने से पहले कॉल को स्थानांतरित कर दिया। –

+0

यकीन नहीं है, सभी कोड की जांच नहीं की है और 'fireIntervalRemoved' नहीं मिल रहा है। TreeModelEvent को तत्व की आवश्यकता नहीं है, जैसा कि मुझे पता है ... मुझे लगता है कि अगर आप ईवेंट को आग लगते हैं और जीयूआई तत्व को हटाने से पहले अपडेट किया जाता है (तेज़ पर्याप्त), तो पेड़ निकालने को प्रतिबिंबित नहीं करेगा (क्योंकि यह अभी तक नहीं हुआ है)। हो सकता है कि आप तत्व को हटाने से पहले ईवेंट का निर्माण कर सकें और ईवेंट को निकालने के बाद ईवेंट को फायर कर सकें ... ((* ग्रस ऑस स्टुटगार्ट *)) –

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