I'd also suggest some kind of interface/subclass solution for encapsulating the different layout calculations for different components. I also would add some registration mechanism in order to be flexible for future additions (if you want to implement another separate behaviour for new component types)
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);
}
}
Now, you can register individual PositionCalculators for all of your components by putting
MyLayoutManager.registerPositionCalculator(JLabel.class, new JLabelCalculator());
MyLayoutManager.registerPositionCalculator(JRadioButton.class, new JRadioButtonCalculator());
// ...
Of course, this solution might suffer from the following drawbacks:
- It's probably slower than the original one.
- It doesn't work with inherited classes: if you have a subclass from JLabel, you must register it separately. The solution could be adapted to this, but this would be at the cost of another performance loss...
On the other hand, the solution is pretty well extensible: You can define different layout behaviour without touching your MyLayoutManager class.