2010-06-02 17 views
12

को अक्षम और ग्रे आउट करें मेरे पास Composite है जो मैं प्रोग्रामेटिक रूप से सक्षम/अक्षम करने में सक्षम होना चाहता हूं। Control.setEnabled(boolean enabled) विधि ठीक काम करती है, लेकिन यह कोई दृश्य जानकारी नहीं देती है कि विजेट अक्षम हैं।एक एसडब्ल्यूटी कंपोजिट

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

उत्तर

10

एक कंपोजिट एक कंटेनर नियंत्रण है जो लेआउट का उपयोग करके अन्य नियंत्रण रखता है - आप वास्तव में एक समग्र नहीं देख सकते हैं, आप केवल उसके नियंत्रण को देख सकते हैं। विकलांग और अक्षम रूप से अक्षम करने के लिए, आपको सभी बच्चों पर setEnabled(false) पर कॉल करना होगा, मान लें कि वे कंटेनर भी नहीं हैं। असल में, पत्ती विजेट को सक्षम/अक्षम करने के लिए और आपको दृश्य संकेत दिखाई देगा।

कंपोजिट को अक्षम करते समय आप विगेट्स के साथ कुछ भी नहीं कर सकते हैं क्योंकि समग्र सभी घटनाएं खा रहा है। यद्यपि बाल विगेट्स ईवेंट को अग्रेषित नहीं कर रहे हैं, लेकिन वे अपने माता-पिता की स्थिति के बारे में कुछ भी नहीं जानते हैं, इसलिए वे बाहर नहीं हैं।

0

दूसरे शब्दों में, अगर आप इस तरह कोड लिखने के लिए, एक Composite c दिया की जरूरत है:

for (Control child : c.getChildren()) 
    child.setEnabled(false); 
+2

वास्तव में नहीं - आपको पूरे नियंत्रण ढेर को फिर से भरना होगा।यह कहने पर काम नहीं करेगा अगर आपके पास एक समग्र में एक सश है और आपके विजेट सैश में हैं। – andyczerwonka

+0

हाँ, मुझे पता है। मैं सिर्फ एक उदाहरण दे रहा था। – dplass

11

समस्या वास्तव में था कि मैं समग्र और इसके अंदर नहीं नियंत्रण अक्षम करने गया था। मैंने जो किया वह कुछ ऐसा था:

public void recursiveSetEnabled(Control ctrl, boolean enabled) { 
    if (ctrl instanceof Composite) { 
     Composite comp = (Composite) ctrl; 
     for (Control c : comp.getChildren()) 
     recursiveSetEnabled(c, enabled); 
    } else { 
     ctrl.setEnabled(enabled); 
    } 
} 
+0

फ्रेड्रिक के पोस्ट में एक अतिरिक्त चिमटा, जो कि मुझे सबसे ज्यादा चाहिए था। मेरे पास ऐसी स्थिति है जहां टैबफॉल्डर और कुछ अन्य प्रकार के कंपोजिट हैं जिन्हें अपने बच्चों को अक्षम करने के अलावा अक्षम होने की आवश्यकता है। तो: ' ... के लिए (नियंत्रण c: comp.getChildren()) recursiveSetEnabled (ग, सक्षम); comp.setEnabled (सक्षम); ... ' –

+0

यह नियंत्रण के पेड़ को अक्षम करने के लिए भी उपयोगी है लेकिन कुछ नियंत्रणों को छोड़कर, जो संभव नहीं है, उदाहरण के लिए संभव नहीं है। समग्र ... अक्षम() और फिर कुछ नियंत्रण पुनः सक्षम करने का प्रयास कर रहा है। – Gregor

+0

लेकिन जब आप उन विगेट्स को पुनः सक्षम करते हैं जिन्हें आप पहले अक्षम लोगों को अक्षम के रूप में रखना चाहते हैं। इस समाधान के साथ आप सब कुछ सक्षम कर देंगे। – Lii

0

यहां पोस्ट किए गए अन्य समाधान बहुत प्राचीन हैं।

  • यहां तक ​​कि अगर एक नियंत्रण के साथ शुरू करने के लिए अक्षम किया गया है, यह अगर उसके नियंत्रण पेड़ अक्षम किया गया है सक्षम हो जाएगा और उसके बाद सक्षम: वे कई कमियों की है। आप शायद इस तरह के नियंत्रण को अक्षम रखना चाहते हैं।
  • कभी-कभी नेस्टेड नियंत्रण सक्षम रहना चाहिए जब उनका नियंत्रण पेड़ अक्षम हो। दिखाने के लिए कोई जानकारी के साथ
    1. विकलांग राज्य:
    2. यह दो अलग विकलांग राज्यों के बीच भेद करने के लिए उपयोगी है। यह उपयोगकर्ता को स्पष्ट रूप से संकेत दिया जाना चाहिए।
    3. जानकारी प्रदर्शित करना, लेकिन केवल पढ़ने के लिए राज्य। यह इस राज्य में टेक्स्ट फ़ील्ड में टेक्स्ट कॉपी करने में सक्षम होना उपयोगी है।

