Swing 邊框(一) – JAVA編程語言程序開發技術文章

Swing組件提供瞭對組件周圍的邊框區域進行定制的功能。為瞭簡單,我們可以使用預定義的八個邊框,或者是我們可以創建自己的邊框。在本章中,我們將會瞭解如何最好的使用已存在邊框以及如何創建我們自己的邊框。


7.1 Some Basics on Woring with Borders
邊框是帶有標準的setBorder()與getBorder()屬性方法的JComponent屬性。所以,所有的JComponent子類的Swing組件都具有邊框。默認情況下,一個組件並沒有與其相關聯的自定義邊框。(JComponent的getBorder()方法返回null。)相反,組件顯示的默認邊框是依據當前的觀感對於其狀態最為合適的邊框。例如,對於JButton,對於每一個觀感特定不同的邊框,邊框可以表現為按下,未按下或是禁止。


盡管對於所有的組件初始的邊框屬性設置為null,我們可以通過調用JComponent的setBorder(Border newValue)方法來修改組件的邊框。一旦設置,修改的值就會覆蓋當前觀感的邊框,並且在組件的區域內繪制新邊框。如果在稍後的時候,我們希望將邊框重新設置為對於狀態與觀感合適的邊框,我們可以將邊框屬性修改為null,使用setBorder(null)並且調用組件的updateUI()方法。updateUI()方法會通知觀感重新設置邊框。如果我們沒有調用updateUI()方法,則組件將沒有邊框。


圖7-1顯示瞭一個JLabel周圍的各種邊框設置,通過文本標簽來標明邊框類型。如何創建不同的邊框將會在本章的稍後部分進行討論。


swing_7_17.1.1 Exploring the Border Inteface
我們可以在javax.swing.border包中找到Border接口。這個接口構成瞭所有邊框類的基礎。這個接口直接由AbstractBorder類實現,這個類是所有預定義的Swing邊框類的父類:BevelBorder,CompoundBorder,EmptyBorder,EtchedBorder,LineBorder,MatteBorder,SoftBevelBorder以及TitledBorder。另外一個有趣的類就是BorderFactory類,我們可以在javax.swing包中找到這個類。這個類使用工廠設計模式來創建邊框,隱藏瞭實現細節,並且可以緩存各種選項來優化共同使用。


在這裡顯示的Border接口由三個方法構成:paintBorder(),getBordernsets()以及isBorderOpaque()。這些方法會在後面的章節中進行描述。


paintBorder()


paintBorder()方法是這個接口的關鍵方法。其定義如下:


public void paintBorder(Component c, Graphics g, int x, int y, int
  width, int height)邊框實現的繪制是由這個方法完成的。通常,Border實現首先會詢問Insets維度,然後在外層區域的四個邊進行繪制,如圖7-2所示。如果邊框是不透明的,paintBorder()實現必須填充整個內部區域。如果一個邊框是不透明的,並沒有填充區域,那麼這是一個bug並且需要修正。


列表7-1顯示瞭一個簡單的paintBorder()實現,這個實現使用比上部與下部略淺的顏色填充左邊與右邊。


public void paintBorder(Component c, Graphics g, int x, int y, int width,
    int height) {
  Insets insets = getBorderInsets(c);
  Color color = c.getForeground();
  Color brighterColor = color.brighter();
// Translate coordinate space
  g.translate(x, y);
// Top
  g.setColor(color);
  g.fillRect(0, 0, width, insets.top);
// Left
  g.setColor(brighterColor);
  g.fillRect(0, insets.top, insets.left, height-insets.top-insets.bottom);
// Bottom
  g.setColor(color);
  g.fillRect(0, height-insets.bottom, width, insets.bottom);
// Right
  g.setColor(brighterColor);
  g.fillRect(width-insets.right, insets.top, insets.right,
    height-insets.top-insets.bottom);
// Translate coordinate space back
  g.translate(-x, -y);
}當創建我們自己的邊框時,我們將會經常發現我們自己在填充相同的非重疊矩形區域。Graphics的translate()方法簡化瞭繪制坐標的指定。無需轉換坐標,我們需要通過原始的(x,y)來偏移繪制。


