我还建议使用某种接口/子类解决方案来封装不同组件的不同布局计算。我还将添加一些注册机制以便灵活地用于将来的添加(如果您想为新组件类型实现另一种单独的行为)
public interface PositionCalculator {
Dimension calculatePositionForComponent(MyLayoutManager manager, Component component);
}
class JLabelCalculator implements PositionCalculator {
public Dimension calculatePositionForComponent(MyLayoutManager manager, Component component) {
// ...
}
}
class JRadioButtonPosCalculator impements PositionCalculator {
public Dimension calculatePositionForComponent(MyLayoutManager manager, Component component) {
// ...
}
}
// More classes ...
class MyLayoutManager extends LayoutManager {
private static HashMap<Class, PositionCalculator> calculators = new HashMap<Class, PositionCalculator>();
public static registerPositionCalculator(Class c, PositionCalculator p) {
calculators.put(c, p);
}
private static PositionCalculator defaultCalculator = new DefaultPositionCalculator(); // Not shown here ...
// ...
private Dimension calculatePositionForComponent(Component c) {
PositionCalculator calc = calculators.get(c.getClass());
if (calc == null)
calc = defaultCalculator;
return calc.calculatePositionForComponent(this, c);
}
}
现在,您可以为所有组件注册单独的 PositionCalculators,方法是:
MyLayoutManager.registerPositionCalculator(JLabel.class, new JLabelCalculator());
MyLayoutManager.registerPositionCalculator(JRadioButton.class, new JRadioButtonCalculator());
// ...
当然,这种解决方案可能存在以下缺点:
- 它可能比原来的慢。
- 它不适用于继承的类:如果您有 JLabel 的子类,则必须单独注册它。该解决方案可以适应这一点,但这将以另一次性能损失为代价......
另一方面,该解决方案具有很好的可扩展性:您可以定义不同的布局行为,而无需触及 MyLayoutManager 类。