swing入門教程

(轉自http://terrificwanjun.bokee.com/)php

UI 組件簡介html

在開始學習 Swing 以前,必須回答針對真正初學者的一個問題:什麼是 UI?初學者的答案是用戶界面。可是由於本教程的目標是要保證您再也不只是個初學者,因此咱們須要比這個定義更高級的定義。java

因此,我再次提出這個問題:什麼是 UI?您可能把它定義成您按下的按鈕、打字的地址欄 、打開和關閉的窗口,等等,這些都是 UI 的元素,可是除了在屏幕上看到的這些以外,還有更多都是 UI 元素。好比鼠標、鍵盤、音量、屏幕顏色、使用的字體,以及一個對象相對於另外一個對象的位置,這些都包含在 UI 之中。實際上,在計算機和用戶的交互之中扮演角色的任何對象都是 UI 的組成部分。這看起來足夠簡單,可是您應當驚訝的是,有許多人和大型公司已經爲它努力了不少年。實際上,如今有的大學專業的唯一課程就是研究這種交互。數據庫

Swing 的角色設計模式

Swing 是 Java 平臺的 UI —— 它充當處理用戶和計算機之間所有交互的軟件。它實際上充當用戶和計算機內部之間的中間人。Swing 究竟是如何作這項工做的呢?它提供了處理前面一節中描述的 UI 各方面內容的機制:數組

  • 鍵盤:Swing 提供了捕捉用戶輸入的方法。
  • 顏色:Swing 提供改變在屏幕上看到的顏色的方法。
  • 打字的地址欄:Swing 提供了文本組件,處理全部普通任務。
  • 音量:Swing 不太擅長。

不管如何,Swing 爲您提供了建立本身的 UI 所須要的全部工具瀏覽器

 

 

 

MVC安全

Swing 甚至走得更遠一步,在基本的 UI 原則之上又放上了一個公共的設計模式。這個設計模式叫作模型-視圖-控制器(Model-View-ControllerMVC),它試圖把角色分開MVC 讓負責顯示的代碼、處理數據的代碼、對交互進行響應並驅動變化的代碼彼此分離。服務器

有點迷惑?若是我爲這個設計模式提供一個現實世界的非技術性示例,它就比較容易了。請想像一次時裝秀。把秀場當成 UI,假設服裝就是數據,是展現給用戶的計算機信息。如今,假設此次時裝秀中只有一我的。這我的設計服裝、修改服裝、同時還在 T 臺上展現這些服裝。這看起來可不是一個構造良好的或有效率的設計。架構

如今,假設一樣的時裝秀採用 MVC 設計模式。此次不是一我的作每件事,而是將角色分開。時裝模特(不要與 MVC 縮寫中的模型混淆)展現服裝。他們扮演的角色是視圖。他們知道展現服裝(數據的)適當方法,可是根本不知道如何建立或設計服裝。另外一方面,時裝設計師充當控制器。時裝設計師對於如何在 T 臺上走秀沒有概念,但他能建立和操縱服裝。時裝模特和設計師都能獨立地處理服裝,但都有本身的專業領域。

這就是 MVC 設計模式背後的概念:讓 UI 的每一個方面處理它擅長的工做。若是您仍然不明白,那麼教程後面的示例有望消除您的迷惑 —— 可是在您繼續進行的時候,請記住基本的原則:用可視組件顯示數據,同時讓其餘類操縱數據。

JComponent

Swing 的整個可視組件庫的基礎構造塊是 JComponent。它是全部組件的父類。它是一個抽象類,因此不能建立 JComponent,可是做爲類層次結構的結果,從字面意義來講它包含了數百個函數,Swing 中的每一個組件均可以使用這些函數。顯然,有些概念要比其餘概念重要,因此對於本教程,須要學習的重要的東西是:

  • JComponent 不只是 Swing 組件的基類,仍是定製組件的基類(有關的更多信息在「中級 Swing」教程中)。
  • 它爲全部組件提供了繪製的基礎架構 —— 一些方便進行組件定製的東西(一樣,在「中級 Swing」中,有關於這個主題的更多信息)。
  • 它知道如何處理全部的鍵盤按鍵。因此類只須要偵聽特定的鍵。
  • 它包含 add() 方法,能夠添加其餘 JComponent。換種方式來看,能夠把任意 Swing 組件添加到其餘任何 Swing 組件,從而構造嵌套組件(例如,JPanel 包含 JButton,甚至包含一些古怪的組合,例如 JMenu 包含 JButton)。


簡單的swing小部件

JLabel

Swing 庫中最基礎的組件是 JLabel。它所作的正是您所指望的:呆在那兒,看起來很漂亮,描述其餘組件。下圖顯示了的 JLabel 實際應用:

JLabel

 

不太吸引人,可是仍然有用。實際上,在整個應用程序中,不只把 JLabel 用做文本描述,還將它用做圖片描述。每當在 Swing 應用程序中看到圖片的時候,它就有多是 JLabel。JLabel 對於 Swing 初學者來講沒有許多意料以外的方法。基本的方法包括設置文本、圖片、對齊以及標籤描述的其餘組件:

  • get/setText(): 獲取/設置標籤的文本。
  • get/seticon(): 獲取/設置標籤的圖片。
  • get/setHorizontalAlignment(): 獲取/設置文本的水平位置。
  • get/setVerticalAlignment(): 獲取/設置文本的垂直位置。
  • get/setDisplayedMnemonic(): 獲取/設置標籤的訪問鍵(下劃線文字)。
  • get/setLableFor(): 獲取/設置這個標籤附着的組件,因此當用戶按下 Alt+訪問鍵時,焦點轉移到指定的組件。

 

 JButton

Swing 中的基本動做組件 JButton,是與每一個窗口中都能看到的 OK 和 Cancel 同樣的按鈕;這些按鈕所作的正是您但願它們作的工做 —— 在單擊它們以後,將發生一些事情。到底會發生什麼呢?您必須定義發生的內容(請參閱 事件,以得到更多信息)。一個 JButton 實例看起來以下所示:

JButton

 

用來改變 JButton 屬性的方法與 JLabel 的方法相似(您可能發現,在大多數 Swing 組件中,這些屬性都相似)。它們控制文本、圖片和方向:

  • get/setText(): 獲取/設置標籤的文本。
  • get/seticon(): 獲取/設置標籤的圖片。
  • get/setHorizontalAlignment(): 獲取/設置文本的水平位置。
  • get/setVerticalAlignment(): 獲取/設置文本的垂直位置。
  • get/setDisplayedMnemonic(): 獲取/設置訪問鍵(下劃線字符),與 Alt 按鈕組合時,形成按鈕單擊。

除了這些方法,我還要介紹 JButton 包含的另一組方法。這些方法利用了按鈕的全部不一樣狀態。狀態是對組件進行描述的一個屬性,一般採用真/假設置。在 JButton 中,能夠包含如下可能狀態:活動/不活動、選中/沒選中、鼠標通過/鼠標離開、按下/沒按下,等等。另外,能夠組合這些狀態,例如按鈕能夠在鼠標通過的同時被選中。如今您可能會問本身用這些狀態到底要作什麼。做爲示例,請看看您的瀏覽器上的後退按鈕。請注意在鼠標通過它的時候,圖片是如何變化的,在按下該按鈕時,圖片又是如何變化的。這個按鈕利用了不一樣的狀態。每一個狀態採用不一樣的圖片,這是提示用戶交互正在進行的一種廣泛而且有效的方式。JButton 上的狀態方法是:

  • get/setDisabledIcon()
  • get/setDisableSelectedIcon()
  • get/setIcon()
  • get/setPressedIcon()
  • get/setRolloverIcon()
  • get/setRolloverSelectedIcon()
  • get/setSelectedIcon()

 

JTextField

Swing 中的基本文本組件是 JTextField,它容許用戶在 UI 中輸入文本。我確定您熟悉文本字段:要掌握本教程,則必須使用一個文本字段輸入用戶名和口令。您輸入文本、刪除文本、選中文本、把文字四處移動 —— Swing 替您負責全部這些工做。做爲 UI 開發人員,利用 JJTextField 時,實際上並不須要作什麼。

在任何狀況下,這是 JTextField 實際使用時看起來的樣子:

JTextField

 

在處理 JTextField 時,只須要關注一個方法 —— 這應當是很明顯的,這個方法就是設置文本的方法: get/setText(),用於獲取/設置 JTextField 中的文本。

 

JFrame

迄今爲止,我介紹了 Swing 的三個基本構造塊:標籤、按鈕和文本字段;可是如今須要個地方放它們,但願用戶知道如何處理它們。JFrame 類就是作這個的——它是一個容器,容許您把其餘組件添加到它裏面,把它們組織起來,並把它們呈現給用戶。它有許多其餘好處,可是我認爲先看看它的圖片最簡單:

JFrame

 

JFrame 實際上不只僅讓您把組件放入其中並呈現給用戶。比起它表面上的簡單性,它其實是 Swing 包中最複雜的組件。爲了最大程度地簡化組件,在獨立於操做系統的 Swing 組件與實際運行這些組件的操做系統之間,JFrame 起着橋樑的做用。JFrame 在本機操做系統中是以窗口的形式註冊的,這麼作以後,就能夠獲得許多熟悉的操做系統窗口的特性:最小化/最大化、改變大小、移動。可是對於本教程的目標來講,把 JFrame 看成放置組件的調色板就足夠了。能夠在 JFrame 上調用的一些修改屬性的方法是:

  • get/setTitle(): 獲取/設置幀的標題。
  • get/setState(): 獲取/設置幀的最小化、最大化等狀態。
  • is/setVisible(): 獲取/設置幀的可視狀態,換句話說,是否在屏幕上顯示。
  • get/setLocation(): 獲取/設置幀在屏幕上應當出現的位置。
  • get/setsize(): 獲取/設置幀的大小。
  • add(): 將組件添加到幀中。

 

 

簡單應用程序

就像全部的「x 入門教程同樣,本教程也包含必不可少的 HelloWorld 演示。但這個示例不只對觀察 Swing 應用程序如何工做有用,還對確保設置正確頗有用。一旦使這個簡單的應用程序可以成功運行,那麼以後的每一個示例也將可以運行。下圖顯示了完成後的示例:

HelloWorld 示例

第一步是建立類。將組件放在 JFrame 上的 Swing 應用程序須要繼承JFrame 類,以下所示:

 publicclassHelloWorldextendsJFrame

這樣作以後,就獲得上面描述的全部 JFrame 屬性,最重要的是操做系統對窗口的本機支持。下一步是把組件放在屏幕上。在這個示例中,使用了一個 null 佈局。在教程的後面部分,您將學到更多關於佈局和佈局管理器的內容。但對於這個示例,能夠用數字表示 JFrame 上的像素位置:

    publicHelloWorld()
    {
      super();
      this.setSize(300,200);
       this.getContentPane().setLayout(null);
      this.add(getJLabel(),null);
      this.add(getJTextField(),null);
      this.add(getJButton(),null);
      this.setTitle("HelloWorld");
    }
  
   privatejavax.swing.JLabel getJLabel() {
      if(jLabel ==null) {
          jLabel =newjavax.swing.JLabel();
          jLabel.setBounds(34,49,53,18);
          jLabel.setText("Name:");
       }
      returnjLabel;
    }
  
   privatejavax.swing.JTextField getJTextField() {
      if(jTextField ==null) {
          jTextField =newjavax.swing.JTextField();
          jTextField.setBounds(96,49,160,20);
       }
      returnjTextField;
    }
  
   privatejavax.swing.JButton getJButton() {
      if(jButton ==null) {
          jButton =newjavax.swing.JButton();
          jButton.setBounds(103,110,71,27);
          jButton.setText("OK");
       }
      returnjButton;
    }

如今組件都放在了 JFrame 上,而且須要在屏幕上顯示 JFrame,並讓應用程序能夠運行。就像在全部的 Java 應用程序中同樣,必須添加一個 main 方法,才能讓 Swing 應用程序運行。在這個 main 方法中,只須要建立 HelloWorld 應用程序對象,而後調用其setVisible()便可:

  
    publicstaticvoidmain(String[] args)
    {
       HelloWorld w =newHelloWorld();
       w.setVisible(true);
    }

完成了!這就是建立應用程序的全部過程。

 

完整代碼以下:

 

package cn.edu.jnu.www;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class HelloWorld extends JFrame{
 private JLabel jLabel;
 private JTextField jTextField;
 private JButton jButton;
 
public HelloWorld()
{
   super();
   this.setSize(300, 200);
   this.getContentPane().setLayout(null);
   this.add(getJLabel(), null);
   this.add(getJTextField(), null);
   this.add(getJButton(), null);
   this.setTitle("HelloWorld");
}

private javax.swing.JLabel getJLabel() {
   if(jLabel == null) {
      jLabel = new javax.swing.JLabel();
      jLabel.setBounds(34, 49, 53, 18);
      jLabel.setText("Name:");
   }
   return jLabel;
}

private javax.swing.JTextField getJTextField() {
   if(jTextField == null) {
      jTextField = new javax.swing.JTextField();
      jTextField.setBounds(96, 49, 160, 20);
   }
   return jTextField;
}

private javax.swing.JButton getJButton() {
   if(jButton == null) {
      jButton = new javax.swing.JButton();
      jButton.setBounds(103, 110, 71, 27);
      jButton.setText("OK");
   }
   return jButton;
}


public static void main(String[] args)
{
   HelloWorld w = new HelloWorld();
   w.setVisible(true);
}

}




附加的swing小部件(上)

JComboBox

在這一節中,我將介紹 Swing 庫中的其餘所有組件、如何使用它們、它們看起來是什麼樣的,等等,這部份內容應當讓您更好地瞭解 Swing 爲 UI 開發人員提供了什麼。

咱們從 JComboBox 開始介紹。組合框與下拉選擇類似,區別在於使用組合框時用戶能夠不從列表中選擇項目,還能夠選擇一個(並且只有一個)項目。在某些版本的組合框中,還能夠輸入本身的選擇。瀏覽器的地址欄就是一個示例:它是一個容許輸入本身選項的組合框。如下是 JComboBox 在 Swing 中看起來的樣子:

JComboBox
JComboBox

JComboBox 的重要函數包括 JComboBox 包含的數據。須要有一種方法來設置 JComboBox 中的數據、修改數據、在用戶選擇時獲得用戶的選擇。可使用如下 JComboBox 方法:

  • addItem()添加一個項目到 JComboBox.
  • get/setSelectedIndex()獲取/設置 JComboBox 中選中項目的索引。
  • get/setSelectedItem()獲取/設置選中的對象。
  • removeAllItems()從 JComboBox 刪除全部對象。
  • remoteItem()從 JComboBox 刪除特定對象。

JTextField

JTextField 的一個細微變化是 JPasswordField,它容許您隱藏在文本字段區域中顯示的字符。畢竟,在您輸入口令的時候,若是每一個人都能看到,那可沒什麼好處?可能根本就很差,並且在私人數據如此脆弱的今天,您須要全部可以獲得的幫助。如下是 JPasswordField 在 Swing 中看起來的樣子:

JPasswordField
JPasswordField

JPasswordField 上額外的「安全性」方法對 JTextField 的行爲作了輕微改變,因此不能閱讀文本:

  • get/setEchoChar()獲取/設置每次字符輸入時在 JPasswordField 中顯示的字符。在獲取口令時,不會返回「回聲」,而是返回實際的字符。

  • getText() 不該當 使用這個函數,由於它會帶來可能的安全問題(String 會保存在內存中,可能的堆棧轉儲會暴露口令)。

  • getPassword()這是從 JPasswordField 中得到口令的恰當方法,由於它返回一個包含口令的 char[]。爲了保證恰當的安全性,數組應當被清爲 0,以確保它不會保留在內存中。

 JCheckBox/JRadioButton

JCheckBox 和 JRadioButton 組件向用戶呈現選項,一般採用多選的格式。區別是什麼?從實踐的角度來講,它們沒有那麼不一樣。它們的行爲方式相同。可是,在通常的 UI 實踐中,它們有細微差別:JRadioButton 一般組合在一塊兒,向用戶呈現帶有必選答案的問題,並且這些答案具備強制性(這意味着問題只能有一個答案)。JRadioButton 的行爲保證了這個用法。一旦選擇了JRadioButton,就不能取消對它的選擇,除非選擇了在同一組中的另一個單選鈕。從效果上看,這就保證了選項的唯一和必選。JCheckBox 的不一樣在於,容許隨機地選擇/取消除選擇,並容許爲問題選擇多個答案。

這裏是個示例。問題「您是男孩仍是女孩!」有兩個唯一答案選項「男孩」或「女孩」。用戶必須選擇一個,不能同時選中。另外一方面,問題「您的習慣是什麼?」的答案有「跑步」、「睡覺」或「閱讀」,不該當只容許爲此問題選擇一個答案,由於人們可能有不止一個習慣。

把這些 JCheckBoxe 或 JRadioButton 捆綁成一組的類是 ButtonGroup 類。它容許把選項組織在一塊兒(例如「男孩」和「女孩」),這樣,其中一個被選擇時,另一個就自動取消選擇。

如下是 JCheckBox 和 JRadioButton 在 Swing 中看起來的樣子:

JCheckBox 和 JRadioButton
JCheckBox/JRadioButton

須要記住的重要的 ButtonGroup 方法是:

  • add()添加 JCheckBox 或 JRadioButton 到 ButtonGroup。
  • getElements()得到 ButtonGroup 中的所有組件,容許對它們進行迭代,找到其中選中的那個。

 JMenu/JMenuItem/JMenuBar

JMenu、JMenuItem 和 JMenuBar 組件是在 JFrame 中開發菜單系統的主要構造塊。任何菜單系統的基礎都是 JMenuBar。它平淡而乏味,但倒是必需的,由於每一個 JMenu 和 JMenuItem 都要用它構建。要用 setJMenuBar() 方法把 JMenuBar 附着到 JFrame。一旦將它附加到 JFrame 中,就能夠添加全部想要的菜單、子菜單和菜單項。

JMenu/JMenuItem 的區別看起來可能很明顯,但實際上,在幕後看起來並不像表面那樣。看看類的類層次結構,就知道JMenu 是 JMenuItem 的子類。可是,在表面上,它們是有區別的:用 JMenu 包含其餘 JMenuItem 和 JMenu;JMenuItem 在選中時觸發操做。

JMenuItem 也支持快捷鍵的概念。與您用過的大多數應用程序同樣,Swing 應用程序容許您按下 Ctrl+(某個鍵)來觸發一個操做,就像選中菜單鍵自己同樣。想一想用來剪切和粘貼的快捷鍵 Ctrl+X 和 Ctrl+V。

除此以外,JMenu 和 JMenuItem 都支持訪問鍵。用 Alt 鍵與某個字母關聯,模擬菜單自己的選擇(例如,在 Windows 中按下 Alt+F,而後按下 Alt+x 就能夠關閉應用程序)。

如下是包含 JMenu 和 JMenuItem 的 JMenuBar 在 Swing 中的樣子:

JMenuBar、JMenu 和 JMenuItem
JMenuBar/JMenu/JMenuItem

這些類須要的重要方法是:

  • JMenuItem and JMenu:
    • get/setAccelerator()獲取/設置用做快捷鍵的 Ctrl+鍵。
    • get/setText()獲取/設置菜單的文本。
    • get/setIcon()獲取/設置菜單使用的圖片。


  • JMenu 專用:
    • add()添加另一個 JMenu 或 JMenuItem 到 JMenu(建立嵌套菜單)。

 JSlider

在應用程序中 JSlider 支持數值變化。它是一種迅速而簡單的方式,不只能讓用戶以可視形式得到他們當前選擇的反饋,還能獲得能夠接受的值的範圍。想像一下這種狀況:能夠提供一個文本字段,容許用戶輸入值,可是這樣作就帶來了額外的麻煩,要確保輸入的值是數字,還要確保數字符合要求的數值範圍。例如,若是有一個金融 Web 站點,它向您提問要在股票上投資的百分比,那麼您不得不檢查在文本字段中輸入的值,以確保它們是數字,並且在 0 到 100 之間。若是換用 JSlider,那麼就能夠確保選擇的是指定範圍內的數字。

在 Swing 中,JSlider 看起來以下所示:

JSlider
JSlider

JSlider 中的重要方法是:

  • get/setMinimum()獲取/設置能夠選擇的最小值。
  • get/setMaximum()獲取/設置能夠選擇的最大值。
  • get/setOrientation()獲取/設置 JSlider 是上/下仍是左/右滾動條。
  • get/setValue()獲取/設置 JSlider 的初始值。

 JSlider

與 JSlider 很是像,能夠用 JSpinner 容許用戶選擇一個整數值。JSlider 的一個主要優點就是比 JSlider 的空間緊湊。可是,它的不足就是沒法方便地設置其邊界。

可是,兩個組件之間的比較僅此而已。JSpinner 更加靈活,能夠用來在任意組的值之間進行選擇。除了在數字間選擇,它還能夠用來在日期、名稱、顏色和任何事之間進行選擇。這使 JSpinner 極爲強大,容許您提供其中只包含預約義的選擇的組件。使用這種方式,它與 JComboBox 相似,可是它們的應用不能互換。只應把 JSpinner 用在邏輯上連續的選擇 —— 數字和日期是最合邏輯的選擇。而另外一方面,在呈現看起來隨機的選擇而且選擇之間沒有鏈接的時候,JComboBox 是更好的選擇。

JSpinner 看起來以下所示:

JSpinner
JSpinner

重要方法是:

  • get/setValue()獲取/設置 JSpinner 的初始值,在基本實例中,須要是整數。
  • getNextValue()獲取按下上箭頭按鈕以後應當選中的下一個值。
  • getPreviousValue()獲取按下下箭頭按鈕以後應當選中的前一個值。

 JToolBar

JToolBar 充當其餘組件(JButton、JComboBoxe 等)的調色板,共同構成您在大多數應用程序中熟悉的工具欄。工具欄容許程序把經常使用的命令放在能夠迅速發現的位置,並把它們以經常使用命令組的形式組合在一塊兒。通常(但不老是這樣)狀況下,工具欄按鈕在菜單欄中會有對應的命令。雖然這不是必需的,但已經變成了一種公共實踐,您也應當試着這麼作。

JToolBar 也提供了您在其餘工具欄中看到過的其餘功能:「浮動」的能力(也就是成爲主幀頂部獨立的幀)。

下圖顯示了一個非浮動 JToolBar:

非浮動 JToolBar
非浮動 JToolBar

對於 JToolBar,要記住的重要方法是:is/setFloatable(),它獲取/設置 JToolBar 是否能夠浮動。

 JToolTip

您可能處處都看到過 JToolTip,可是歷來不知道它們叫什麼。它們就像您鞋帶上的塑料部件 —— 處處都有,可是您就是不知道它們正確的名字(若是您想知道,那麼能夠叫它們 金屬箍)。JToolTip 就是您將鼠標停留在某個東西上面的時候彈出來的小「泡泡」。它們在應用程序中可能很是有用,能夠爲難用的項目提供幫助、擴展信息,甚至在擁擠的 UI 中顯示某個項目的完整文本。在 Swing 中,能夠經過把鼠標放在某個組件上的特定時間來觸發它們;它們一般在鼠標處於不活動狀態大約 1 秒鐘以後顯示。只要鼠標還停留在那個組件上,它們就保持可見。

JToolTip 的重要部分是它的易用性。setToolTip() 方法是 JComponent 類中的一個方法,這意味着每一個 Swing 組件都能有一個與之關聯的工具提示。雖然JToolTip 自己也是一個 Swing 類,但目前,對於您的須要,它確實沒有提供更多功能,並且自己也不應被建立。能夠經過調用 JComponent 的 setToolTip() 函數訪問和使用它。

如下是 JToolTip 看起來的樣子:

A JToolTip
JToolTip



附加的swing小部件(下)

JOptionPane

JOptionPane 是在 Swing 中相似「快捷方式」的東西。一般,做爲 UI 開發人員,您須要向用戶呈現快速信息,讓用戶瞭解錯誤和信息。甚至可能想獲得一些快速數據,例如名稱或數字。在 Swing 中,JOptionPane 類爲這些東西提供了快捷方式,但這並非它必須完成的任務。不須要讓每一個開發人員重頭開始重複相同的工做,Swing 已經提供了這個基本的但頗有用的類,爲 UI 開發人員提供了獲取和接收簡單消息的簡易方法。

如下是一個 JOptionPane:

JOptionPane
JOptionPane

使用 JOptionPane 時有點麻煩的是可使用的所有選項。雖然簡單,可是它仍然提供了大量選項,這些選項有可能形成混淆。學習 JOptionPane 的最好方法就是使用它;編寫代碼,觀察彈出的是什麼。這個組件幾乎可讓您修改它的每一方面:幀標題、消息自己、顯示的圖標、按鈕選項,以及是否須要文本響應。由於有太多的可能性,沒法在本教程中一一列舉它們,因此您最好是訪問 JOptionPane 的 API 頁面,查看它的衆多可能性。

 JTextArea

JTextArea 比 JTextField 更進了一步。JTextField 被侷限在一行文本中,而 JTextArea 擴展了這個能力,支持多行文本。能夠把它想像成一個空白頁,您能夠在其中的任意地方進行輸入。正如您可能猜到的,JTextArea 包含許多與 JTextField 相同的功能,畢竟,它們其實是相同的組件。可是 JTextArea 提供了一些額外的重要功能,能夠把它區別開。這些功能包括單詞自動換行的能力(即把長文本自動換行到下一行,而不是將單詞從中斷開)、對文本自動換行的能力(即把長的文本行移動到下一行,而不是建立一個須要水平滾動條的很是長的行)。

Swing 中的 JTextArea 看起來就像您指望的那樣:

A JTextArea
JTextArea

支持行和單詞的自動換行的重要方法是:

  • is/setLineWrap()設置在行過長的時候是否要自動換行。
  • is/setWrapStyleWord()設置在單詞過長的時候是否要把長單詞移到下一行。

 JScrollPane

上面的示例構造完成以後,假設 JTextArea 包含太多文本,而給定的空間中容納不下,那這該怎麼辦?若是您覺得會自動出現滾動條,那麼很不幸,您錯了。JScrollPane 添補了這個空白,爲 Swing 組件提供了處理全部與滾動條相關的動做。因此雖然爲每一個須要的組件提供滾動塊可能有些痛苦,可是一旦添加了它,它就會自動處理每件事,包括在須要的時候隱藏/顯示滾動條。

除了用須要自動換行的組件建立 JScrollPane 以外,沒必要直接處理它。根據上面的示例,用 JTextArea 調用 JScrollPane 的構造函數,這爲 JTextArea 建立了在文本過長時滾動的能力:

 JScrollPane scroll = new JScrollPane(getTextArea()); add(scroll);

更新後的示例看起來以下所示:

JScrollPane 示例
JScrollPane

JScrollPane 也公開了它將建立的兩個 JScrollBar。這些 JScrollBar 組件也包含一些方法,能夠用這些方法來修改組件的行爲(雖然它們不在本教程的範圍以內)。

使用 JScrollPane 須要的方法是:

  • getHorizontalScrollBar()返回水平的 JScrollBar 組件。
  • getVerticalScrollBar():返回垂直的 JScrollBar 組件.
  • get/setHorizontalScrollBarPolicy()這個「策略」能夠是如下三個之一:Always、Never 或 As Needed。
  • get/setVerticalScrollBarPolicy()與水平函數相同。

JList

 

JList 是一個有用的組件,用於向用戶呈現許多選擇。能夠把它看成 JComboBox 的擴展。JList 提供了更多選擇,並添加了多選的能力。在 JList 與 JComboBox 之間進行選擇一般取決於如下兩個特性:若是須要多選,或者選擇的選項超過 15 個(雖然這個數字並非通用規則),那麼就應當選擇 JList。

應用將 JList 與 JScrollPane 結合使用,就像上面演示的那樣,由於它可以呈現比它的空間所能容納的更多的選項。

JList 包含選擇模型的概念(在 JTable 中也會看到),在這裏,能夠設置 JList 接受不一樣類型的選擇。這些類型是:單一選擇(只能選擇一項)、單一間隔選擇(只能選擇相鄰選項),以及任意多項或者多項間隔選擇(能夠選擇任意數量、任意組合的選擇)。

JList 是第一個我稱爲 「複雜組件」 的組件,該複雜組件還包含 JTable 和 JTree,它們支持大量的定製變化,其中包括改變 UI 的表現方式、處理數據的方式。由於本教程只是想介紹基礎知識,因此我不想深刻這些更高級的功能,可是在使用這些組件時有件事須要記住 —— 它們帶來的挑戰要比目前爲止介紹過的全部組件都大。

JList 在 Swing 中看起來以下所示:

JList
JList

JList 中有許多處理數據的函數,並且根據個人說法,這些也只不過是使用 JList 的細節的皮毛而已。如下是一些基本方法:

  • get/setSelectedIndex()獲取/設置列表中選中的行;在多選擇列表的狀況下,返回一個 int[]
  • get/setSelectionMode()與上面解釋的同樣,獲取/設置選擇模式,模式有:單1、單一間隔和多選間隔。
  • setListData()設置在 JList 中使用的數據。
  • get/setSelectedValue()得到選中的對象(與選中行號對應)。

 JTable

在考慮 JTable 時,請想像一下一個 Excel 工做表,這樣就能夠對 JTable 在 Swing 中的做用有一個清晰的印象。它與工做表共享許多相同的特徵:單元格、行、列、移動列、隱藏列等。JTable 把 JList 的想法更進了一步。它不是在一列中顯示數據,而是在多列中顯示數據。讓咱們以人爲例。JList 只能顯示人的一個屬性 —— 例如他或她的名字。而 JTable 就可以顯示多個屬性 —— 名字、年齡、地址,等等。JTable 是支持提供數據的大多數信息的 Swing 組件。

不幸的是,做爲代價,JTable 也是最難對付的 Swing 組件。許多 UI 開發人員都爲了學習 JTable 的每一個細節而頭痛。在這裏,我但願我把能把您解救出來,只用您的 JTable 知識處理問題。

許多 JList 中的概念也擴展到了 JTable,其中包括不一樣的選擇間隔的概念。可是 JList 中一列的概念變成了 JTable 的單元格的概念。這意味着在 JTable 中進行選擇時會有不一樣的方式,例如列、行或者一個單元格。

在 Swing 中,JTable 看起來以下所示:

JTable
JTable

最後,JTable 的大多數函數都超出本教程的範圍;「中級 Swing」會深刻這個複雜組件的更多細節。

 JTree

JTree 是另一個複雜組件,它不像 JTable 那樣難用,可是也不像 JList 那麼容易。使用 JTree 時麻煩的部分是它要求的數據模型。

JTree 的功能來自樹的概念,樹有分支和葉子。您在 Windows 中使用 IE 瀏覽器時,可能很是熟悉這個概念 —— 能夠展開和摺疊分支,顯示能夠選擇和取消選擇的不一樣葉子。

您頗有可能發現樹在應用程序中不像表格或列表那樣有用,因此在 Internet 上沒有許多有幫助的這方面的示例。實際上,像 JTable 同樣,JTree 沒有什麼入門級的功能。若是決定使用 JTree,那麼當即就能夠達到中級水平,固然還必須學習隨之而來的概念。所以,示例應用程序沒有介紹 JTree,因此也很不幸,無論是入門教程仍是中級教程,都沒有涉及這個不太流行的組件。

可是,樹有一些時候是符合需求的合理的 UI 組件。文件/目錄系統就是一個示例(就像在 IE 瀏覽器中那樣),並且當數據採起層次結構的時候,也就是說數據採用樹的形式的時候,JTree 就是最佳組件。

在 Swing 中,JTree 看起來以下所示:

JTree
JTree



Swing概念

佈局、模型和事件

既然您已經知道了大多數(確定不是所有)能夠用來製做 UI 的組件,那麼就必須實際用它們作些什麼。您不能只是隨意地把它們放在屏幕上,而後就期望它們當即就能工做。您必須把它們放在特定的點上,對它們的交互做出反應,而後根據交互更新它們,用數據填充它們。要填滿 UI 知識的這片空白,還須要更多地學習 UI 的其餘重要部分。

因此,讓咱們來研究如下內容:

 

  • 佈局:Swing 包括許多佈局,佈局也是類,負責處理組件在應用程序中的擺放位置,以及在應用程序改變尺寸或者刪除、添加組件時對組件進行相應處理。

  • 事件:您須要對按下按鈕、單擊鼠標和用戶在 UI 上能作的每件事進行響應。想像一下,若是不能響應會發生什麼 —— 用戶單擊以後,什麼變化也沒有。

  • 模型: 對於更高級的組件(列表、表格和樹),以及一些像 JComboBox 這樣的更容易的組件來講,模型是處理數據最有效的途徑。它們把大部分處理數據的工做從實際的組件自己撤出來(請回想一下前面討論的 MVC),並提供了一個公共數據對象類(例如 Vector 和ArrayList)的包裝器。

簡單佈局

就像在前面提到過的,佈局替您處理組件在應用程序中的擺放。您的第一個問題多是「爲何不能用像素告訴它應當在什麼地方呢?」是的,您能夠這樣作,可是在窗口改變大小的時候,或者更糟一些狀況,即用戶改變其屏幕的分辨率的時候,亦或在有人想在其餘操做系統上試用應用程序的時候,您馬上就會遇到麻煩。佈局管理器把這些擔憂一掃而空。不是每一個人都用相同的設置,因此佈局管理器會建立「相對」佈局,容許您指定組件相對於其餘組件的擺放方式,決定事物改變尺寸的方式。這是好的部分:比聽起來更容易。只要調用 setLayout(yourLayout) 設置佈局管理器便可。後面對 add() 的調用能夠將組件添加到容器中,並讓佈局管理器負責將它放在應當的位置上。

目前在 Swing 中包含了大量佈局;看起來好象每次發佈都會有一個新佈局負責不一樣的目的。可是,有些通過實踐檢驗的佈局一直存在,並且會永遠存在,我指的是永遠 —— 由於從 1995 年 Java 語言的第一個發行版開始,就有這些佈局。這些佈局是:FlowLayout、GridLayout 和 BorderLayout。

FlowLayout 從左到右安排組件。當空間不足時,就移到下一行。它是使用起來最簡單的佈局,所以,也就是能力最弱的佈局:

 setLayout(new FlowLayout()); add(new JButton("Button1")); add(new JButton("Button2")); add(new JButton("Button3"));

FlowLayout 實例
FlowLayout

GridLayout 就像您想像的那樣工做:它容許指定行和列的數量,而後在添加組件時把組件放在這些單元格中:

 setLayout(new GridLayout(1,2)); add(new JButton("Button1")); add(new JButton("Button2")); add(new JButton("Button3"));

GridLayout 實例
GridLayout

即便 Swing 中添加了許多新的佈局管理器,BorderLayout 仍然是其中很是有用的一個。即便有經驗的 UI 開發人員也常用 BorderLayout。它使用東、南、西、北、中的概念在屏幕上放置組件:

 setLayout(new BorderLayout()); add(new JButton("Button1"), "North"); add(new JButton("Button2"), "Center"); add(new JButton("Button3"), "West");

BorderLayout 實例
BorderLayout

 GridBagLayout

雖然上面的示例對於簡單的佈局來講很好,可是更高級的 UI 須要更高級的佈局管理器。這是 GridBagLayout 發揮做用的地方。不幸的是,使用它的時候極易混淆、極爲困難,每一個曾經用過它的人都會贊成這點。我也不能反對;可是除了它的困難以外,它多是用 Swing 內置的佈局管理器建立漂亮 UI 的最好方式。

如下是個人第一個小建議:在最新版的 Eclipse 中,有內置的可視化構建器,這個個小建議能夠自動根據每一個屏幕的須要來構建必需的 GridBagLayout 代碼。請使用這個功能!它會節約無數爲了讓數字正確而浪費的時間。因此在我用這一節解釋 GridBagLayout 如何工做、如何調整它才能讓它作得最好時,建議您去找一個可視化構建器並生成代碼。它會節約您的工做時間

事件

最後,咱們來到 Swing 最重要的一部分:處理事件,對 UI 的交互做出反應。Swing 用事件/偵聽器模型處理事件。這個模型的工做方式是:容許某個類登記到某個組件的某個事件上。登記到事件的這個類叫作偵聽器,由於它等候組件的事件發生,並且在事件發生時採起行動。組件自己知道如何「激活」事件(即,知道它能生成的交互類型,以及如何讓偵聽器知道這個交互何時發生)。組件與包含有關交互信息的事件和類針對交互進行通訊。

把技術方面的空談放在一邊,咱們來看幾個 Swing 中事件的實例。首先從最簡單的示例開始,即一個 JButton,按下它的時候,會在控制檯上輸出「Hello」。

JButton 知道它何時被按下;這是在內部處理的,不須要代碼處理它。可是,偵聽器須要進行登記,以接收來自 JButton 的事件,這樣您才能輸出「Hello」。listener 類經過實現 listener 接口而後調用 JButton 上的 addActionListener() 作到這一點:

 // Create the JButton JButton b = new JButton("Button"); // Register as a listener b.addActionListener(new HelloListener()); class HelloListener implements ActionListener { // The interface method to receive button clicks public void actionPerformed(ActionEvent e) { System.out.println("Hello"); } }

JList 也用相似的方式工做。當有人在 JList 中選中什麼時,您可能想把選中的對象輸出到控制檯上:

 // myList is a JList populate with data myList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { Object o = myList.getSelectedItem(); System.out.println(o.toString()); } } );

從這兩個示例,您應當可以理解事件/偵聽器模型在 Swing 中如何工做了。實際上,Swing 中的每一個交互都是以這種方式處理的,因此經過理解這個模型,您就當即可以理解在 Swing 中如何處理每一個事件,以及如何對用戶可能拋給您的任何交互作反應了。

模型

如今,您應當瞭解了 Java 的集合(Collection),這是一組處理數據的 Java 類。這些類包括 ArrayListHashMap 和 Set。大多數應用程序在反覆處理數據時,常常用這些類。可是,當須要在 UI 中使用這些數據類時,出現了一個限制。UI 不知道如何顯示它們。請先想一分鐘。若是有一個 JList 和一個某種數據對象(例如 Person 對象)的 ArrayListJList 怎樣才能知道要顯示什麼?它是要顯示某我的的名字,仍是連名帶姓一塊兒顯示?

這就是模型的概念發揮做用的地方了。雖然模型這個術語表達的範圍更大,可是在本教程的示例中,我用 UI 模型這個術語描述組件用來顯示數據的類。

在 Swing 中每一個處理集合數據的的組件都採用模型的概念,並且這也是使用和操縱數據的首選方法。它清晰地把 UI 的工做與底層數據分開(請回想 MVC 示例)。模型工做的機制是向組件描述如何顯示集合數據。我說的「描述」指的是什麼呢?每一個組件須要的描述略有不一樣:

 

  • JComboBox 要求其模型告訴它把什麼文本做爲選項顯示,以及有多少選項。

  • JSpinner 要求其模型告訴它顯示什麼文本,前一個和下一個選擇是什麼。

  • JList 也要求其模型告訴它把什麼文本做爲選項顯示,存在多少選項。

  • JTable 要求的更多:它要求模型告訴它存在多少列和多少行,列名稱、每列的類以及在每一個單元格中顯示什麼文本。

  • JTree 要求它的模型告訴它整個樹的根節點、父節點和子節點。

 

您可能會問:爲何要作這麼些工做?爲何要把這些功能分開?請想像如下場景:您有一個複雜的 JTable,有許多列數據,您在許多不一樣的屏幕上使用這個表格。若是您忽然決定刪除某個列,那麼怎麼作會更容易呢?修改您使用的每一個 JTable 實例中的代碼?仍是建立一個能夠在每一個 JTable 實例中使用的模型類,而後只修改這一個模型類呢?顯然,所作的修改越少越好。

模型示例

咱們來看看模型如何工做,在一個簡單的 JComboBox 示例中使用模型。在 JComboBox 前面的演示中,我介紹瞭如何調用 setItem() 向數據中添加項目。雖然對於簡單的演示,這樣作能夠接受,可是在實際的應用程序中不多這麼用。畢竟,在有 25 個選項,並且選項不斷變化的時候,您還真的想每次都調用 addItem()25 次對這些選項進行迭代嗎?固然不是。

JComboBox 包含一個方法調用 setModel(),它接受 ComboBoxModel 類的實例。應當用這個方法代替 addItem() 方法來建立 JComboBox 中的數據。

假設有一個 ArrayList,其中使用字母表做爲其數據(「A」、「B」、「C」 ,等等):

 MyComboModel model = new MyComboModel(alphaList); myComboBox.setModel(model); public class MyComboModel implements ComboBoxModel { private List data = new ArrayList(); private int selected = 0; public MyComboModel(List list) { data = list; } public void setSelectedItem(Object o) { selected = data.indexOf(o); } public Object getSelectedItem() { return data.get(selected); } public int getSize() { return data.size(); } public Object getElementAt(int i) { return data.get(i); } }

採用模型時更好的地方是:您能夠反覆重用它。例如,假設 JComboBox 的數據須要從字母表變成 1 到27 的數字。那麼只用一行就能夠實現這個變化:用新的數據 List 添加 JComboBox,不須要使用額外的代碼:

 myComboBox.setModel(new MyComboModel(numberList));

模型在 Swing 中是很是有好處的特性,由於它們提供了代碼重用功能,並且使數據處理更加容易。更常見的應用是在大型應用程序中,服務器端開發人員建立和檢索數據,並把數據傳遞給 UI 開發人員。如何處理這些數據和正確地顯示它們,取決於 UI 開發人員,而模型就是實現這項任務的工具。



Swing入門(一) (2009-04-21 00:02:20)

(轉自http://terrificwanjun.bokee.com)

package cn.edu.jnu.www;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class test {
 public static void main(String[] args) {
  JFrame a=new JFrame("中繼數據庫系統");
  Container c=new  Container();
  //Swing更強調容器的概念,通常不容許之間將組件放置到頂層容器中
  //而是放在容器框架中,而awt則是直接放的
  a.setSize(200,200);
  a.setLocation(100, 200);
  a.setLayout(new BorderLayout());
  JButton b=new JButton("GO");
  c=a.getContentPane();
  c.add(b,BorderLayout.SOUTH);
  a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  a.setVisible(true);
 }

}



Swing學習(二) (2009-04-21 00:03:22)

(轉自http://terrificwanjun.bokee.com)

 接觸java幾天,本身試着作了第一個java程序,其實只是一個簡單的對話框窗口,不過作起仍是費了半天功夫,主要是對一些語法還不太熟悉,幸好有CSDN上的朋友相助,問題得以解決.

import java.awt.*;
import javax.swing.*;

public void class AboutDialog extends JDialog {              //這裏誤用void,返回空值     
 
  public AboutDialog() {

   this.setTitle("About");                                                    //窗體標題顯示
           this.setSize(320, 200);                                                //窗體的大小
   
       JLabel about = new JLabel("關於:JAVA的一個窗口 :) ");             //對話框內容
        about.setHorizontalAlignment(SwingConstants.CENTER);     //內容顯示在窗口的中央
       this.getContentPane().add(about, BorderLayout.CENTER);
  }

  public static void main(String[] args) throws HeadlessException {
          AboutDialog kk = new  AboutDialog() ;
         kk.setVisible(true);                                                                             //原來的show()顯示已過期
         kk.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);       

 }

}

 
 

上面誤用void生成的結果,有興趣的朋友能夠試試.另外查了一下J2SE API,才知道show( )方法已經被setvisible( )取代.



使用Frame建立窗體

 



在Awt中,Window類沒有邊界和菜單欄,因此不能直接使用Window類來建立窗體,必須使用Window類的子類Frame來建立,建立代碼爲:

 

package cn.edu.jnu.www;

import java.awt.*;
import java.awt.event.*;
public class FrameTest {
 public static void main(String[] args) {
  // TODO 自動生成方法存根 
  Frame myFrame=new Frame("Hello");
  //Frame 是帶有標題和邊界的頂層窗口
  
  myFrame.setLocation(250, 150);
  
  //myFrame.setLayout(new BorderLayout(10,20));
  //設置窗體佈局,BorderLayout裏面的兩個參數用指定的組件之間的水平間距構造一個邊界佈局。
  //BorderLayout爲JAVA中的默認窗體佈局
  
  //myFrame.setLayout(new FlowLayout(FlowLayout.LEFT));
  //設置窗體佈局爲FlowLayout,對齊方式居左對齊
  
  //myFrame.setLayout(new GridLayout(3,2));
  //設置窗體佈局爲GridLayout,將窗體分爲6塊,3行2列
  myFrame.setSize(300,400);
  
  Button myButton1=new Button("east");
  Button myButton2=new Button("south");
  Button myButton3=new Button("west");
  Button myButton4=new Button("north");
  Button myButton5=new Button("center");
  
  //myFrame.add(myButton1,BorderLayout.EAST);
  myFrame.add(myButton1,"East");
  //兩種方法均可以,可是要注意大小寫
  myFrame.add(myButton2,BorderLayout.SOUTH);
  myFrame.add(myButton3,BorderLayout.WEST);
  myFrame.add(myButton4,BorderLayout.NORTH);
  myFrame.add(myButton5,BorderLayout.CENTER);
  
  //myFrame.addWindowListener(new myWindowListener());
  
  
  //使用適配器的方法實現監聽器做用
  //myFrame.addWindowListener(new yourWindowListener());
  
  //使用匿名內部類的方法實現監聽器的功能,只有含有適配器的事件纔可使用此方法
  myFrame.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent e){
    System.exit(0);
   }
  });
  myFrame.setVisible(true);
  //myFrame.show();//eclipse 不建議使用show()方法
 }

}