26
Swing Swing 井井井 井井 http://debut.cis.nctu.edu.tw/~chi

Swing 井民全 製作 ching

  • View
    227

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Swing 井民全 製作 ching

SwingSwing

井民全 製作 http://debut.cis.nctu.edu.tw/~ching

Page 2: Swing 井民全 製作 ching

IntroductionIntroduction

Swing Swing 是 是 Java Java 的的使用者介面工具組使用者介面工具組 例如例如 : : 視窗視窗 ,, 按鈕按鈕 , , 下拉式選單下拉式選單 ,, 樹狀結構樹狀結構目前正式被包含在 目前正式被包含在 Java2 Java2 的 的 API API 中中Swing Swing 使用者介面類別都放在 使用者介面類別都放在 Javax.swingJavax.swing 套件與子套件中套件與子套件中

Page 3: Swing 井民全 製作 ching

A Visual Index to the Swing A Visual Index to the Swing ComponentsComponents

Page 4: Swing 井民全 製作 ching

Other ComponentsOther Components

Reference: Java Tutorials\Sun\uiswing\components\components.html

Page 5: Swing 井民全 製作 ching

Java Foundation ClassesJava Foundation Classes

Swing Swing 是 是 JFC ( java JFC ( java 基礎類別基礎類別 )) 的一部分的一部分JFC JFC 包含以下的部分包含以下的部分 AWT AWT (Abstrqact Window Toolkit,(Abstrqact Window Toolkit, 抽象視窗工具組抽象視窗工具組 )) SwingSwing 2D API2D API Drag and Drop Drag and Drop 的 的 API API 類別類別

Page 6: Swing 井民全 製作 ching

AWT(AWT( 抽象視窗工具組抽象視窗工具組 ))

AWT AWT 在所有平台上都有相同的功能在所有平台上都有相同的功能 為了達到跨平台的效果為了達到跨平台的效果 ,AWT ,AWT 使用使用可替代式的可替代式的 toolkittoolkit

來和執行端的作業系統作溝通來和執行端的作業系統作溝通 ,, 顯示使用者介面顯示使用者介面 當你的 當你的 applet applet 或應用程式執行時或應用程式執行時 , toolkit , toolkit 會把會把真正繪真正繪

出按鈕的動作交給作業系統執行出按鈕的動作交給作業系統執行在 在 Windows Windows 下下 ,, 會得到視窗樣式的按鈕會得到視窗樣式的按鈕在 在 MAC MAC 下下 , , 會得到麥金塔的按鈕會得到麥金塔的按鈕

缺點缺點 AWT AWT 使用 使用 OS OS 的的 toolkittoolkit 會造成不同作業平台上有會造成不同作業平台上有不不

相容的問題相容的問題

Page 7: Swing 井民全 製作 ching

SwingSwing

Swing Swing 不使用 不使用 OS OS 的 的 toolkittoolkit 來建立使用者介面來建立使用者介面 ,, 所有的元件都由 所有的元件都由 java java 自己提供自己提供 ,, 不管在哪一個平台上執行不管在哪一個平台上執行 ,, 按鈕都長的一樣按鈕都長的一樣如何使用 如何使用 Swing ?Swing ?

1.1. 組合預先建造好的元件組合預先建造好的元件2.2. 把它們放到把它們放到容器容器 (container)(container) 中中3.3. 利用利用版面管理員版面管理員製造更複雜的介面製造更複雜的介面

Swing Swing 利用利用版面管理員版面管理員 (layout manager)(layout manager) 來管理容器內的元件來管理容器內的元件 ,, 控控制它們的大小及位置制它們的大小及位置

相對位置相對位置取代絕對位置取代絕對位置 (( 直接用座標控制直接用座標控制 ): ): 好處是當使用者重好處是當使用者重新改變視窗大小時新改變視窗大小時 ,, 你可以確定其元件可以在正確位置上出現你可以確定其元件可以在正確位置上出現

Page 8: Swing 井民全 製作 ching

元件元件SwingSwing 元件必須放置在元件必須放置在容器容器中才可以使用中才可以使用 ,, 而容器負責將元件分類而容器負責將元件分類 ,, 讓它們可讓它們可以被以被版面管理員版面管理員顯示顯示

所有的 所有的 SwingSwing 元件都是元件都是抽象類別 抽象類別 javax.swing.JComponentjavax.swing.JComponent 繼承而來的繼承而來的 如 如 JButtonJButton 是 是 AbstractButton AbstractButton 的子類別的子類別 ,, 而 而 AbstractButtonAbstractButton 又是 又是 JCoJCo

