Java Swing layout manager circular reference being set twice

和自甴很熟 提交于 2019-12-11 18:54:41

问题


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);

回答1:


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.




回答2:


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:


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.



来源:https://stackoverflow.com/questions/13810075/java-swing-layout-manager-circular-reference-being-set-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!