2013-10-27 27 views
0

我想編寫一個類,比如說JComponentEx,它將枚舉所有的子類成員並將其添加到一個對象中。如何在超類的構造函數中處理所有子類的成員?

這樣我就能寫

class MyComponent extends JComponentEx { 

    private JLabel mylabel = new JLabel(); 

    private JTextField mytext = new JTextField(); 

} 

,這將導致自動調用

this.add(mylabel); 
this.add(mytext); 

我明白了一些問題,這會導致搖擺的情況下。我的問題是如何在原則上實現這個想法。

UPDATE

總而言之一句話,我想填充成員定義列表。

更新2

如果我跑除了內部構造,我不會看到的成員,因爲父類的構造是子類的實例初始化之前執行:

public class Try_Reflection_01 { 

    private final static Logger log = LoggerFactory 
      .getLogger(Try_Reflection_01.class); 

    public static interface IAutoAdd { 
    } 

    @SuppressWarnings("serial") 
    public static class JComponentEx extends JComponent { 

     public JComponentEx() { 
      updateComponents(); 
     } 

     protected void updateComponents() { 
      log.info("In updateComponents()"); 
      for (Field f : getClass().getFields()) { 

       try { 
        Object x = f.get(this); 
        log.info("Checking '{}' = {}", f.getName(), x); 
        if (x instanceof IAutoAdd) { 
         log.info("Adding"); 
         add((JComponent)x); 
        } 
        else { 
         log.info("Not adding"); 
        } 

       } catch (IllegalArgumentException e) { 
        log.error("Error getting member", e); 
       } catch (IllegalAccessException e) { 
        log.error("Error getting member", e); 
       } 

      } 
     } 
    } 

    public static class JMyComponent extends JComponentEx implements IAutoAdd { 
     public JLabel label = new JLabel("my label"); 
    } 

    public static void main(String[] args) { 
     JMyComponent component = new JMyComponent(); 
    } 
} 

輸出

[main] INFO test.java.Try_Reflection_01 - In updateComponents() 
[main] INFO test.java.Try_Reflection_01 - Checking 'label' = null 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_FOCUSED' = 0 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT' = 1 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'WHEN_IN_FOCUSED_WINDOW' = 2 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'UNDEFINED_CONDITION' = -1 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'TOOL_TIP_TEXT_KEY' = ToolTipText 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'TOP_ALIGNMENT' = 0.0 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'CENTER_ALIGNMENT' = 0.5 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'BOTTOM_ALIGNMENT' = 1.0 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'LEFT_ALIGNMENT' = 0.0 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'RIGHT_ALIGNMENT' = 1.0 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'WIDTH' = 1 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'HEIGHT' = 2 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'PROPERTIES' = 4 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'SOMEBITS' = 8 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'FRAMEBITS' = 16 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'ALLBITS' = 32 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'ERROR' = 64 
[main] INFO test.java.Try_Reflection_01 - Not adding 
[main] INFO test.java.Try_Reflection_01 - Checking 'ABORT' = 128 
[main] INFO test.java.Try_Reflection_01 - Not adding 

回答

1

將它們存儲在列表中而不是單獨的字段中。

protected List<JComponent> components = new ArrayList<>(); 

// initializer 
{ 
components.add(new JLabel()); 
components.add(new JTextField()); 
} 

而當你想使用它們:

for(JComponent comp : components){ 
this.add(comp); 
} 

替代的方式來存儲他們:

protected Map<String, JComponent> components = new HashMap<>(); 

{ 
components.put("inputfield", new JTextField()); 
} 

這將讓您可以輕鬆地通過使用密鑰作爲修改組件標識符。

如果你真的想使用反射此:

public class MyComponent { 
    private JLabel mylabel = new JLabel(); 
    private JTextField mytext = new JTextField(); 

    private String someString; 

    public List<JComponent> getComponents() throws IllegalArgumentException, 
      IllegalAccessException { 
     Field[] fields = this.getClass().getDeclaredFields(); 

     List<JComponent> list = new ArrayList<>(); 
     for (Field field : fields) { 
      Object someField = field.get(this); 
      if (someField instanceof JComponent) { 
       list.add((JComponent) someField); 
      } 
     } 

     return list; 
    } 
} 

public class Test { 
    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException{ 
     MyComponent comp = new MyComponent(); 
     System.out.println(comp.getComponents().size()); 
    } 
} 

輸出:

+0

它們已經存儲在列表中,就像JComponent一樣。現在我想用成員聲明來填充這個列表。 –

+0

@SuzanCioc:你對'成員聲明'的含義是什麼? –

+0

我想要那行'private JLabel label = new JLabel();'自動將'label'添加到底層列表中,而不需要明確地寫入'add(label)'。 –

0

你需要使用反射 - 類似:

for(Field f: getClass().getFields()) { 
    Object x = f.get(this); 
    if(x instanceof JComponent) add(x); 
} 

請注意,我所給的只適用於公共領域;訪問私有字段有點棘手 - 它需要安全權限,所以它不能在未簽名的applet中工作。

+0

'getDeclaredFields()'也適用於私人領域。 'getFields()'是公共的。 –

+0

是的,但我想在超類中這樣做,以便子類不包含任何代碼。 –

+0

@JeroenVannevel謝謝,我糾正了它。 –

相關問題