Java2 JDK5.0 教學手冊第三版洪維恩編著博碩文化出版書號 pg20210 第二十三章認識 Swing 本章學習目標 Swing 概述認識 JFrame 類別學習 Swing 的基本物件學習 Swing 物件之間的互動
認識 Swing 23-2 23.1 Swing 概述 Swing 提供了豐富的物件 更美觀的圖形介面, 以及更高的執行效率 幾乎每一個 AWT 物件都有一個相對應的 Swing 介面取代它 Swing 還提供了 AWT 所沒有的物件, 如進度列 (process bar) 內部視窗 (internal frame) 等等
下圖是 Swing 執行的範例畫面 : 認識 Swing 23-3
認識 Swing 23-4 下圖繪出了本章所要介紹 Swing 物件的繼承關係圖 : java.lang.object java.awt.component javax.swing.buttongroup java.awt.container java.awt.window java.awt.dialog javax.swing.jdialog javax.swing.jcomponent java.awt.frame javax.swing.jframe javax.swing.jlabel java.swing.jwindow javax.swing.jlist javax.swing.jscrollpane javax.swing.jcolorchooser A
認識 Swing 23-5 A javax.swing.jlayeredpane javax.swing.jdesktoppane javax.swing.jinternalframe javax.swing.abstractbutton javax.swing.jbutton javax.swing.jtogglebutton javax.swing.jcheckbox javax.swing.jradiobutton
認識 Swing 23-6 23.2 Swing 的 JFrame 視窗 Swing 的視窗包含了好幾個層級 (layer), 其中以 content pane 這個層級較為常用 : JFrame MenuBar Button Top lever container ( 最頂層的視窗容器 ) Content pane, 譯為內容層, 此層扮演視窗容器的角色, 可用來盛裝視窗物件, 如按鈕 標籤等 視窗物件可放置在 Content pane 內
認識 Swing 23-7 下表列出了 JFrame 類別的建構元與常用的 method: 表 23.2.1 JFrame 的建構元與常用的 method 建構元 JFrame() JFrame(String title) 主要功能 建立 JFrame 視窗物件 建立 JFrame 視窗物件, 視窗標題為 title method Container getcontentpane() void setlayout(layoutmanager manager) void update(graphics g) 主要功能取得 content pane 設定版面配置為 manager 跳過清除背景的步驟, 直接呼叫 paint()
認識 Swing 23-8 JFrame 視窗的練習 下面的範例是 JFrame 視窗類別的練習 : 01 // app23_1,jframe 類別的練習 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; // 載入 javax.swing 類別庫裡的所有類別 05 06 public class app23_1 extends JFrame implements ActionListener 07 { 08 static app23_1 frm=new app23_1(); 09 static Button btn=new Button("Click Me"); 10 static Container cp=frm.getcontentpane(); // 取得視窗容器 11 12 public static void main(string args[]) 13 { 14 cp.add(btn); // 將按鈕 btn 加入內容層中 15 cp.setlayout(new FlowLayout()); // 設定內容層的版面配置 16 cp.setbackground(color.pink); // 設定內容層的顏色 17 btn.addactionlistener(frm); 18 frm.settitle("jframe 視窗 "); 19 frm.setsize(200,150); 20 frm.setvisible(true);
21 } 22 // 按下 btn 按鈕的事件處理 23 public void actionperformed(actionevent e) 24 { 25 if(cp.getbackground()==color.pink) 26 cp.setbackground(color.yellow); 27 else 28 cp.setbackground(color.pink); 29 } 30 } 認識 Swing 23-9
認識 Swing 23-10 JInternalFrame 視窗的練習 Swing 子視窗的建立是用 JInternalFrame 類別來達成 下表列出了 JInternalFrame 類別常用的建構元與 method: 表 23.2.2 建構元 JInternalFrame() JInternalFrame(String title) JInternalFrame 類別的建構元與 method JInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable) 主要功能 建立一個子視窗物件 建立一個子視窗物件, 視窗標題為 title 建立一個子視窗物件, 視窗標題為 title, 並且可設定大小是否可調整 是否可關閉 是否可最大化, 以及是否可縮小成一個圖示
認識 Swing 23-11 method void dispose() Container getcontentpane() String gettitle() String settitle(string title) void show() 主要功能將子視窗關閉, 並釋放資源取得子視窗的內容層取得子視窗的標題設定子視窗的標題顯示子視窗 下面的範例是 JInternalFrame 類別的練習
認識 Swing 23-12 接下來是本範例的程式碼 : 01 // app23_2,jinternalframe 類別的練習 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 06 public class app23_2 07 { 08 static JFrame frm=new JFrame("JInternalFrame"); 09 static JButton btn=new JButton("New Frame");// 建立 JButton 物件 10 11 static Container cp=frm.getcontentpane(); // 取得內容層 12 static JDesktopPane jdp=new JDesktopPane(); // 建立桌面層物件 13 14 public static void main(string args[]) 15 { 16 cp.setlayout(new BorderLayout()); 17 cp.add(btn,borderlayout.south); 18 cp.add(jdp); // 將桌面層加到內容層中 19 20 btn.addactionlistener(new ActLis()); 21 frm.setsize(400,300); 22 frm.setvisible(true);
認識 Swing 23-13 23 } 24 25 static class ActLis implements ActionListener 26 { 27 static int count=1; // 宣告 count 變數, 用來記錄子視窗的總數 28 public void actionperformed(actionevent e) 29 { 30 JInternalFrame jif; // 建立子視窗物件 jif 31 jif=new JInternalFrame("Frame "+(count++),true,true,true,true); 32 Container icp=jif.getcontentpane(); // 取得 jif 的內容層 33 JButton ibtn=new JButton("JInternalFrame Button"); 34 icp.add(ibtn,borderlayout.south); // 將 ibtn 按鈕加入 icp 中 35 jdp.add(jif); // 將子視窗物件 jif 加到桌面層中 36 jif.setsize(200,150); 37 jif.setvisible(true); 38 } 39 } 40 }
認識 Swing 23-14 參考下圖, 就可以了解到物件與圖層的關係 : JFrame (frm 物件 ) ContentPane ( 內容層,cp 物件 ) JDesktopPane ( 桌面層,jpd 物件 ) JInternalFrame ( 子視窗,jif 物件 ) ContentPane ( 子視窗的內容層,icp 物件 ) ibtn 物件 btn 物件
認識 Swing 23-15 23.3 按鈕與標籤 按鈕與標籤可以加上圖片影像, 使得外型更為美觀 也可以設定按鈕被按下, 或者是滑鼠指標停在按鈕上時所顯示的影像圖形 (image icon) ImageIcon 類別 要把影像加到按鈕 ( 或標籤 ) 中, 可利用 ImageIcon() 建構元讀入圖檔
認識 Swing 23-16 23.3.1 使用 JButton 按鈕 Swing 按鈕常用的 method, 多半是定義在 JButton 的父類別 AbstractButton 中 下表列出 JButton 建構元, 以及使用 JButton 類別時常用到的 method: 表 23.3.1 JButton 的建構元 建構元 JButton() JButton(Icon icon) JButton(String text) JButton(String text, Icon icon) 主要功能建立 JButton 物件建立 JButton 物件, 並使用 icon 為圖示建立 JButton 物件, 標題為 text 建立 JButton 物件, 標題為 text, 圖示為 icon
認識 Swing 23-17 表 23.3.2 JButton 常用的 method( 這些 method 定義在 JButton 的父類別 AbstractButton 中 ) method Icon geticon() void seticon(icon icon) Icon getpressedicon() void setpressedicon(icon icon) Icon getrollovericon() void setrollovericon(icon icon) String gettext() void settext(string str) void sethorizontaltextposition(int pos) void setverticaltextposition(int pos) void setenabled(boolean b) 主要功能 傳回按鈕的圖示 設定按鈕的圖示為 icon 傳回按鈕被按下時的圖示 設定按鈕被按下時的圖示為 icon 傳回滑鼠從上面經過時, 按鈕的圖示 設定滑鼠從上面經過時, 按鈕的圖示為 icon 傳回按鈕的標題 設定按鈕的標題為 str 設定按鈕的標題在圖示的左邊或右邊,pos 的值可為 JButton.LEFT 或 JButton.RIGHT 設定按鈕標題的垂直位置,pos 的值可為 JButton.TOP JButton.CENTER 或 JButton.RIGHT 設定按鈕是否可用
認識 Swing 23-18 app23_3 是 JButton 使用的範例 滑鼠沒有停在按鈕上 滑鼠停在按鈕上 按下滑鼠按鈕時
認識 Swing 23-19 app23_3 程式碼的撰寫如下 : 01 // app23_3,jbutton 影像圖示的變化 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 06 public class app23_3 07 { 08 static JFrame frm=new JFrame("JButton 測試 "); 09 static Container cp=frm.getcontentpane(); 10 static ImageIcon general=new ImageIcon("c:\\Java\\img1.gif"); 11 static ImageIcon rollover=new ImageIcon("c:\\Java\\img2.gif"); 12 static ImageIcon pressed=new ImageIcon("c:\\Java\\img3.gif"); 13 static JButton btn=new JButton("JButton"); // 建立 JButton 物件 14 15 public static void main(string args[]) 16 { 17 cp.setlayout(new FlowLayout()); 18 cp.add(btn); // 將按鈕加入內容層中 19 20 btn.setrolloverenabled(true);// 設定滑鼠指標與按鈕有互動效果 21 btn.seticon(general); // 設定在一般情況下, 按鈕的圖示 22 btn.setrollovericon(rollover); // 設定指標在按鈕上方時的圖示
認識 Swing 23-20 23 btn.setpressedicon(pressed); // 設定滑鼠按鍵按下時的圖示 24 25 frm.setsize(200,120); 26 frm.setvisible(true); 27 } 28 }
認識 Swing 23-21 23.3.2 使用 JLabel 標籤 JLabel 可在標籤內加入影像 下表列出了 JLabel 常用的建構元與 method: 表 23.3.3 JLabel 的建構元 建構元 JLabel() JLabel(Icon icon) JLabel(String text) JLabel(String text, Icon icon, int align) 主要功能 建立 JLabel 物件 建立 JLabel 物件, 並使用 icon 為圖示 建立 JLabel 物件, 標題為 text 建立 JLabel 物件, 標題為 text, 圖示為 icon, 水平的對齊方式為 align( 可為 CENTER LEFT 或 RIGHT)
認識 Swing 23-22 表 23.3.4 method Icon geticon() void seticon(icon icon) Icon getdisabledicon() JLabel 的 method void setdisabledicon(icon icon) int geticontextgap() void seticontextgap(int gap) void sethorizontaltextposition(int pos) 主要功能 傳回標籤的圖示 設定標籤的圖示為 icon 傳回標籤無作用時的圖示 設定標籤無作用時的圖示為 icon 取得標籤和文字間的距離 設定標籤和文字間的距離為 gap 設定標籤的名稱在圖示的左邊或右邊,pos 可為 JLabel.LEFT 或 JLabel.RIGHT void setverticaltextposition(int pos) 設定標籤名稱的垂直位置,pos 可為 JLabel.TOP JLabel.CENTER 或 JLabel.RIGHT String gettext() String settext(string str) 傳回標籤的名稱 設定標籤的名稱為 str
認識 Swing 23-23 下面的範例說明了 JLabel 類別的使用 01 // app23_4, JButton 與 JLabel 的綜合應用 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 06 public class app23_4 07 { 08 static JFrame frm=new JFrame("JButton & JLabel"); 09 static Container cp=frm.getcontentpane();
認識 Swing 23-24 10 11 static ImageIcon pic[]=new ImageIcon[4]; // 建立 ImageIcon 陣列 12 13 static ImageIcon left=new ImageIcon("c:\\Java\\left.gif"); 14 static ImageIcon right=new ImageIcon("c:\\Java\\right.gif"); 15 16 static JButton btn1=new JButton(" 前一張 ",left); 17 static JButton btn2=new JButton(" 後一張 ",right); 18 static JLabel lab=new JLabel(); 19 20 static int index=0; // index 變數, 用來記錄哪一張影像正被顯示 21 22 public static void main(string args[]) 23 { 24 pic[0]=new ImageIcon("c:\\Java\\pic0.jpg"); // 載入影像 25 pic[1]=new ImageIcon("c:\\Java\\pic1.jpg"); 26 pic[2]=new ImageIcon("c:\\Java\\pic2.jpg"); 27 pic[3]=new ImageIcon("c:\\Java\\pic3.jpg"); 28 29 cp.setlayout(new FlowLayout()); 30 btn2.sethorizontaltextposition(jbutton.left); 31 cp.add(btn1); 32 cp.add(btn2); 33 cp.add(lab); 34 lab.seticon(pic[0]); 35 lab.settext("pic0.jpg"); 36 lab.sethorizontaltextposition(jlabel.center);
認識 Swing 23-25 37 lab.setverticaltextposition(jlabel.bottom); 38 39 btn1.addactionlistener(new ActLis()); 40 btn2.addactionlistener(new ActLis()); 41 42 frm.setsize(400,350); 43 frm.setvisible(true); 44 } 45 46 static class ActLis implements ActionListener 47 { 48 public void actionperformed(actionevent e) 49 { 50 JButton btn=(jbutton) e.getsource(); // 取得被按下的按鈕 51 int num=pic.length; 52 53 if(btn==btn1 && index>0) 54 index--; 55 if(btn==btn2 && index<num-1) 56 index++; 57 58 lab.settext("pic"+ index%num +".jpg"); // 設定標題名稱 59 lab.seticon(pic[index%num]); 60 } 61 } 62 }
認識 Swing 23-26 23.4 核取方塊 Swing 是以 JCheckBox 與 JOptionButton 類別來做核取方塊的動作 JCheckBox 類別 ( 核取方塊 ) 下表列出了 JCheckBox 類別常用的建構元 : 表 23.4.1 javax.swing.jcheckbox 的建構元與 method 建構元 JCheckBox() JCheckBox(String label) JCheckBox(Icon icon) JCheckBox(String label, boolean state) 主要功能 建立核取方塊 建立標題為 label 的核取方塊 建立圖示為 icon 的核取方塊 建立標題為 label 的核取方塊, 並設定 state 狀態, 若 state 為 true, 則核取方塊呈被選取狀態
認識 Swing 23-27 JRadioButton 類別 ( 選項方塊 ) JCheckBox 使用的是方形的選擇圖形 JRadioButton 則是使用圓形的選擇圖形 JRadioButton 物件 JChecBox 物件
認識 Swing 23-28 下表列出了 JRadioButton 類別常用的建構元 : 表 23.4.2 javax.swing.jradiobutton 的建構元 建構元 JRadioButton() JRadioButton (String label) JRadioButton (Icon icon) 主要功能 建立選項方塊 建立標籤為 label 的選項方塊 建立圖示為 icon 的選項方塊 JRadioButton (String label, boolean st) 建立標籤為 label 的選項方塊, 並設定 st 狀態, 若 st 為 true, 則選項方塊呈被選取狀態
認識 Swing 23-29 下面的範例說明了 JCheckBox 與 JRadioButton 的應用 : 01 // app23_5, 核取方塊與選項方塊的應用 02 import java.awt.*; 03 import javax.swing.*; 04 05 class app23_5 extends Frame 06 { 07 static JFrame frm=new JFrame("Checkbox class"); 08 09 static JRadioButton rb1=new JRadioButton(" 黑白 "); 10 static JRadioButton rb2=new JRadioButton(" 彩色 "); 11 12 static JCheckBox ckb1=new JCheckBox("Epson 5900L",true); 13 static JCheckBox ckb2=new JCheckBox("HP LaserJet 4p",true); 14 static JCheckBox ckb3=new JCheckBox("Other printer"); 15 16 public static void main(string args[]) 17 { 18 rb1.setbounds(20,40,60,20); 19 rb2.setbounds(100,40,60,20); 20 ckb1.setbounds(20,80,140,20); 21 ckb2.setbounds(20,100,140,20); 22 ckb3.setbounds(20,120,140,20);
認識 Swing 23-30 23 24 ButtonGroup bgroup=new ButtonGroup(); // 建立 ButtonGroup 物件 25 bgroup.add(rb1); // 將 rb1 設定為單選 26 bgroup.add(rb2); // 將 rb2 設定為單選 27 rb1.setselected(true); // 設定 rb1 被選擇 28 29 frm.add(rb1); 30 frm.add(rb2); 31 frm.add(ckb1); 32 frm.add(ckb2); 33 frm.add(ckb3); 34 frm.setsize(200,160); 35 frm.setlayout(null); 36 frm.setvisible(true); 37 } 38 }
認識 Swing 23-31 23.5 建立 JList 選單物件 JList 直接繼承自 JComponent 類別 下表列出了 JList 常用的建構元與 method: 表 23.5.1 javax.swing.jllist 的建構元 建構元 JList() JList (Object listdata[]) JList(Vector listdata) 主要功能建立一個 JList 物件利用 Object 陣列建立 JList 物件利用 Vector 類別的物件來建立 JList 物件 method 主要功能 void addlistselectionlistener( ListSelectionListener listener) void clearselection() 設定 JList 物件的傾聽者 取消所選取的項目 Color getselectionforeground() 取得被選取選項的前景顏色 ( 即文字的顏色 ) void setselectionforeground() 設定被選取選項的前景顏色 ( 即文字的顏色 ) Color getselectionbackground() 取得被選取選項的背景顏色
認識 Swing 23-32 method void setselectionbackground() int locationtoindex(point location) void setlistdata(object[] listdata) void setlistdata(vector listdata) void setselectedindex(int index) int getselectedindex() Object getselectedvalue() 主要功能 設定被選取選項的背景顏色 將 JList 物件上的任一點位置 location 轉換成 JList 選項的索引值 以 Object 陣列設定 JList 物件的選單 以 Array 類別的物件設定 JList 物件內的選項 設定在索引值為 index 的選項被選取 取得被選取選項的索引值 取得被選取選項的值
認識 Swing 23-33 下面的範例配置了一個 JList 物件與一個 JButton 按鈕 : (1) 按下顏色按鈕, 可以取得顏色選單 (2) 選擇選單內的選項, 即可將 JList 物件的底色改為選項所指定的顏色 01 // app23_6, JList 的練習 ( 一 ) 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 import javax.swing.event.*; 06 07 public class app23_6 08 {
認識 Swing 23-34 09 static JFrame frm=new JFrame("JList demo"); 10 static Container cp=frm.getcontentpane(); 11 static JButton btn=new JButton("Get Colors"); 12 static JList lst=new JList(); // 建立 JList 物件 13 14 public static void main(string args[]) 15 { 16 cp.setlayout(new BorderLayout()); 17 cp.add(btn,borderlayout.south); 18 cp.add(new JScrollPane(lst)); // 將 lst 加入 JScrollPane 中 19 btn.addactionlistener(new ActLis()); // 設定 btn 的傾聽者 20 lst.addlistselectionlistener(new LSLis()); // 設定 lst 的傾聽者 21 frm.setsize(200,155); 22 frm.setvisible(); 23 } 24 static class ActLis implements ActionListener 25 { 26 public void actionperformed(actionevent e) 27 { 28 String s[]={"red","green","blue","pink","yellow","cyan","gray"}; 29 lst.setlistdata(s);// 將陣列 s 的內容加入 lst 中, 做為 lst 的選項 30 } 31 } 32 static class LSLis implements ListSelectionListener
認識 Swing 23-35 33 { 34 public void valuechanged(listselectionevent e) 35 { 36 int color=lst.getselectedindex(); // 取得被選取選項的索引值 37 switch(color) 38 { 39 case 0: lst.setbackground(color.red); break; 40 case 1: lst.setbackground(color.green); break; 41 case 2: lst.setbackground(color.blue); break; 42 case 3: lst.setbackground(color.pink); break; 43 case 4: lst.setbackground(color.yellow); break; 44 case 5: lst.setbackground(color.cyan); break; 45 case 6: lst.setbackground(color.gray); break; 46 } 47 } 48 } 49 }
認識 Swing 23-36 連按兩下選項的事件處理 下面是在 JList 物件中, 連按兩下滑鼠左鍵的事件處理 此範例的執行結果與程式碼如下所示 : (1) 程式執行時最初的狀態 (2) 連按兩下選擇選單內的選項, 即可將選項送到右邊的 JList 物件中
認識 Swing 23-37 01 // app23_7, JList 的練習 ( 二 ) 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 import java.util.vector; // 載入 util 類別庫裡的 Vector 類別 06 07 public class app23_7 08 { 09 static JFrame frm=new JFrame("JList demo"); 10 static Container cp=frm.getcontentpane(); 11 static JList lst1=new JList(); // 建立 lst1 物件 12 static JList lst2=new JList(); // 建立 lst2 物件 13 static String s[]={"red","green","blue","pink","yellow","cyan","gray"}; 14 static Vector v=new Vector(); // 建立 Vector 類別的物件 v 15 16 public static void main(string args[]) 17 { 18 cp.setlayout(new GridLayout(1,2)); 19 cp.add(new JScrollPane(lst1)); // 將 JScrollPane 加入 cp 中 20 cp.add(new JScrollPane(lst2)); // 將 JScrollPane 加入 cp 中 21 lst1.setlistdata(s); // 設定 lst1 物件的選單 22 lst1.addmouselistener(new MouseLis()); // 設定 lst1 物件的傾聽 者
認識 Swing 23-38 23 frm.setsize(200,155); 24 frm.setvisible(); 25 } 26 static class MouseLis extends MouseAdapter 27 { 28 public void mouseclicked(mouseevent e) 29 { 30 if(e.getsource()==lst1) // 如果是 lst1 物件被按下 31 if(e.getclickcount()==2) // 如果連續被按了兩下 32 { 33 int index=lst1.getselectedindex(); 34 String str=s[index]; 35 v.add(str); // 將字串 str 加入向量 v 中 36 lst2.setlistdata(v); // 設定向量 v 為 lst2 物件的選單 37 } 38 } 39 } 40 }
認識 Swing 23-39 23.6 顏色選擇方塊 下表列出了 JColorChooser 類別常用的建構元與 method: 表 23.6.1 javax.swing.jcolorchooser 的建構元與 method 建構元 主要功能 JColorChooser() 建立 JColorChooser 物件, 預設顏色為白色 JColorChooser(Color icolor) 建立 JColorChooser 物件, 預設顏色為 icolor method Color getcolor() void setcolor(color color) void setcolor(int r, int g, int b) Color showdialog(component c, String title, Color icolor) 主要功能 取得顏色選擇對話方塊中所選取的顏色 設定顏色選擇對話方塊中的顏色 以 r,g,b 三個顏色設定對話方塊中的顏色 顯示顏色選擇對話方塊, 其父類別的物件為 c, 標題為 title, 預設顏色為 icolor
認識 Swing 23-40 下面是一個使用 JColorChooser 類別來設定視窗顏色的範例 : 顏色選擇對話方塊
認識 Swing 23-41 01 // app23_8, JColorChooser 示範練習 02 import java.awt.*; 03 import java.awt.event.*; 04 import javax.swing.*; 05 06 public class app23_8 07 { 08 static JFrame frm=new JFrame("JColorChooser"); 09 static Container cp=frm.getcontentpane(); 10 static JButton btn=new JButton("Get Color"); 11 static JColorChooser JCC=new JColorChooser(); // 建立 JCC 物件 12 static Color color; // 宣告 Color 型態的變數 color 13 14 public static void main(string args[]) 15 { 16 cp.setlayout(new BorderLayout()); 17 cp.add(btn,borderlayout.south); 18 btn.addactionlistener(new ActLis()); 19 cp.setbackground(color.yellow); 20 frm.setsize(200,150); 21 frm.setvisible(true); 22 } 23 static class ActLis implements ActionListener 24 {
認識 Swing 23-42 25 public void actionperformed(actionevent e) 26 { 27 color=jcc.showdialog(frm,"jcolorchooser",color.pink); 28 cp.setbackground(color); // 將視窗背景設為 color 29 } 30 } 31 } 顏色選擇對話方塊有三個頁籤可供選擇, 分別為調色板 HSB 與 RGB
HSB 與 RGB 頁籤的內容可參考下圖 : 認識 Swing 23-43
認識 Swing 23-44