mponentmponent 的子類別的子類別JComponent JComponent 是 是 Swing Swing 元件階層的 元件階層的 rootroot

JComponent

AWT Container 的 類別

Component 類別

我們可以說 Swing 是 AWT 的大延伸• 因為 JComponent 類別是從 Container 類別繼承而來 所以他同時具備元件與容器的特性

Page 9: Swing 井民全 製作 ching

JComponent JComponent 類別的功能分成兩類類別的功能分成兩類

控制外觀控制外觀 :: 顯形顯形 // 隱形隱形 , , 元件大小與位置元件大小與位置 , , 字型與顏色字型與顏色 當元件顯示時當元件顯示時 , JComponent , JComponent 負責負責與顯示裝置作關聯與顯示裝置作關聯 ,, 並處理繪並處理繪

圖圖

元件的行為元件的行為 : : 處理對使用者產生的處理對使用者產生的事件事件作出反應作出反應 當使用者在元件的當使用者在元件的顯示區域顯示區域作出動作作出動作 , Swing , Swing 的執行緒會送出一的執行緒會送出一

個事件來描述 個事件來描述 [[ 發生了甚麼事發生了甚麼事 ]]

[ 註冊 ] 若你被按下時 , 請通知我1 2

物件 1

物件 2

物件 1

物件 2

當使用者發出事件時 , 根據註冊列表傳送事件給聆聽者

Page 10: Swing 井民全 製作 ching

事件事件 (Event)(Event)

當使用者當使用者按下一個按鈕按下一個按鈕時時 , , 按鈕會傳送一個 按鈕會傳送一個 ActionEventActionEvent 物件給所有的註冊者物件給所有的註冊者如果要接受這事件如果要接受這事件 , , 則必須要向該按鈕則必須要向該按鈕註冊註冊 ((ActionListenerActionListener))

事件接受者事件接受者必須必須實作 實作 methodmethod 來接受按鈕傳來的事件來接受按鈕傳來的事件

特定的事件可以由不同種類元件產生特定的事件可以由不同種類元件產生 MouseEventMouseEvent --> --> 滑鼠在元件區域中的行為滑鼠在元件區域中的行為 KeyEventKeyEvent 鍵盤按鍵的行為鍵盤按鍵的行為 高階事件 高階事件 (ex: (ex: ActionEventActionEvent) ) 代表使用者介面元件完成其工作代表使用者介面元件完成其工作

物件內部的溝通上物件內部的溝通上 ,, 也可以利用事件的機制 也可以利用事件的機制 (JavaBeans)(JavaBeans)

Page 11: Swing 井民全 製作 ching

容器容器的重大責任的重大責任

負責排列它所包含的元件負責排列它所包含的元件 若一個元件若一個元件改變改變了大小或可見度了大小或可見度 , , 則必須則必須通知它的容器通知它的容器 容器則通知容器則通知版面管理器版面管理器來整理容器中的子元件來整理容器中的子元件

Swing Swing 的元件同時也是的元件同時也是容器容器 (Container)(Container) 容器可以容器可以直接排列管理直接排列管理它裡面的它裡面的 JComponentJComponent 物件物件 你不需要知道這些物件是甚麼 你不需要知道這些物件是甚麼 ? ? 有何功用 有何功用 ? ? 你可以你可以自由抽換容器自由抽換容器內的元件或內的元件或組合更複雜的使用者介面組合更複雜的使用者介面元件元件

Page 12: Swing 井民全 製作 ching

對等物對等物我們的元件必須包含我們的元件必須包含原生方法原生方法的物件溝通的物件溝通 ,, 才能與實際才能與實際的作業系統互動 的作業系統互動 (AWT(AWT 對等物介面對等物介面 ))

Ex. Ex. 要把資料顯示在螢幕上要把資料顯示在螢幕上 ,, 從輸入裝置讀取資料從輸入裝置讀取資料 , , 則必須由 則必須由 JJava ava 的世界跳到真實作業環境的世界跳到真實作業環境

AWT AWT 使用許多對等物使用許多對等物 一個元件對應一個對等物一個元件對應一個對等物 Ex. Ex. 若你建立一個視窗若你建立一個視窗 ,, 在裡面加入 在裡面加入 8 8 個按鈕個按鈕