註意:我們不能通過插入g.fillRect(x,y,width,height)來簡化,因為這會填充整個組件區域,而不是邊框區域。


getBorderInsets()


getBorderInsets()方法會返回在指定的組件c作為Insets對象的周圍繪制邊框所必須的空間。其定義如下:


public Insets getBorderInsets(Component c)如圖7-2所示,這些內部區域定義瞭可以繪制邊框的合法區域。Component參數可以使得我們使用他的一些屬性來決定內部區域的尺寸。


isBorderOpaque()


邊框可以是不透明的或是透明的。isBorderOpaque()方法可以返回true或是false來表明邊框是哪種形式。其定義如下:


public boolean isBorderOpaque()當這個方法返回true時,邊框需要是非透明的,填充其整個內部區域。當其返回false時,沒有繪制的區域將會保持邊框所在的組件的背景顏色。


7.1.2 Introducing BorderFactory
現在我們已經基本瞭解瞭Border接口是如何工作的,現在我們來瞭解一下作為簡單創建邊框方法的BorderFactory類。我們可以在javax.swing包中找到這個類,BorderFactory類提供瞭一系列的static方法來創建預定義的邊框。無需調用不同的邊框類的特定構造函數,通過這個工廠類我們幾乎可以創建所有的邊框。這個工廠類同時可以緩存一些邊框的創建從而避免多次重新創建經常使用的邊框。這個類的定義如下:


public class BorderFactory {
  public static Border createBevelBorder(int type);
  public static Border createBevelBorder(int type, Color highlight,
    Color shadow);
  public static Border createBevelBorder(int type, Color highlightOuter,
    Color highlightInner, Color shadowOuter, Color shadowInner);
  public static CompoundBorder createCompoundBorder();
  public static CompoundBorder createCompoundBorder(Border outside,
    Border inside);
  public static Border createEmptyBorder();
  public static Border createEmptyBorder(int top, int left, int bottom,
    int right);
  public static Border createEtchedBorder();
  public static Border createEtchedBorder(Color highlight, Color shadow);
  public static Border createEtchedBorder(int type);
  public static Border createEtchedBorder(int type, Color highlight,
    Color shadow);
  public static Border createLineBorder(Color color);
  public static Border createLineBorder(Color color, int thickness);
  public static Border createLoweredBevelBorder();
  public static MatteBorder createMatteBorder(int top, int left, int bottom,
    int right, Color color);
  public static MatteBorder createMatteBorder(int top, int left, int bottom,
    int right, Icon icon);
  public static Border createRaisedBevelBorder();
  public static TitledBorder createTitledBorder(Border border);
  public static TitledBorder createTitledBorder(Border border, String title);
  public static TitledBorder createTitledBorder(Border border, String title,
    int justification, int position);
  public static TitledBorder createTitledBorder(Border border, String title,
    int justification, int position, Font font);
  public static TitledBorder createTitledBorder(Border border, String title,
    int justification, int position, Font font, Color color);
  public static TitledBorder createTitledBorder(String title);
}我們將會在描述特定的邊框類型的過程中描述這個類的不同方法。例如,要創建一個具有紅線的邊框,我們可以使用下面的語句,然後將這個邊框關聯到一個組件。


Border lineBorder = BorderFactory.createLineBorder(Color.RED);7.1.3 Starting with AbstractBorder
在我們瞭解javax.swing.border包中單個的邊框之前,一個系統邊框需要獲得特別的關註:AbstractBorder。正如前面所提到的,AbstractBorder類是其他的預定義邊框的父類。


創建AbstractBorder


AbstractBorder有一個構造函數:


public AbstractBorder()因為AbstractBorder是其他標準邊框的父類,這個構造函數實際是為其他邊框類自動調用的。


檢測AbstractBorder方法


AbstractBorder類提供瞭Border接口的三個方法實現。


public Insets getBorderInsets(Component c)AbstractBorder的內部區域是零。每一個預定義的子類要重寫getBorderInsets()方法。


public boolean isBorderOpaque()AbstractBorder的默認非透明屬性設置為false。這就意味著如果我們需要繪制類似點劃線

發佈留言