6.1.5 JSeparator類
JSeparator類是一種特殊的組件,他在JMenu上提供分隔符。JPopupMenu與JToolBar類也支持分隔,但是每一個都使用JSeparator類的相應子類。除瞭可以放置在菜單上以外,JSeparator類也可以放置在任何我們希望使用水平或是垂直線來分隔屏幕不同區域的地方。
JSeparator是一個嚴格的可視化組件,所以,他沒有數據模型。
創建JSeparator組件
要為菜單創建一個分隔,我們並不直接創建一個JSeparator,盡管我們可以這樣做。相反,我們調用JMenu的addSeparator()方法,而菜單會創建分隔符並將其添加為下一個菜單項。他是一個JSeparator(不是JMenuItem子類)的事實是隱藏的。JMenu還有一個insertSeparator(int index)方法,這個方法可以使得我們在菜單上指定的位置添加分隔,這並不必須是下一個位置。
如果我們希望在菜單以外使用JSeparator(例如,在佈局中分隔兩個面板),我們應該使用JSeparator的兩個構造函數:
public JSeparator()
JSeparator jSeparator = new JSeparator();
public JSeparator(int orientation)
JSeparator jSeparator = new JSeparator(JSeparator.VERTICAL);
這兩個構造函數使得我們可以創建一個水平或是垂直分隔。如果沒有指定方向,則為水平方向。如果我們希望顯示式指定方向,我們可以使用JSeparator的常量HORIZONTAL或是VERTICAL。
JSeparator屬性
在我們擁有JSeparator以外,我們就可以像其他的組件一樣將其添加到屏幕中。組件的初始維度是空的(寬度與高度均為0),所以如果屏幕的佈局管理器詢問組件的尺寸應是多少,分隔符將會回復他不需要空間。另一方面,如果佈局管理器提供一定量的空間,如果方向合適則分隔就會使用這個空間。例如,將一個水平JSeparator添加到BorderLayout面板的北側則會在屏幕上繪制一個分隔線。然而,如果將水平JSeparator添加到相同面板的東側則不會繪制任何內容。對於垂直JSeparator,其行為則是相反的:北側將是空的,而在東側則會出現垂直線。
表6-7顯示瞭JSeparator的四個屬性。
JSeparator屬性
屬性名
數據類型
訪問性
accessibleContext
AccessibleContext
隻讀
orientation
int
讀寫綁定
UI
SeparatorUI
讀寫綁定
UIClassID
String
隻讀
自定義JSeparator觀感
預安裝的觀感類型集合下的JSeparator外觀以及其他的菜單組件顯示在圖6-3中。
表6-8列出瞭JSeparator的UIResource相關屬性集合。對於JSeparator組件,有五個不同的屬性。
JSeparator UIResource元素
屬性字符串
對象類型
Separator.background
Color
Separator.foreground
Color
Separator.insets
Insets
Separator.thickness
Integer
SeparatorUI
String
6.1.6 JPopupMenu類
JPopupMenu組件是彈出菜單組件的容器,可以顯示在任何地方並且為JMenu所支持。當一個編程者定義的觸發事件發生時,我們顯示JPopupMenu,並且菜單顯示所包含的菜單組件。與JMenuBar類似,JpopupMenu使用SingleSelectionModel來管理當前被選中的元素。
創建JpopupMenu組件
JPopupMenu有兩個構造函數:
public JPopupMenu()
JPopupMenu jPopupMenu = new JPopupMenu();
public JPopupMenu(String title)
JPopupMenu jPopupMenu = new JPopupMenu(“Welcome”);
如果需要,隻有一個函數允許我們初始化菜單標題。標題的處理方式會依賴於所安裝的觀感。當前安裝的觀感會忽略標題。
向JPopupMenu添加菜項
與JMenu類似,一旦我們有瞭JPopupMenu,我們需要向其添加菜單項;否則,菜單將會是空的。有三個JPopupMenu方法可以添加菜單項,一個用於添加分隔符。
public JMenuItem add(JMenuItem menuItem);
public JMenuItem add(String label);
public JMenuItem add(Action action);
public void addSeparator();
另外還有一個由Container所繼承的add()方法可以用於添加通常的AWT組件:
public Component add(Component component);
添加菜單項的通常方法是使用第一個add()方法。我們獨立於彈出菜單創建菜單項,包含其行為行定,然後將其關聯到菜單。使用第二個add()方法,我們必須將事件處理器關聯到由方法返回的菜單;否則,當被選中時菜單並不會響應。下面的代碼顯示瞭兩種方法。我們使用哪一種方法完全依賴於我們的喜好。可視化編程環境,例如JBuilder,會使用第一種。因為第一種方法並不是十分復雜,如果不是全部,絕大多數的程序員應該使用第一種方法。
JPopupMenu popupenu = new JPopupMenu();
ActionListener anActionListener = …;
// The first way
JMenuItem firstItem = new JMenuItem(“Hello”);
firstItem.addActionListener(anActionListener);
popupMenu.add(firstItem);
// The second way
JMenuItem secondItem = popupMenu.add(“World”);
secondItem.addActionListener(anActionListener);
使用Action來創建與JPopupMenu結合使用的菜單項的方式類似於JMenu。然而,依據JPopupMenu類的Javadoc,並不鼓勵使用add()方法的Action變體。相反,可以將Action傳遞給JMenuItem的構造函數,或者是使用setAction()方法進行配置,然後將其添加到JPopupMenu。為什麼這個方法沒有被deprecated並不清楚。
最後,我們可以使用addSeparator()方法添加分隔。
除瞭在菜單尾部添加菜單項,我們可以在指定的位置添加菜單項,或者是在指定的位置添加分隔。
public JMenuItem insert(Component component, int position);
public JMenuItem insert(Action action, int position);
與JMenu不同,並不存在insertSeparator()方法。但是我們可以使用由Container繼承的add(Component component, int position)方法。如果我們希望移除組件,可以使用JPopupMenu特定的remove(Component component)方法。
顯示JPopupMenu
與JMenu不同,簡單的組裝彈出菜單並不夠。我們需要將彈出菜單與合適的組件相關聯。在Swing 5.0版本之前,我們需要添加事件處理代碼來觸發彈出菜單的顯示。現在,我們所需要做的就是為我們希望關聯彈出菜單的組件調用setComponentPopupMenu()方法。當平臺特定的觸發事件發生時,彈出菜單會自動顯示。
我們隻需要簡單的創建JPopupMenu的實例,並將其關聯到我們希望顯示彈出菜單的組件,如下所示:
JPopupMenu popupMenu = …;
aComponent.setComponentPopupMenu(popupMenu);
對於彈出菜單比較重要的JComponent方法主要有getComponentPopupMenu(), setComponentPopupMenu(), getInheritsPopupMenu(), setInheritsPopupMenu()以及getPopupLocation()方法。setInheritsPopupMenu()方法會接受一個boolean參數。當為true時,並沒有直接為組件設置組件彈出菜單,則會查找父容器用於彈出菜單。
JPopupMenu屬性
表6-9列出瞭JPopupMenu的16個屬性。更多的屬性是由JComponent,Container與Component繼承的。
JPopupMenu屬性
屬性名
數據類型
訪問性
accessibleContext
AccessibleContext
隻讀
borderPainted
boolean
讀寫
component
Component
隻讀
invoker
Component
隻讀
label
String
讀寫綁定
lightWeightPopupEnabled
boolean
讀寫
margin
Insets
隻讀
menuKeyListeners
MenuKeyListener[]
隻讀
popupMenuListeners
PopupMenuListener[]
隻讀
popupSize
Dimension
隻寫
selected
Component
隻寫
selectionModel
SingleSelectionModel
隻寫
subElements
MenuElement[]
隻讀
UI
PopupMenuUI
讀寫綁定
UIClassID
String
隻讀
visible
boolean
讀寫
JPopupMenu最有趣的屬性就是lightWeightPopupEnabled。通常來說,JPopupMenu會嘗試避免為顯示其菜單項而創建新的重量級組件。相反,當JPopupMenu可以完整的顯示在最外層的窗體框架內時彈出菜單使用JPanel。否則,如果菜單項不適合時,JPopupMenu使用JWindow。然而,如果我們在不同的窗體層上混合使用輕量級與重量級組件,在一個JPanel內顯示彈出菜單並不會起作用,因為在菜單層顯示的一個重量級組件會在JPanel之前出現。要糾正這種行為,彈出菜單使用Panel用來顯示菜單選項。默認情況下,JPopupMenu絕不使用Panel。
如果我們需要允許Panel顯示,我們可以在單個的JPopupMenu級別或是整個的Applet或是程序進行配置。在單獨的彈出級別,隻需要將lightWeightPopupEnable屬性設置為false。在系統級別,可以通過如下的代碼進行設置:
// From now on, all JPopupMenus will be heavy