How to disable a container and its children in Swing

后端 未结 6 745
伪装坚强ぢ
伪装坚强ぢ 2020-12-08 16:44

I cannot figure out a way to disable a container AND its children in Swing. Is Swing really missing this basic feature?

If I do setEnabled(false) on a container, its

6条回答
  •  我在风中等你
    2020-12-08 16:53

    This is the code I use. It recursively visits the component tree, maintaining a counter for each component. Only weak references are kept on the components, preventing any memory leak.

    You say that traversing all the elements is not an option, but my experience is that this code works well for quite complex GUIs. By the way, if Swing had this feature natively, there would be no other way than traversing the component tree, anyway.

    Example usage (parenthesis means disabled) :

         a
        / \
       b   c
          / \
         d   e
    
    setMoreDisabled(c)
    
         a
        / \
       b  (c)
          / \
        (d) (e)
    
    setMoreDisabled(a)
    
        (a)
        / \
       b  (c)
          / \
        (d) (e)
    
    setMoreEnabled(a)
    
         a
        / \
       b  (c)
          / \
        (d) (e)
    

    Now the code :

    import java.awt.Component;
    import java.awt.Container;
    import java.util.Map;
    import java.util.WeakHashMap;
    
    public class EnableDisable {
    
        private static final Map componentAvailability = new WeakHashMap();
    
        public static void setMoreEnabled(Component component) {
            setEnabledRecursive(component, +1);
        }
    
        public static void setMoreDisabled(Component component) {
            setEnabledRecursive(component, -1);
        }
    
        // val = 1 for enabling, val = -1 for disabling
        private static void setEnabledRecursive(Component component, int val) {
            if (component != null) {
                final Integer oldValObj = componentAvailability.get(component);
                final int oldVal = (oldValObj == null)
                        ? 0
                        : oldValObj;
                final int newVal = oldVal + val;
                componentAvailability.put(component, newVal);
    
                if (newVal >= 0) {
                    component.setEnabled(true);
                } else if (newVal < 0) {
                    component.setEnabled(false);
                }
                if (component instanceof Container) {
                    Container componentAsContainer = (Container) component;
                    for (Component c : componentAsContainer.getComponents()) {
                        setEnabledRecursive(c,val);
                    }
                }
            }
        }
    
    }
    

提交回复
热议问题