2012-09-12 14 views
6

में फोर्बिड टैब परिवर्तन, मैं वर्तमान टैब मान्य नहीं होने पर उपयोगकर्ता को टैब बदलने से रोकने की कोशिश कर रहा हूं। तो जब वह किसी टैब पर क्लिक करता है, तो मैं यह जांचना चाहता हूं कि वर्तमान वाला "मान्य" है, और यदि नहीं, तो वर्तमान टैब पर बने रहें। मैं एक VetoableChangeListener जो काम नहीं किया उपयोग करने के लिए कोशिश की, कोड कभी नहीं vetoableChange विधि के अंदर चला जाता:JTabbedPane

jTabbedPane.addVetoableChangeListener(new VetoableChangeListener() { 

    @Override 
    public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { 
    if (!isCurrentTabValid()) { 
     throw new PropertyVetoException("test", evt); 
    } 
    } 
}); 

मैं इस ठीक से कैसे कर सकते हैं?

धन्यवाद!

उत्तर

14

एक VetoableChangeListener केवल तभी उपयोगी होता है जब वह जिस श्रेणी में पंजीकृत है, वह एक vetoable propertyChange आग के साथ पंजीकृत है। अधिकांश (सभी? कभी भी एक नहीं आया) JComponents और subclasses पर गुण vetoable नहीं हैं। इसके अलावा चयन को एकल चयन मॉडल द्वारा संभाला जाता है, न कि घटक स्वयं।

मॉडल हुक vetoable बदलता है

  • कि चयन परिवर्तन पर एक vetoablePropertyChange आग कस्टम मॉडल को लागू करने का समर्थन है कि
  • अगर अपने श्रोताओं में से कोई भी, परिवर्तन के साथ आगे बढ़ो वस्तु, अन्यथा कुछ भी नहीं
  • करना
  • tabbedPane
  • करने के लिए कस्टम मॉडल सेट एक VetoablePropertyChangeListener जो मान्यता तर्क
  • रजिस्टर vetoableList शामिल लागू मॉडल
कोड में

,

public static class VetoableSingleSelectionModel extends 
     DefaultSingleSelectionModel { 

    private VetoableChangeSupport vetoableChangeSupport; 

    @Override 
    public void setSelectedIndex(int index) { 
     if (getSelectedIndex() == index) 
      return; 
     try { 
      fireVetoableChange(getSelectedIndex(), index); 
     } catch (PropertyVetoException e) { 
      return; 
     } 
     super.setSelectedIndex(index); 
    } 

    private void fireVetoableChange(int oldSelectionIndex, 
      int newSelectionIndex) throws PropertyVetoException { 
     if (!isVetoable()) 
      return; 
     vetoableChangeSupport.fireVetoableChange("selectedIndex", 
       oldSelectionIndex, newSelectionIndex); 

    } 

    private boolean isVetoable() { 
     if (vetoableChangeSupport == null) 
      return false; 
     return vetoableChangeSupport.hasListeners(null); 
    } 

    public void addVetoableChangeListener(VetoableChangeListener l) { 
     if (vetoableChangeSupport == null) { 
      vetoableChangeSupport = new VetoableChangeSupport(this); 
     } 
     vetoableChangeSupport.addVetoableChangeListener(l); 
    } 

    public void removeVetoableChangeListener(VetoableChangeListener l) { 
     if (vetoableChangeSupport == null) 
      return; 
     vetoableChangeSupport.removeVetoableChangeListener(l); 
    } 

} 

// usage 
JTabbedPane pane = new JTabbedPane(); 
VetoableSingleSelectionModel model = new VetoableSingleSelectionModel(); 
VetoableChangeListener validator = new VetoableChangeListener() { 

    @Override 
    public void vetoableChange(PropertyChangeEvent evt) 
      throws PropertyVetoException { 
     int oldSelection = (int) evt.getOldValue(); 
     if ((oldSelection == -1) || isValidTab(oldSelection)) return; 

     throw new PropertyVetoException("change not valid", evt); 

    } 

    private boolean isValidTab(int oldSelection) { 
     // implement your validation logic here 
     return false; 
    } 
}; 
model.addVetoableChangeListener(validator); 
pane.setModel(model); 
pane.addTab("one", new JLabel("here we are and stay")); 
pane.addTab("other", new JLabel("poor me, never shown")); 
+0

यह टैब परिवर्तन के लिए बहुत अच्छा काम करता है, लेकिन आप टैब को बंद करने के लिए कैसे करते हैं? टैब बंद होने के बाद 'vetoableChange' को बुलाया जाता है और जब पिछला टैब चुना जाता है। मैंने vetoableClose के लिए इंटरनेट की खोज की, लेकिन कोई हिट नहीं। –

+0

असंबद्ध/विस्तारित लगता है - कृपया एक एसएससीसीई – kleopatra

+0

के साथ एक प्रश्न पोस्ट करें ठीक है, मैंने इसे हल किया। मेरे पास बंद करने के लिए प्रत्येक टैब पर एक बटन घटक जोड़ा गया है। यह 'JTabbedPane.remove (tabIndex) 'का आह्वान करता है। मैं इसके आसपास काम करने में कामयाब रहा। मैं वर्तमान को बंद करने से पहले पिछले टैब का चयन कर रहा हूं, इसलिए 'valueChanged' विधि लागू हो जाती है। –

0

ऐसा लगता है कि vetoableChange java.beans पैकेज का हिस्सा है। javax.swing.event.ChangeListener जोड़ने का प्रयास करें।

bodyTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() { 
     public void stateChanged(javax.swing.event.ChangeEvent evt) { 
      bodyTabbedPaneStateChanged(evt); 
     } 
    }); 


private void bodyTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) { 
    if (!isCurrentTabValid()) {    
     throw new PropertyVetoException("test", evt);   
    } 
} 
+4

की तरह कुछ करने के लिए ener लगता है कि आप आप की कोशिश नहीं की कि ;-) चयन परिवर्तन सूचना के समय चयन पहले से ही बदल _is_ ताकि केवल, आप जो करने में सक्षम होंगे वह परिवर्तन को वापस करने के लिए है - लेकिन कुएं में गिरने के बाद बच्चा पहले से ही मर चुका है .. – kleopatra

1

लगता है जैसे आप पहले टैब को अक्षम करना चाहते हैं। फिर जब वर्तमान पृष्ठ मान्य है तो टैब सक्षम करें। यह भी लगता है कि आप टैब के बजाय कार्डलाउट पर विचार करना चाहेंगे। फिर वर्तमान पृष्ठ मान्य होने पर "अगला" या "जारी रखें" बटन का उपयोग करें।

+1

दूसरे टैब को अक्षम करने से उपयोगकर्ता के लिए सहज नहीं हो सकता है। लेकिन कार्ड लेआउट नौकरी कर सकता है। उपयोगकर्ता के लिए कुछ सुझाव जोड़ने के लिए मत भूलना कि वह अगली स्क्रीन पर क्यों नहीं जा सकता है। – svz

+0

मैं किसी भी टैब को अक्षम नहीं करना चाहता हूं। इसका मतलब यह होगा कि मुझे यह जांचना होगा कि उपयोगकर्ता द्वारा किए गए प्रत्येक क्रिया के बाद टैब मान्य है, जो संभव नहीं है। – Nanocom

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

  • कोई संबंधित समस्या नहीं^_^