如何处理超类'构造函数中的所有子类'成员?

时间:2013-10-27 10:26:55

标签: java inheritance reflection subclassing

我想编写一个类,比如JComponentEx,它将枚举所有子类成员并将其添加到对象中。

这样我就可以写

class MyComponent extends JComponentEx {

    private JLabel mylabel = new JLabel();

    private JTextField mytext = new JTextField();

}

这将导致自动调用

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

我理解在Swing的情况下会导致一些问题。我的问题是如何原则上实现这个想法。

更新

简而言之,我想用成员定义填充列表。

更新2

如果我在构造函数中运行add,我将看不到成员,因为超类构造函数在子类实例初始化之前执行:

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

2 个答案:

答案 0 :(得分: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());
    }
}

输出:

  

2

答案 1 :(得分:0)

您需要使用反射 - 类似于:

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

请注意,我所提供的仅适用于公共领域;访问私有字段有点棘手 - 它需要安全权限,因此它不适用于未签名的applet。