कोड के नीचे इन समस्याओं को हल करती है। यह एसडब्ल्यूटी के लिए अंतिम एनबेलर/डिब्बलर है।

यह Widget.setData के साथ टैग करके संशोधित नियंत्रणों का ट्रैक रखता है, ताकि यह केवल उन contoles को सक्षम कर सके जो इसे पहले अक्षम कर चुके हैं। यह वृक्ष राज्यों में विभिन्न प्रकार के नियंत्रणों को अलग-अलग नियंत्रित करता है: DISABLED, READ_ONLY और EDITABLE

import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Set; 

import org.eclipse.swt.widgets.Combo; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Control; 
import org.eclipse.swt.widgets.Label; 
import org.eclipse.swt.widgets.Text; 
import org.eclipse.ui.forms.widgets.ExpandableComposite; 

public class GuiEnabler { 
    /** 
    * Used to set the enable state of a tree of controls. 
    */ 
    public enum EnableState { 
     /** 
     * The control is disabled, for when there is no information to show in 
     * it. All controls, including labels, are disabled. 
     */ 
     DISABLED, 
     /** 
     * For when there is information to show in the control, but it should 
     * be read-only. Controls are disabled, except Text which is 
     * non-editable, and Lables, which are enabeled. 
     */ 
     READ_ONLY, 
     /** 
     * All controls are enabled and editable. 
     */ 
     EDITABLE 
    } 

    private static final String ENABLED_KEY = GuiEnabler.class.getName() + ".disabled"; 
    private static final String EDITABLE_KEY = GuiEnabler.class.getName() + ".read_only"; 

    /** 
    * Disables or makes read-only {@code control} and all its child controls (recursively). 
    * Also restores the state of controls previously disabled by this method. The action 
    * performed on the controls is determined by {@link EnableState enableState}. 
    * 
    * @param excluded These controls (and their children) are not modified by 
    * the method. 
    */ 
    public static void recursiveUpdateEnableState(Control control, EnableState enableState, Control... excluded) { 
     updateEnabledState(control, enableState, new HashSet<>(Arrays.asList(excluded))); 
    } 

    /** 
    * See {@link GuiEnabler#recursiveUpdateEnableState(Control, EnableState, Control...)}. 
    */ 
    public static void updateEnabledState(Control control, EnableState enableState, Set<Control> excluded) { 
     if (excluded.contains(control)) { 
      return; 
     } else if (control instanceof ExpandableComposite) { 
      updateEnabledState(((ExpandableComposite) control).getClient(), enableState, excluded); 
     } else if (control instanceof Composite && !(control instanceof Combo)) { 
      for (Control child : ((Composite) control).getChildren()) { 
       updateEnabledState(child, enableState, excluded); 
      } 
     } else { 
      updateControl(control, enableState); 
     } 
    } 

    /** 
    * Updates a single control to have its proper state for enableState. 
    */ 
    private static void updateControl(Control control, EnableState enableState) { 
     if (enableState == EnableState.DISABLED) { 
      makeDisabled(control); 
     } else if (enableState == EnableState.READ_ONLY) { 
      if (control instanceof Text) { 
       makeNonEditable((Text) control); 
       makeEnabled(control); 
      } if (control instanceof Label) { 
       makeEnabled(control); 
      } else { 
       makeDisabled(control); 
      } 
     } else if (enableState == EnableState.EDITABLE) { 
      makeEnabled(control); 
      if (control instanceof Text) makeEditable((Text) control); 
     } 
    } 


    private static void makeEnabled(Control control) { 
     if (control.getData(ENABLED_KEY) != null) { 
      control.setData(ENABLED_KEY, null); 
      control.setEnabled(true); 
     } 
    } 

    private static void makeDisabled(Control control) { 
     if (control.getEnabled()) { 
      control.setData(ENABLED_KEY, "marked"); 
      control.setEnabled(false); 
     } 
    } 

    private static void makeEditable(Text text) { 
     if (text.getData(EDITABLE_KEY) != null) { 
      text.setData(EDITABLE_KEY, null); 
      text.setEditable(true); 
     } 
    } 

    private static void makeNonEditable(Text text) { 
     if (text.getEditable()) { 
      text.setData(EDITABLE_KEY, "marked"); 
      text.setEditable(false); 
     } 
    } 
} 
इस के

एक सीमा भी है कि विकलांग राज्य में यह अभी भी संभव है एक TabFolder नियंत्रण में सक्रिय टैब को बदलने के लिए है।

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