2012-12-10 28 views
0

任何人都可以解釋爲什麼循環引用在後續代碼中設置兩次?Java Swing佈局管理器循環引用被設置兩次

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

爲什麼要到BoxLayout鏈接回JPanel容器明確,而不是JPanel.setLayout做本身設置在幕後,並使用二傳手從BoxLayout代碼緊湊?

例如爲:

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

看來你的問題不是爲什麼有循環引用,但爲什麼客戶端代碼必須通過將'Container'傳遞給'BoxLayout'構造函數來連接它。 –

+0

好點。讓我改編一下 – amphibient

+0

好吧 - 現在看看,希望更清楚 – amphibient

回答

2

因爲BoxLayout是一個特殊的佈局,需要引用它指定的目標容器。這不是所有佈局經理的情況。在setLayout()方法中爲BoxLayout添加特定的案例會很難。而且這也意味着BoxLayout在建造之後會處於不穩定狀態,因爲它還沒有強制目標容器。

反過來可能已經完成了:在目標容器上使用BoxLayout構造函數調用setLayout(this)。但我不知道爲什麼沒有完成。

+0

'BoxLayout'構造函數不能調用'setLayout',因爲對於同一個'Container'可能有多個'LayoutManagers',不是嗎? –

+0

不可以。一個容器只能有一個佈局管理器。 –

+0

我的意思是不同的佈局管理器在不同的時間,實際上,不同的對象調用setLayout是不同的時間 –

0

因爲一個JPanel是不是在Swing唯一可用的容器。尤其是,您可能會創建自己的容器類,而不瞭解BoxLayout的這些特殊要求。因此,佈局管理器不適用於您的實施。

現在人們可能會問爲什麼BoxLayout需要引用JPanel來開始,但這是另一回事。

+0

您的意思是說您可以將面板X的佈局設置爲佈局A,但是將容器Y設置爲佈局的目標?我想如果你將面板X設置爲佈局A作爲佈局,佈局A的目標總是應該是X而不是其他容器。 – amphibient

+0

不,我的意思是在某個時候定義的API聲明瞭一個方法'Container#setLayout',它沒有實現容器類自己在佈局中注入的隱式要求。沒有容器調用'LayoutManager#setContainer'的約定(事實上,大多數佈局管理器沒有該方法開始)。 – sarcan

1

爲什麼要到BoxLayout鏈接回JPanel容器明確,而不是JPanel.setLayout做的設置本身在幕後,並使用二傳手從BoxLayout代碼緊湊?

你叫什麼JPanel.setLayout實際上Container.setLayout是:

public void setLayout(LayoutManager mgr) 

你叫調用方法與BoxLayout,因爲它implements LayoutManager。但是LayoutManager沒有setContainer方法,因此如果不添加該方法就無法工作。但似乎大多數佈局管理器不關心容器,因此該方法不屬於那裏。

BoxLayout這個構造函數能夠做到這一點嗎?也許不是,雖然BoxLayout綁定到Container,但相反不一定是這樣。試想一下:

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

現在在不同的時間,你可以叫this.cntnrPnl.setLayout(bX)this.cntnrPnl.setLayout(bY)

因此,看看所有的選擇,似乎目前的API是最好的,但當然這一切都有些主觀。

順便提一下,請考慮將cntnrPnl更名爲containerPanel。通過剝離元音你並不是真的節省了很多。