Java Swing layout manager circular reference being

2019-08-29 08:49发布

Can anybody explain why circular reference is being set twice in the followig code?

//declare panel
this.cntnrPnl = new JPanel();
//define layout manager for the panel - but why circ ref?
this.cntnrPnl.setLayout(new BoxLayout(this.cntnrPnl, BoxLayout.Y_AXIS));

Why is it necessary to link the BoxLayout back to the JPanel container explicitly instead of JPanel.setLayout doing the setting itself behind the scene and using a setter from BoxLayout for code compactness?

E.g.:

this.cntnrPnl.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
//and then in JPanel.setLayout have something line
_layout.setContainer(this);

3条回答
你好瞎i
2楼-- · 2019-08-29 09:32

Why is it necessary to link the BoxLayout back to the JPanel container explicitly instead of JPanel.setLayout doing the setting itself behind the scene and using a setter from BoxLayout for code compactness?

What you call JPanel.setLayout is actually Container.setLayout:

public void setLayout(LayoutManager mgr)

You call call the method with a BoxLayout because it implements LayoutManager. But LayoutManager does not have a setContainer method, so it would not have worked without adding that method. But it seems that most layout managers don't care about a container so the method would not belong there.

Would it be possible for BoxLayout constructor to do the magic? Maybe not, though a BoxLayout is tied to a Container, the reverse is not necessarily true. Consider:

this.cntnrPnl = new JPanel();
BoxLayout bY = new BoxLayout(this.cntnrPnl, BoxLayout.Y_AXIS);
BoxLayout bX = new BoxLayout(this.cntnrPnl, BoxLayout.X_AXIS);

Now at different times you can call this.cntnrPnl.setLayout(bX) and this.cntnrPnl.setLayout(bY).

So looking at all options, it seems the current API is best, though of course all this is somewhat subjective.

By the way, please consider renaming cntnrPnl to containerPanel. You are not really saving much by stripping the vowels.

查看更多
何必那么认真
3楼-- · 2019-08-29 09:34

Because a JPanel is not the only available container in Swing. In particular, you might create your own container class and not know about those special requirements for BoxLayout. As a result, the layout manater would not work for your implementation.

Now one could ask why the BoxLayout needs a reference to the JPanel to begin with, but this is a different matter.

查看更多
淡お忘
4楼-- · 2019-08-29 09:46

Because BoxLayout is a special layout that needs a reference to the target container it lays out. That's not the case of all the layout managers. It would be ugly to add a specific case for BoxLayout in the setLayout() method. And it would also mean that the BoxLayout would be in an unstable state after its construction, since it wouldn't have the mandatory target container yet.

The reverse could have been done though: having the BoxLayout constructor call setLayout(this) on the target container. But I don't know why it hasn't been done.

查看更多
登录 后发表回答