第 18 章 Swing 1
本章提要 18.1 前言 18.2 Swing 介紹 18.3 視窗元件 18.3.1 JFrame 18.3.2 Content Pane 18.3.3 Menu Bar 18.4 Swing 元件 18.4.1 JCheckBox JRadioButton JComboBox 18.4.2 JTextField JPasswordField 18.4.3 JTable 18.4.4 JTree 18.5 後記 2
18.1 前言 利用 AWT 製造出來的元件都長得一模一樣例如, 按鈕就是灰色的底色, 加上黑色的文字 ;List 中的項目千篇一律都是文字顯示有沒有辦法讓這些元件變得更具特色, 或是能夠按照使用者的意思改變外觀呢? Swing 3
JDK 1.2 版 18.2 Swing 介紹 Swing 的元件, 包括 JButton JCheckBox JList JComboBox JTable JTextField JTextArea JTree JMenu Swing 的元件其實絕大部分都是繼承自 AWT 的元件而 Swing 元件不但可以改變外觀, 在功能上也較 AWT 強大許多 4
18.2 Swing 介紹 AWT 元件與 Swing 元件比較表 項目 ATW 元件 Swing 元件 套件 java.awt javax.swing 可改變元件外觀顯示 No Yes 可改變元件形狀 No Yes 可利用鍵盤操控元件 No Yes JDK 版本 1.1 以上 1.2 以上 5
javax.swing 18.2 Swing 介紹 JApplet JFileChooser JOptionPane JSeparator JWindow JButton JFormattedText Field JPanel JSlider KeyStroke JCheckBox JFrame JPasswordField JSpinner LookAndFeel JCheckBoxMenuI tem JInternalFrame JPopupMenu JTable Popup JColorChooser JLabel JProgressBar JTextArea PopupFactory JComboBox JLayeredPane JRadioButton JTextField JComponent JList JRadioButtonMenu Item JDesktopPane JMenu JRootPane JTextPane JToggleBut ton ProgressMonit or RepaintManag er ScrollPaneLay out 6
18.3.1 JFrame JFrame 繼承了 AWT 的 Frame 類別 JFrame 在設計時, 就採用更具彈性的 Pane Container 方式, 讓改變元件配置就像抽換卡片一樣簡單 7
18.3.1 JFrame 鑲板 (Pane) 用來放置元件 Pane 又因功能和作用不同而分為 1. Glass Pane 2. Layered Pane 其中 Layered Pane 包含了 1. Content Pane 2. Menu Bar 8
18.3.1 JFrame JRootPane 是一個介面 (Interface), 裡面定義了 Pane 基本該有的功能建立鑲板 : createcontentpane() createglasspane() createlayeredpane(); 取得鑲板 : getcontentpane() getglasspane() getlayeredpane(); 設定鑲板 : setcontentpane() setglasspane() setlayeredpane(); 設定選單 : setmenubar() 9
18.3.1 JFrame Layered Pane: 是用來放置各種不同 Pane( 如 Content Pane Menu Bar Pop Menu) 的置物櫃 0: Default Layer Layered Pane 的底層, 主要用來放置 Content Pane 及 Menu Bar 1: Palette Layer 覆蓋在 Default Layer 之上, 主要用來擺放工具列 (Toolbar) 調色盤 (Palette) 等 2: Model Layer 當有對話框, 如檔案選擇精靈 色彩選擇對話框等, 出現時, 即在此 Layer 做顯示 3: Popup Layer 用來放置 Popup Menu 訊息框等 4: Drag Layer 當使用者執行拖拉物件動作時, 會將物件放置到最上一層, 當完成拖拉動作時, 再將物件放回它原來的位置 10
18.3.1 JFrame 11
18.3.1 JFrame 對視窗而言,Menu 可有可無, 如果有 Menu 則 Menu Bar 會在 Content Pane 的上方 ; 若沒有 Menu 則整個視窗都是 Content Pane 12
18.3.1 JFrame Layered Pane 在顯示不同 Pane 時, 是以堆疊的方式呈現 Drag Layer 的元件會疊在 Popup Layer 上面, 而 Popup Layer 的元件會疊在 Model Layer 上面 13
18.3.1 JFrame Glass Pane 是覆蓋在鑲板上面的透明面板, 主要是讓使用者可以在上面畫圖平常是看不到的, 但需要時我們可以將它變成可以看得見的 14
JFrame 的建構元 18.3.1 JFrame 項次 1 JFrame() 2 JFrame 的建構元 JFrame(String frametitle) 建立一個標題為 frametitle 的視窗 15
18.3.1 JFrame 項次 1 2 3 4 5 JFrame 的方法 Container getcontentpane() 傳回目前視窗 Layered Pane 的 Content Pane Contain getglasspane() 傳回目前視窗的 Glass Pane JMenuBar getjmenubar() 傳回視窗所使用的 JMenu Bar setcontentpane(container contentpane) 設定視窗的 Content Pane 為 contentpane setdefaultcloseoperation(int operation) 設定當視窗關閉時該做什麼動作 Operation 的值為 : DO_NOTHING_ON_CLOSE: 不做任何事情 HIDE_ON_CLOSE: 將視窗隱藏起來, 若需要再次顯現視窗時, 只需再使用 show() 即可 DISPOSE_ON_CLOSE: 將本視窗的系統資源釋放掉, 等到所有視窗都被 Dispose 時, 則關閉應用程式 EXIT_ON_CLOSE: 關閉應用程式 16
範例程式 1 JFram 產生一個視窗 7 public class ch18_jfram_1 extends JFrame 8 { public ch18_jfram_1(string name, int X, int Y){ 9 super(name); 10 setbounds(100, 100, 200, 200); 11 settitle(name); 12 setresizable(true); 13 setvisible(true); 14 setlocation(x, Y); 15 setdefaultcloseoperation(jframe.dispose_on_close); 16 } 17 public static void main(string args[]){ 18 ch18_jfram_1 f1 = new ch18_jfram_1("frame 1", 100, 100); 19 ch18_jfram_1 f2 = new ch18_jfram_1("frame 2", 150, 150); 20 } 17
18
18.3.2 Content Pane 範例程式 2 JFram 加入 Swing 元件 5 import javax.swing.*; 6 import java.awt.*; 16 setlayout(new FlowLayout()); 17 18 JLabel l1 = new JLabel(" 這是測試 Label,JLabel.RIGHT); 19 getcontentpane().add(l1); 19
21 JButton jb1 = new JButton(" 按鈕 1"); 22 getcontentpane().add(jb1); 23 24 JLabel l2 = new JLabel(new ImageIcon("java.jpg"),JLabel.CENTER); 25 getcontentpane().add(l2); 26 27 JButton jb2 = new JButton(" 按鈕 2", new ImageIcon("man.jpg")); 28 getcontentpane().add(jb2); 29 30 JTextArea jt1 = new JTextArea("This is text area", 1, 10); 31 getcontentpane().add(jt1); 32 33 JTextArea jt2 = new JTextArea (" 這是有捲軸的 TextArea\n\n\n\n hi hi ~", 4, 10); 34 getcontentpane().add(new JScrollPane(jt2)); 35 pack(); 36 show(); 20
項次 JTextArea 的建構元 1 JTextArea() 2 JTextArea(Document d) 3 JTextArea(Document d, String text, int rows, int columns) 4 JTextArea(int rows, int columns) 5 JTextArea(String text) 6 JTextArea(String text, int rows, int columns) 項次 1 2 JScrollPane 的建構元 JScrollPane() 產生一個空白的 ScrollPane, 預設有水平和垂直捲軸 JScrollPane(Component view) 產生一個包含 view 元件的 ScrollPane, 預設有水平和垂直捲軸 21
18.3.3 Menu Bar 22
範例程式 3 JFram 加入 JMenu 9 { private JMenuBar menbar; 17 JTextArea tx1 = new JTextArea(); 18 getcontentpane().add(tx1, BorderLayout.CENTER); 19 JButton jb = new JButton(" 按鈕 "); 20 getcontentpane().add(jb, BorderLayout.SOUTH); 21 createmenu(); 22 setjmenubar(menbar); 23 setvisible(true); 24 show(); 23
29 public void createmenu() 30 { 31 menbar = new JMenuBar(); 32 JMenu m_file = new JMenu(" 檔案相關 "); 33 JMenuItem mi1 = new JMenuItem(" 新開檔案 "); 34 JMenuItem mi2 = new JMenuItem(" 關閉檔案 "); 35 m_file.add(mi1); 36 m_file.add(mi2); 37 m_file.add(" 儲存檔案 "); 39 JMenu m_window = new JMenu(" 視窗 "); 40 JMenu m_window_copy = new JMenu(" 視窗相關 "); 42 JMenuItem m_past = new JMenuItem(" 複製視窗 ", new ImageIcon("copy.jpg")); 43 m_past.setaccelerator(keystroke.getkeystroke('p', java.awt.event.inputevent.ctrl_mask)); 44 m_window_copy.add(m_past); 24
46 m_window_copy.add(new JMenuItem(" 貼上視窗 ", new ImageIcon("past.jpg"))); 47 m_window_copy.addseparator() ; 48 m_window_copy.add(new JMenuItem(" 水平排列 ")); 49 m_window_copy.add(new JMenuItem(" 垂直並排 ")); 51 JMenuItem mihelp = new JMenuItem(" 求助 ", new ImageIcon("help.jpg")); 52 mihelp.setaccelerator(keystroke.getkeystroke('h', java.awt.event.inputevent.shift_mask)); 53 m_window_copy.add(mihelp); 55 m_window_copy.insert(new JMenuItem(" 上一個視窗 ", new ImageIcon("last.jpg")), 3); 56 JMenuItem mioverlap = m_window_copy.getitem(0); 57 mioverlap.setenabled(false); 59 m_window.add(m_window_copy); 60 menbar.add(m_file); 61 menbar.add(m_window); 25
18.4.1 JCheckBox JRadioButton JComboBox 26
18.4.1 JCheckBox JRadioButton JComboBox 有三個框線, 分別放置 興趣 性別 和 地址 欄位利用 JPanel 製作 Pane Java 提供了不同的 Pane 可以用來放置 Swing 元件, 而 JPanel 就是其中的一個 27
範例程式 4 選擇性欄位的 Swing 元件 5 import javax.swing.*; 6 import javax.swing.border.*; 7 import java.awt.*; 13 getcontentpane().setlayout(new GridLayout(3, 1)); 14 setdefaultcloseoperation(jframe.dispose_on_close); 16 JPanel jp1 = new JPanel(); 17 JPanel jp2 = new JPanel(); 18 JPanel jp3 = new JPanel(new FlowLayout()); 20 jp1.setborder(new TitledBorder(" 興趣 ")); 21 jp1.setlayout(new GridLayout(1, 4)); 22 JCheckBox jcb1 = new JCheckBox(" 運動 "); 23 jp1.add(jcb1); 24 jp1.add(new JCheckBox(" 閱讀 ")); 25 jp1.add(new JCheckBox(" 旅遊 ")); 26 jp1.add(new JCheckBox(" 購物 ", true)); 28
28 jp2.setborder(new LineBorder(new Color(104,127,43), 4)); 29 jp2.setlayout(new GridLayout(1, 3)); 30 31 JRadioButton jrwoman = new JRadioButton(" 女生 "); 32 JRadioButton jrman = new JRadioButton(" 男生 ", true); 33 ButtonGroup bg = new ButtonGroup(); 34 bg.add(jrwoman); 35 bg.add(jrman); 40 jp3.setborder(new MatteBorder(5, 5, 5, 5, new ImageIcon("d112.jpg"))); 41 String [] data = {" 台北 ", " 高雄 ", " 台中 ", " 花蓮 ", " 南投 ", " 嘉義 "}; 42 JComboBox j1 = new JComboBox(data); 43 j1.additem(" 雲林 "); 44 j1.additem(" 彰化 "); 47 jp3.setbackground(color.white); 48 getcontentpane().add(jp1); 49 getcontentpane().add(jp2); 50 getcontentpane().add(jp3); 29
項次 18.4.1 JCheckBox JRadioButton JComboBox JPanel 是一個類別, 其定義如下 : public class JPanel extends JComponent implements Accessible 1 JPanel ) 2 JPanel 的建構元 JPanel LayoutManager layout) 設定 JPanel 的版面管理員為 layout 30
項次 1 JCheckBox() 18.4.1 JCheckBox JRadioButton JComboBox JCheckBox 的建構元 JCheckBox(Icon icon, boolean selected) 產生一個圖示為 icon 的 JCheckBox, 當 selected 為 true 時, 表 2 示 JCheckBox 的狀態是被選擇的狀態, 若為 false, 則表示沒有被選擇 3 JCheckBox(String text, boolean selected) JCheckBox(String text) 4 JCheckBox 顯示文字為 text JCheckBox(String text, Icon icon) 5 可同時顯示 icon 及文字 6 JCheckBox(String text, Icon icon, boolean selected) 31
項次 18.4.1 JCheckBox JRadioButton JComboBox 1 JRadioButton () 2 3 JRadioButton 的建構元 JRadioButton (Icon icon, boolean selected) 產生一個圖示為 icon 的 JRadioButton, 當 selected 為 true 時, 表示 JRadioButton 的狀態是被選擇的狀態, 若為 false, 則表示沒有被選擇 JRadioButton (String text) JRadioButton 顯示文字為 text 4 5 6 JRadioButton (String text, boolean selected) JRadioButton (String text, Icon icon) 可同時顯示 icon 及文字 JRadioButton (String text, Icon icon, boolean selected) 32
18.4.2 JTextField JPasswordField 33
範例程式 5 JTextField 及 JPasswordField 10 { private JTextArea jta; 11 private JTextField jtf1; 12 private JPasswordField jpwf1, jpwf2; 22 jtf1 = new JTextField("", 20); 23 jp1.add(jtf1); 25 jp1.add(new JLabel(" 帳號 :")); 26 jp1.add(new JTextField("", 20)); 28 jp1.add(new JLabel(" 密碼 :")); 29 jpwf1 = new JPasswordField(" 這是密碼 ", 18); 30 jp1.add(jpwf1); 32 jp1.add(new JLabel(" 機密資訊 ")); 33 jpwf2 = new JPasswordField("1234567", 15); 34 jpwf2.setechochar('@'); 35 jp1.add(jpwf2); 34
42 confirmbutton.addmouselistener(new MouseAdapter (){ 43 public void mouseclicked(mouseevent e) { 44 String s=jtf1.gettext()+" 你的密碼是 :"; 45 char [] pass = jpwf1.getpassword(); 46 for (int i =0; i < pass.length; i++) 47 s += pass[i]; 48 s += " \n 給你的機密是 :"; 49 char [] pass2 = jpwf2.getpassword(); 50 for (int i =0; i < pass2.length; i++) 51 s += pass2[i]; 52 jta.settext(s); 53 } 54 public void mouseentered(mouseevent e) { 55 jta.append("\n 按下按鈕會清除以上的資訊..."); 56 } 57 }); 35
項次 1 JTextField() 2 JTextField 的建構元 JTextField(Document doc, String text, int columns) 設定 JTextField 的顯示模式為 doc, 初始值為 text, 並指定 JTextField 欄位大小為 columns 3 JTextField(int columns) 4 JTextField(String text) 5 JTextField(String text, int columns) 項次 JPasswordField 的建構元 1 JPasswordField () JPasswordField (Document doc, String text, int columns) 2 設定 JPasswordField 的顯示模式為 doc, 初始值為 text, 並指定 JPasswordField 欄位大小為 columns 3 JPasswordField (int columns) 4 JPasswordField (String text) 5 JPasswordField (String text, int columns) 36
18.4.3 JTable 37
範例程式 6 JTable 範例 14 String[] columnnames = {" 編號 ", " 商品名稱 ", " 價格 ", " 促銷品 "}; 15 Object [][] product = { 16 {"A0001", " 牙刷 ", new Integer(55), new Boolean(true)}, 17 {"B0003", " 洗髮精 ", new Integer(375), new Boolean(true)}, 18 {"A1258", " 可樂 ", new Integer(25), new Boolean(false)}, 19 {"B1534", " 抹布 ", new Integer(80), new Boolean(false)}, 20 {"B5582", " 電池 ", new Integer(60), new Boolean(false)}, 21 {"B1752", " 鉛筆 ", new Integer(12), new Boolean(true)} 22 }; 23 24 JTable table = new JTable(product, columnnames); 25 getcontentpane().add(new JScrollPane(table)); 38
項次 1 JTable() 2 3 4 JTable 的建構元 JTable(int numrows, int numcolumns) 建立一個有 numrows 行,numColumns 欄的 JTable JTable(Object[][] rowdata, Object[] columnnames) 建立一個初始值為 rowdata 的 JTable,columnNames 為欄位名稱 JTable(TableModel dm) 設定 JTable 的編排規則為 dm 39
範例程式 7 JTable 範例, 欄位顯示不同 6 import javax.swing.table.*; 23 JTable table = new JTable(new DefaultTableModel(product, columnnames)) 24 { 25 public Class getcolumnclass(int column) 26 { 27 return getvalueat(0, column).getclass(); 28 } 29 }; 30 TableColumn productcolumn = table.getcolumnmodel().getcolumn(1); 31 JComboBox jcb = new JComboBox(); 32 jcb.additem(" 牙刷 "); 33 jcb.additem(" 洗髮精 "); 38 productcolumn.setcelleditor(new DefaultCellEditor(jcb)); 39 getcontentpane().add(new JScrollPane(table)); 40
18.4.3 JTable 41
樹節點 (TreeNode) 根節節 (TreeRoot) 18.4.4 JTree 42
範例程式 8 JTree 範例 6 import javax.swing.tree.*; 13 DefaultMutableTreeNode treeroot = new DefaultMutableTreeNode(); 14 createtree(treeroot); 15 JTree t = new JTree(treeRoot); 16 t.setshowsroothandles(true); 17 t.seteditable(true); 18 getcontentpane().add(new JScrollPane(t)); 43
24 public void createtree(defaultmutabletreenode treeroot) 25 { DefaultMutableTreeNode tn1 = new DefaultMutableTreeNode( " 公司檔案 "); 26 tn1.add(new DefaultMutableTreeNode(" 台積電 ")); 27 tn1.add(new DefaultMutableTreeNode("IBM")); 28 tn1.add(new DefaultMutableTreeNode("ACER")); 30 DefaultMutableTreeNode tn2 = new DefaultMutableTreeNode( " 主管資料 "); 31 DefaultMutableTreeNode tn2_1 = new DefaultMutableTreeNode( " 董事長 "); 33 tn2_1.add(new DefaultMutableTreeNode("Chang")); 34 tn2_2.add(new DefaultMutableTreeNode("Wang")); 37 tn2.add(tn2_1); 38 tn2.add(tn2_2); 40 MutableTreeNode tn3 = new DefaultMutableTreeNode(" 部門資訊 "); 42 treeroot.add(tn1); 43 treeroot.add(tn2); 44 treeroot.add(tn3); 45 } 44
18.5 後記 Swing 元件 JFrame JButton JCheckBox JList JComboBox JTable JTextField JTextArea JTree JMenu Swing 元件是由 AWT 演進而來在使用上 Swing 元件與 AWT 元件可以搭配使用在 AWT 單位介紹的 Event 在 Swing 上面也可以使用, 讓 Swing 元件構成的視窗也能夠與使用者互動 45