2012年10月20日 星期六

Java Swing──使用最高等級的容器

本文譯自Using Top-Level Containers
JAVA官網的入門教學

名詞對照:最高等級容器=top-level container、容器=container、類別=class、元件=component、外觀設定=Look and Feel、標籤=Label、佈局管理器=layout manager

簡稱說明:GUI=Graphic User Interface=圖形化使用者介面

使用最高等級的容器

就像之前我們提到的,Swing提供三種有用的容器類別: JFrame, JDialog, 和 JApplet. 當使用這些類別時,您應該把這些事實記在心裡:
  • 為了出現在螢幕上,所有GUI元件都需要是容器階層(containment hierarchy)的一部份。容器階層(containment hierarchy)是元件的樹狀結構,有著最高等級容器當作它的根部。(這超難翻的啊~~到底是啥意思,等等再說)我們等等會讓您看看是什麼意思。
  • 每個GUI元件只能被包含一次。如果一個元件已經被某個容器包含了,您又試圖把他家到另一個容器中,這個元件將會從原本的容器中被剔除,然後被加到第二個容器中。
  • 每個最高等級容器有著一般來說直接或間接包含可見元件的content pane。
  • 您可以選擇是否要在最高等級容器中加入一個選單列。這個選單列照慣例會被擺在最高等級容器內,但在content pane之外。一些外觀設定(look and feel),像是Mac OS外觀設定,可以給您擺放選單列在其他更適合的地方的選擇。例如在螢幕的最頂端。


註記: 即使 JInternalFrame 仿造(mimic) JFrame(的行為,樣子,etc), internal frames 並不是真正的最高頂級容器。

這裡有張圖片,顯示了出一個被應用程式製造出來的視窗。這視窗包含了一個綠色的選單列(但沒有選單項),然後,這視窗的content pane有個很大的空白黃色標籤。
A simple application with a frame that contains a menu bar and a content pane.
A diagram of the frame's major parts
您可以在 TopLevelDemo.java裡找到整個範例原始碼。 雖然這些範例使用 JFrame 在一個獨立的應用程式內,這些觀念同樣可以應用於 JAppletJDialog。這裡有範例中的容器階層(containment hierarchy):
Containment hierarchy for the TopLeveDemo example's GUI.
就像是那些圈圈指出的,我們省去了圖表中的一些細節。我們會在一下下會再表明那些被省去的細節。下面是接下來的部分要討論的:
  • 最高等級容器以及容器階層(Containment Hierarchies)
  • 將元件加到Content Pane
  • 增加一個選單列
  • Root Pane (也就是省略掉的細節)

最高等級容器以及容器階層(Containment Hierarchies)

每個使用Swing的程式都至少擁有一個最高等級容器。這個最高等級容器是容器階層(containment hierarchy)的根部──這個繼承包含了所有會出現最高等級容器裡的Swing元件。

作為一項規則,一個有著Swing作為GUI基礎的獨立應用程式擁有至少一個以 JFrame 作為根的容器繼階層。舉例來說,如果一個應用程式擁有一個主要視窗(window)和兩個對話盒(dialog),這個應用程式就擁有了三個容器階層,也因此擁有三個最高等級容器。一個容器階層有著 JFrame 作為它的根部,其他兩個則擁有 JDialog 物件當作根部。

一個以Swing作為基礎的applet擁有至少一個容器階層,尤其其中一個是以 JApplet 物件當作根部。舉例來說,有一個對話盒(dialog)的applet擁有兩個容器階層。在瀏覽視窗中的元件們是在一個以 JApplet 物件作為根部的容器階層之中。那個對話盒則擁有一個以 JDialog 物件當作根部的容器階層。

將元件加到Content Pane

在先前例子中得到視窗的content pane並加入黃色標籤的程式碼:
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
就像這程式碼顯示的,您可以藉由呼叫 getContentPane 方法,而獲得一個最高容器的content paneer。預設的content pane是一個簡單中級,繼承自 JComponent 的容器,然後使用 BorderLayout 當作它的佈局管理器。

自行定義content pane是很容易的──例如,設定佈局管理器或增加一個邊界(border)。然而,有個小小的問題。 getContentPane 方法回傳的是一個 Container 物件,而非 JComponent 物件。這代表如果您想利用content pane的 JComponent 特性,您必須轉換傳回值的類型或是製造您自己的元件來當作content pane。我們的範例通常會採用第二種方法,因為它較為簡潔。另一種方法我們偶爾用來簡單地增加一個自訂的元件到content pane,並覆蓋整個content pane。

注意 JPanel 預設的佈局管理器是 FlowLayout ;您可能會希望改變它。可以使用最高等級容器的 setContentPane 方法。下面有範例:
//Create a panel and add components to it.(創建一個面板然後把元件加上去)
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(someBorder);
contentPane.add(someComponent, BorderLayout.CENTER);
contentPane.add(anotherComponent, BorderLayout.PAGE_END);

topLevelContainer.setContentPane(contentPane);

註記: 為了方便, add 方法和它的變化型 removesetLayout 已經被覆寫(override)以配合 contentPane 的需要。這代表您可以這樣寫
frame.add(child);
然後child會被增加到 contentPane 之中。

注意只有這三個方法。
(省略一句"getLayout() will not return the layout set with setLayout()",因為不知道它想表達什麼=  =←不負責任 應該是說除了這三個方法,其他人沒有被覆寫,用法繼承自母類別。)

增加一個選單列(Menu Bar)

理論上,所有的最高等級容器可以支持一個選單列。然而,在實踐上,選單列通常只出現在視窗與applet中。要增加一個選單列到最高等級容器中,需要建立一個 JMenuBar 物件,把選單選項填進去,然後呼叫 setJMenuBar 方法。 TopLevelDemo 增加了一個選單列到它的視窗:
frame.setJMenuBar(greenMenuBar);
需要更多關於實作選單與選單列的資訊,請參照 How to Use Menus.

Root Pane(根窗格)

每個最高等級容器依賴在一個叫作"root pane"的隱性中級容器上Root pane 管理content pane 和選單列,加上其他一些容器。一般來說,您不需要知道root pane就可以使用Swing 元件了。然而,如果您需要監聽滑鼠點擊或是在數個元件上繪製(paint),你就需要熟悉root pane了。

這裡有個列表列出了root pane提供給一個視窗(和所有其他的最高等級容器)的元件們:
A root pane manages four other panes: a layered pane, a menu bar, a content pane, and a glass pane.
我們已經告訴過您關於content pane 和 選擇性的選單列。Root Pane增加的其他的兩個元件是圖層窗格(layered pane) 和 玻璃窗格(glass pane)。圖層窗格包含了選單列與content pane,並能夠Z排序其他元件;玻璃窗格通常用來監聽透過最高等級容器輸入的事件,並能夠繪製東西於數個元件上。
關於更多細節,請參照 How to Use Root Panes.




好累喔,果然是官方文件,真的是毫無趣味性可言。。。
僅供參考,可以對照著英文版看。
可能有翻錯的地方,請見諒。 

個人筆記:

沒有留言:

張貼留言