AWT AWT 會建立 會建立 9 9 個對等物 個對等物 : (: ( 一個視窗一個視窗 ,8 ,8 個按鈕對等物個按鈕對等物 ))

Swing Swing 的元件幾乎是的元件幾乎是不對等不對等的 的 ((輕小元件輕小元件 )) Swing Swing 元件與 元件與 os os 沒有互動沒有互動 元件的元件的繪製繪製與與 UserUser 事件回應事件回應 由 由 parent container parent container 負責處理負責處理

Page 13: Swing 井民全 製作 ching

使用輕小元件的原因使用輕小元件的原因因為是元件自己因為是元件自己繪製自己的外框繪製自己的外框 , , 所以可以動態的決定如何繪製所以可以動態的決定如何繪製

Swing Swing 支援不同的 支援不同的 Look and FeelLook and Feel 我們可以動態的改變外觀 我們可以動態的改變外觀 ( ( 預設值是 預設值是 Metal)Metal)

使用對等物的方式使用對等物的方式很難改變元件的特性很難改變元件的特性 因為對等物是由因為對等物是由 OSOS 提供提供

使用作業系統原生碼,將使程式使用作業系統原生碼,將使程式移植變的困難移植變的困難

原生對等物原生對等物沒有效率沒有效率 Ex.Ex. 若使用 若使用 AWT AWT 的 的 TextField TextField 作為試算表的作為試算表的 cell,cell, 建立數百個 建立數百個 TextFieldTextField

zPeer zPeer 非常沒有效率非常沒有效率

為何不用 AWT

Page 14: Swing 井民全 製作 ching

MVC MVC 架構架構Model/View/Control Model/View/Control 架構的目的是架構的目的是建立一個可以重複使用建立一個可以重複使用元件的方法元件的方法

依照依照資料結構資料結構 ,, 顯示方式顯示方式 ,, 行為行為區分成不同的部分區分成不同的部分 主要適用於 主要適用於 GUI GUI 元件的設計上 元件的設計上 (( 但也可以應用到但也可以應用到設計設計上上 ))

MVC MVC 的基本概念的基本概念 :: 把把資料模型資料模型與與資料顯示資料顯示區隔開來區隔開來

Ex. Ex. 試算表的資料可以用長條圖或圓餅圖表示試算表的資料可以用長條圖或圓餅圖表示 ,, 其中資料其中資料 model, model, 不同的表示方式不同的表示方式 ViewView

ControlControl 則是控制元件的行為則是控制元件的行為當當資料資料改變時改變時 ,, 顯示顯示的部分亦要改變的部分亦要改變

Page 15: Swing 井民全 製作 ching

繪圖繪圖Swing Swing 元件可能在元件可能在任何時候任何時候被要求重畫外觀被要求重畫外觀

Ex: Ex: 當一個視窗將元件蓋住當一個視窗將元件蓋住 ,,之後又離開之後又離開 . . 這時 這時 swing swing 的執行緒將會要的執行緒將會要求元件重畫外觀求元件重畫外觀

Swing Swing 是藉由 是藉由 paint ( ) methodpaint ( ) method 進行重畫的動作進行重畫的動作 paint paint 可能在任何時後被呼叫可能在任何時後被呼叫 一個元件需要被重畫時一個元件需要被重畫時 ,, 改由透過 改由透過 repaint() method repaint() method 來安排呼叫 來安排呼叫 paint()paint()

有效率的繪圖有效率的繪圖 同時有太多重畫的要求或對同一個元件有許多的要求同時有太多重畫的要求或對同一個元件有許多的要求 , , 執行緒會重新安執行緒會重新安

排並排並想辦法解化成一個 想辦法解化成一個 paint paint 呼叫呼叫 repaint repaint 亦可以自訂亦可以自訂一定時間內畫面要被更新一定時間內畫面要被更新無論是 無論是 paint paint 或 或 paintComponent()paintComponent() 都有一個參數都有一個參數

Graphics Graphics 物件 物件 => => 代表元件的繪圖內容代表元件的繪圖內容 ,, 他提供了基本繪圖與圖片處理他提供了基本繪圖與圖片處理的方法的方法

Page 16: Swing 井民全 製作 ching

Swing Swing 元件自己負責它的繪圖元件自己負責它的繪圖Swing Swing 元件可以容納其他的元件元件可以容納其他的元件 ,, 故有故有必要告知他所容納必要告知他所容納的所有元件作出重畫的所有元件作出重畫

