2014-12-29 48 views
2

我正在學習基本的JavaFX,而且我不明白這本書的讀法:「不,可以將節點(如文本字段)僅添加到一個窗格中,也可以添加一次。多次添加到窗格或添加到不同的窗格將導致運行時錯誤。「我從UML圖中可以看出,本書規定它是一個組合,但我不明白爲什麼(庫類代碼實現)是。JavaFX - 爲什麼將節點多次添加到窗格或添加到不同窗格會導致錯誤?

例如,爲什麼會導致編譯錯誤?是不是在窗格內實例化的新文本字段,因爲它是一個組合?

FlowPane pane = new FlowPane(); 
StackPane pane2 = new StackPane(); 
TextField tf = new TextField(); 
pane.getChildren().add(tf); 
pane.getChildren().add(tf); 

此外,爲什麼以下運行,但不顯示放置在窗格中的文本字段?

FlowPane pane = new FlowPane(); 
StackPane pane2 = new StackPane(); 
TextField tf = new TextField(); 
pane.getChildren().add(tf); 
pane2.getChildren().add(tf); 

primaryStage.setScene(new Scene(pane)); 
primaryStage.show(); 
+1

該聲明來自哪裏?有些上下文會很有用。 –

+0

它來自教科書 – Hyde

+0

您可以查看JavaFX源代碼並找出原因。 –

回答

0

試試這個:

TextField tf = new TextField(); 
TextField tf2 = new TextField(); 
pane.getChildren().add(tf); 
pane.getChildren().add(tf2); 

的原因,你不能添加同一節點兩次是,只有一個具有相同規格和尺寸節點可以在GUI中查看。這就像將相同的藍色圓圈複製到原始的藍色圓圈上。對用戶來說,它看起來是一樣的,但它佔用更多的內存。

2

這是基本的API設計方式的(故意)的後果。每個Node具有屬性的集合,包括parent屬性(在 - 一個且僅一個 - 在場景圖中的節點的父)中,用如layoutXlayoutY性質,這是節點的座標相對於它的父沿。因此,節點只能屬於一個父節點,並且只能添加到父節點(因爲它只能在父節點中有一個位置)。以這種方式組織事物可以實現非常有效的佈局過程。

另一種方式去思考的是:假設你的第一個代碼塊沒有你想要的東西;所以文本字段tf在流程窗格中出現了兩次。你期望從tf.getBoundsInParent()得到什麼結果?由於tf在父項中出現兩次,因此API無法爲此調用提供合理的值。

有陳述了幾個不準確的,你做你的問題:

舉例來說,爲什麼會出現這種結果編譯錯誤?是不是一個新的 文本字段在窗格中實例化,因爲它是一個組合?

首先,在技術上,這是聚集,不組合物;儘管我不確定理解這些差異會有助於你理解在這一點上發生的事情。

其次,這裏沒有編譯錯誤;在運行時出現錯誤(pane檢測到相同的node已添加兩次;編譯器無法檢查此問題)。

三,父母不要實例您添加到他們的節點的副本。如果是這樣,您將無法更改顯示的節點的屬性。例如,如果在您的示例FlowPane實例化一個新的TextField當你叫pane.getChildren().add(tf);,然後顯示的新文本字段,那麼如果隨後叫tf.setText("new text"),那就沒有任何作用,因爲它不會改變文本的文本pane正在顯示的字段。

當您致電pane.getChildren().add(...)時,您傳遞了要添加的節點的引用;它就是那個節點,然後顯示爲窗格的子節點。任何其他的實現都會產生非常不直觀的行爲。

在你的第二個代碼塊:

pane.getChildren().add(tf); 
pane2.getChildren().add(tf); 

第二個呼叫隱式設置的tfpane2parent財產;因此tf不再是pane的孩子。因此,此代碼的作用是從第一個父項pane中刪除tf。據我所知,這種副作用沒有記錄,所以你可能應該避免編寫這樣的代碼。

相關問題