public void paint(Graphics g) { super.paint(g); // 呼叫子元件重畫 …}

一個簡單的例子 :

1. Frame 先畫自己2. content pane first paints its background, then ask its child, JPanel, to paint. 3. JPanel

a. background b. border c. children4. JButton a. background b. text c. focus5. JLabel

Page 17: Swing 井民全 製作 ching

Custom PaintingCustom Painting

Your custom painting code belongs in a method named Your custom painting code belongs in a method named paintComponentpaintComponent

class ImagePanel extends JPanel { public void paintComponent(Graphics g) { super.paintComponent(g); //paint background //Draw image at its natural size first. g.drawImage(image, 0, 0, this); //85x62 image //Now draw the image scaled. g.drawImage(image, 90, 0, 300, 62, this); }}

ImageDisplayer.java

Page 18: Swing 井民全 製作 ching

Enable Enable the componentthe component

每個標準的 每個標準的 Swing Swing 元件都有 元件都有 setEnabledsetEnabled()() 決定 決定 enable or disableenable or disable Ex: Ex: 當 當 JButton JButton 或 或 JTextField JTextField 的元件被 的元件被 disable, disable, 將不接受任何的輸入將不接受任何的輸入

反應反應

如何製作一個如何製作一個只被使用一次只被使用一次的元件的元件 當我們按下 當我們按下 JButtonJButton 時時 , , 它會產生一個 它會產生一個 ActionEventActionEvent 這個事件會傳送給聆聽者的 這個事件會傳送給聆聽者的 actionPerformedactionPerformed() () 方法 方法

聆聽者利用聆聽者利用 getSource() getSource() 方法來找到產生事件的元件方法來找到產生事件的元件

public boolean void actionPerformed(ActionEvent e) { … ((JComponent) e.getSource()).setEnabled(false);}

聆聽者聆聽者

Page 19: Swing 井民全 製作 ching

FocusFocus

元件焦點元件焦點 : : 指的是目前被選取的輸入元件指的是目前被選取的輸入元件 為了要接受鍵盤上的事件為了要接受鍵盤上的事件 , , 元件通常會有元件通常會有鍵盤焦點鍵盤焦點 我們可以用 我們可以用 JComponent JComponent 的 的 requestFocus() requestFocus() 要求取得焦點要求取得焦點

JTextField, JTextArea JTextField, JTextArea 等文字元件等文字元件 ,, 在其區域中按下滑鼠則會自動取在其區域中按下滑鼠則會自動取得焦點得焦點

若你希望某個元件得到焦點後若你希望某個元件得到焦點後 ,, 通知你則必須實做 通知你則必須實做 FocusListenerFocusListener 介面介面

Ex: Ex: 當元件被選擇後當元件被選擇後 , , 改變滑鼠的樣式改變滑鼠的樣式

當使用者按下 當使用者按下 [[tabtab], ], 焦點會轉移到下一個可用的元件焦點會轉移到下一個可用的元件上上 JComponent JComponent 提供 提供 transferFocustransferFocus(), (), setNextFocusableComponesetNextFocusableCompone

ntnt(), (), setFocusTraverablesetFocusTraverable().().

Page 20: Swing 井民全 製作 ching

Swing Swing 元件的一些 元件的一些 methodmethodContainer Container getParentgetParent()() 傳回包含該元件的傳回包含該元件的容器容器

String String getNamegetName()()

void void setNamesetName(string name)(string name) 指定一個字串作為該指定一個字串作為該元件的名稱元件的名稱 (( 該名稱會由 該名稱會由 toStringtoString() () 方法傳方法傳回回 ))

void void setVisiblesetVisible(boolean visible)(boolean visible) 決定該元件在容器中決定該元件在容器中是否可見是否可見

設定及取得設定及取得元件的前景和背景顏色元件的前景和背景顏色(( 對傳給 對傳給 paintpaint() () 和 和 paintComponentpaintComponent() () 的 的 Graphics Graphics 物件來說物件來說 ,,

前景前景 繪圖顏色 繪圖顏色 背景背景 元件區域被 元件區域被 update () update () 時填滿的顏色時填滿的顏色 ))

Color Color getForegroundgetForeground()()

void void setForegroundsetForeground(Color c)(Color c)

Color Color getBackgroundgetBackground()()

void void setBackgroundsetBackground(Color c)(Color c)

Page 21: Swing 井民全 製作 ching

取得及設定元件的大小取得及設定元件的大小 (( 版面管理員版面管理員會改變元件大小會改變元件大小 ))

Dimension Dimension getSizegetSize()()

void void setSizesetSize(int W, int H)(int W, int H)

版面管理員版面管理員會嘗試使用最佳元件尺寸設定元件會嘗試使用最佳元件尺寸設定元件

Dimension Dimension getPreferredSizegetPreferredSize()()

void void setPreferredSizesetPreferredSize(Dimension preferedsize)(Dimension preferedsize)

取得及設定取得及設定滑鼠樣式滑鼠樣式

Cursor Cursor getCursorgetCursor()()

void void setCursorsetCursor(Cursor cursor)(Cursor cursor)

Ex:Ex:

JComponent myComponent = …;JComponent myComponent = …;

Cursor crossHairs= Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)Cursor crossHairs= Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)

myComponent.setCursor(crossHairs);myComponent.setCursor(crossHairs);

Page 22: Swing 井民全 製作 ching

容器 容器 (Container)(Container)容器是一種元件用來容器是一種元件用來管理以及容納其他元件管理以及容納其他元件JComponent JComponent 繼承 繼承 Container Container 是容器是容器

最常用的三種最常用的三種容器容器 JFrame, JPanel, JAppletJFrame, JPanel, JApplet

JFrameJFrame 最上層的視窗 最上層的視窗

JPanelJPanel 用來管理 用來管理 JFrame JFrame 與 與 JPanel JPanel 中的元件中的元件

JAppletJApplet JApplet JApplet 是一個容器是一個容器 , , 可以容納其他元可以容納其他元件件

Page 23: Swing 井民全 製作 ching

每個容器都有一個每個容器都有一個列表列表 ,,紀錄所有的紀錄所有的 child child 元元件件

除了 除了 JFrame JFrame 和 和 JWindow JWindow 外外 , , 其他元件其他元件和容器都是 和容器都是 lightweightlightweight

大部分的元件要大部分的元件要加入容器加入容器並並顯示顯示出來才有出來才有作用作用

add

Page 24: Swing 井民全 製作 ching

版面管理員 版面管理員 (Layout manager)(Layout manager)

控制容器中元件的控制容器中元件的大小大小及及位置位置預設管理員預設管理員 : : 每個容器都有預設管理員每個容器都有預設管理員 可使用 可使用 setLayout() setLayout() 方法使用其他的管理員方法使用其他的管理員

元件元件 預設版面管理員預設版面管理員 描述描述JPanelJPanel FlowLayoutFlowLayout 排列元件排列元件 : : 由左到右 由上到下由左到右 由上到下

JFrameJFrame BorderLayoutBorderLayout 排列元件排列元件 : : 把元件依照把元件依照方位方位排排列在視窗中 列在視窗中 ( ( NORTH, SOUTH,NORTH, SOUTH, CENTER CENTER))

EX:EX:

myContainer.add(myComponent, myContainer.add(myComponent, BorderLayout.NORTHBorderLayout.NORTH););

Page 25: Swing 井民全 製作 ching

補充一補充一 : : 如何設定元件的 如何設定元件的 ToolTipsToolTips

jButton1.setToolTipText(“ 將資料存成 XML檔 ");UIManager.put("ToolTip.font",new Font(" 標楷體 ",Font.BOLD,20));

基本的範例程式

Page 26: Swing 井民全 製作 ching

改變 改變 Tooltips Tooltips 的字型的字型

ImageIcon MyIcon=new ImageIcon("hls_lock.gif"); // 載入按鈕圖示jButton1.setIcon(MyIcon); // 設定按鈕圖示jButton1.setFont(new java.awt.Font("Dialog", 1, 20)); // 設定按鈕字型jButton1.setToolTipText(" 這是一定要的 "); // 設定 Tooltip 要顯示的字串UIManager.put("ToolTip.font",new Font(" 標楷體 ",Font.BOLD,20)); // 設定 Tooltip 的字型

ImageIcon MyIcon=new ImageIcon("hls_lock.gif"); // 載入按鈕圖示jButton1.setIcon(MyIcon); // 設定按鈕圖示jButton1.setFont(new java.awt.Font("Dialog", 1, 20)); // 設定按鈕字型jButton1.setToolTipText(" 這是一定要的 "); // 設定 Tooltip 要顯示的字串UIManager.put("ToolTip.font",new Font(" 標楷體 ",Font.BOLD,20)); // 設定 Tooltip 的字型

井民全

完整程式範例 :CustomTooltipsDemo