Download presentation
Presentation is loading. Please wait.
1
視窗程式設計 2. 視窗版面配置 Chih Hung Wang Reference:
1. Java 2 視窗程式設計,文魁出版社,位元文化編著 (2008) (教科書) 2. 深入研究Java Swing (第二版),上奇資訊股份有限公司,黃嘉輝著 (2013) 3. Java SE 6.0視窗程式設計之道,碁峰出版社,黃嘉輝著 (2008) 4. Java 初學指引,博碩文化,陳錦輝著 (2010) 視窗程式設計 2. 視窗版面配置 Chih Hung Wang
2
處理視窗程式畫面的佈局管理員 Java將視窗程式畫面視為一個容器,容器內可以包含元件,以及子容器。依照這個觀念,視窗畫面內的各種元件,應該先用子容器區隔為幾個群組,再將元件放入各子容器內。 至於內容面版內子容器的擺放,以及子容器內元件的擺放,則由版面管理員(Layout Manager)處理。當調整視窗大小或顯示於不同作業系統時,版面管理員將自動更新版面,不需您費心處理元件在版面的位置與大小。 版面管理員的特性,請看下表的簡要說明。
3
佈局管理員的取得與設定 欲設定視窗框架中內容面版的佈局管理員時,必須呼叫Container類別的setLayout()方法,規格如下:
public void setLayout(LayoutManager mgr) 回傳值:無 參數說明: LayoutManager mgr 內容面版欲設定使用的佈局管理員物件。若不欲使用任何佈局管理員,則設定為null,您可參考1-4-3節的範例1-5。 欲取得版面管理員則需呼叫Container類別的getLayout()方法,規格如下: public LayoutManager getLayout() 回傳值:回傳目前使用的佈局管理員,型別為LayoutManager。
4
BorderLayout佈局管理員 BorderLayout(外框佈局管理員)是JFrame的內容面版預設之佈局管理員,將把整個版面分成五個區域,分別為東、西、南、北、中,如下圖。 這種版面配置方式適合用於建構視窗程式的主畫面。下表將說明以BorderLayout配置版面時,各位置元件之高度、寬度的設定方式。
5
BorderLayout類別的繼承架構如下圖所示。
6
範例 2-1 BoderLayout import javax.swing.*; //引用套件 import java.awt.*;
public class BorderLayoutEX extends JFrame { BorderLayoutEX() { Container cp = getContentPane(); //取得內容面版 cp.setLayout(new BorderLayout(10, 10)); //建立各區域水平、垂直間距為10的BorderLayout物件 //將各按鈕控制項,加入版面的指定位置 cp.add(new JButton("EAST"), BorderLayout.EAST); cp.add(new JButton("WEST"), BorderLayout.WEST); cp.add(new JButton("SOUTH"), BorderLayout.SOUTH); cp.add(new JButton("NORTH"), BorderLayout.NORTH); cp.add(new JButton("CENTER")); //將元件加入中間區域, //相當於cp.add(new JButton("CENTER", BorderLayout.CENTER)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new BorderLayoutEX(); 範例 2-1 BoderLayout
7
FlowLayout佈局管理員 add()方法的規格如下: public Component add(Component comp)
public Component add(Component comp, int index) 回傳值:完成加入的元件,型別為Component。 使用BorderLayout時,置入各區域之元件的大小,並不是設定的大小,而將依照BoraderLayout的規則控制,說明如下表。 FlowLayout佈局管理員 FlowLayout類別的繼承架構如圖所示。
8
下表將說明FlowLayout的建構子與設定對齊方式、間距之方法。
9
flowLayout import javax.swing.*; //引用套件 import java.awt.*;
public class FlowLayoutEX extends JFrame { FlowLayoutEX() { Container cp = getContentPane(); //取得內容面版 cp.setLayout(new FlowLayout(FlowLayout.RIGHT)); //設定使用版面配置將運用靠右對齊的FlowLayout物件 for(int i=1; i<=5; i++) cp.add(new JButton("按鈕 " + i)); //將按鈕控制項加入面版 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 150); //設定視窗的寬度為300, 高度為150 setVisible(true); } public static void main(String args[]) { new FlowLayoutEX();
10
GridLayout佈局管理員 GridLayout的繼承架構如圖所示 下表為GridLayout的建構子與常用方法
當欄、列數均不為零時,將先符合列數再決定欄數。舉例來說,當設定格狀區塊為3列4欄時,若只有7個元件,最後畫面將被劃分為3列3欄。 若列數為零時,則將先以指定欄數排列元件,再依照元件個數決定列數。
11
GridBagLayout佈局管理員 簡介GridBagLayout 運用GridBagConstraints物件控制元件
範例2-3將運用GridLayout管理內容面版的配置,建立4列3欄水平、垂直間隔均為10的格狀區塊,並加入7個元件。圖的執行結果中,由於僅放入7個元件,故僅顯示3列3欄。 GridBagLayout佈局管理員 簡介GridBagLayout GridBagLayout的繼承架構如圖所示。 範例2-4將設定視窗框架使用GridBagLayout管理版面,並直接加入按鈕元件,不使用GridBagConstraints物件控制。執行結果如下圖所示。 運用GridBagConstraints物件控制元件 GridBagConstraints類別的繼承架構如圖所示。
12
GridLayout import javax.swing.*; //引用套件 import java.awt.*;
public class GridLayoutEX extends JFrame { GridLayoutEX() { Container cp = getContentPane(); //取得內容面版 cp.setLayout(new GridLayout(3, 4, 10, 10)); //指定版面運用3列4行的格狀佈局管理員, 水平與垂直間距分別為10 for(int i=1; i<=7; i++) cp.add(new JButton("Button_" + i)); //將7個按鈕元件加入版面 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 150); setVisible(true); } public static void main(String args[]) { new GridLayoutEX();
13
元件的欄、列位置 – gridx、gridy
GridBagLayout配置版面所劃分的格狀區域,將以左上角為原點,X、Y軸的座標值將從0開始,並向下向右遞增。gridx與gridy屬性將指定元件顯示區域之位置的X、Y座標。若設定給gridx或gridy屬性的數值,其中有一個為負值,則代表是以相對(GridBagLayout.RELATIVE)於前一元件之gridx與gridy位置的方式指定元件位置。 元件內部文字與邊界的間距 – ipadx、ipady ipadx與ipady屬性用於設定元件內部水平與垂直之預留空間的大小。設定後,將增加元件的喜好大小,增加的空間大小分別為ipadx*2像素與ipady*2像素。乘以2的原因是元件的兩邊都會出現預留空間。 控制元件與四周其他元件的間距 – insets GridBagConstraints物件的insets屬性,其型別為java.awt.Insets類別。Insets物件包含四個屬性,可分別代表元件與上、下、左、右四週其他元件的間距大小之整數值。預設Insets物件四週間距的大小均為0。下表將說明Insets類別的建構子。
14
GridBagLayout Ex2-4 import javax.swing.*; //引用Swing套件
import java.awt.*; //引用AWT套件 public class GridBagLayoutEX01 extends JFrame { GridBagLayoutEX01() { Container cp = getContentPane(); //取得版面 cp.setLayout(new GridBagLayout()); //設定使用GridBagLayout版面配置 JButton btnOne = new JButton("Button One"); btnOne.setPreferredSize(new Dimension(120, 40)); //設定元件的喜好大小 cp.add(btnOne); //將按鈕加到版面 cp.add(new JButton("2")); cp.add(new JButton("Button Three")); cp.add(new JButton("Button 4")); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設定關閉視窗時,將結束應用程式 setSize(400, 80); //調整視窗大小 setVisible(true); //顯示視窗 } public static void main(String args[]) { new GridBagLayoutEX01(); //宣告建立視窗畫面的frame物件 GridBagLayout Ex2-4
15
範例2-5將示範使用GridBagLayout管理佈局,並將8個按鈕元件加入視窗畫面,執行結果如圖所示。
顯示空間的對齊設定 – anchor 透過anchor屬性可以控制元件在顯示空間的對齊方式。下表將說明各設定值與代表的對齊方式。
16
GridBagLayout Ex2-5 import javax.swing.*; //引用Swing套件
import java.awt.*; //引用AWT套件 public class GridBagLayoutEX02 extends JFrame { GridBagLayoutEX02() { Container cp = getContentPane(); //取得版面 cp.setLayout(new GridBagLayout()); //設定使用GridBagLayout版面配置 GridBagConstraints gbc = new GridBagConstraints(); //宣告控制元件版面配置的GridBagConstraints物件 gbc.insets = new Insets(5, 5, 5, 5); //設定元件與四周元件的距離 /***加入第一列的元件***/ gbc.ipadx = gbc.ipady = 15; //設定元件內文字與四周邊界的間距均為15 gbc.gridx = 0; gbc.gridy = 0; //設定元件的行列位置 cp.add(new JButton("Button One"), gbc); //將按鈕加到版面 gbc.gridx = 1; gbc.gridy = 0; //設定元件的行列位置 cp.add(new JButton("2"), gbc); /***加入第二列的元件***/ gbc.ipadx = gbc.ipady = 0; //設定元件內文字與四周邊界的間距均為0 GridBagLayout Ex2-5
17
gbc.gridx = 0; gbc.gridy = 1; //設定元件的行列位置
cp.add(new JButton("Button Three"), gbc); gbc.gridx = 1; gbc.gridy = 1; //設定元件的行列位置 cp.add(new JButton("Button 4"), gbc); /***加入第三列的元件***/ gbc.insets = new Insets(0, 0, 0, 0); //設定元件與四周元件的距離 gbc.gridx = 0; gbc.gridy = 2; //設定元件的行列位置 cp.add(new JButton("Button 5"), gbc); //將按鈕加到版面 gbc.gridx = 1; gbc.gridy = 2; //設定元件的行列位置 cp.add(new JButton("Button 6"), gbc); /***加入第四列的元件***/ gbc.gridx = 0; gbc.gridy = 3; //設定元件的行列位置 cp.add(new JButton("Button 7"), gbc); gbc.gridx = 1; gbc.gridy = 3; //設定元件的行列位置 cp.add(new JButton("Button 8"), gbc); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設定關閉視窗時,將結束應用程式 pack(); //調整視窗大小 setVisible(true); //顯示視窗 } public static void main(String args[]) { new GridBagLayoutEX02(); //宣告建立視窗畫面的frame物件
18
多餘空間的分配 – weightx、weighty
右圖為範例2-6的執行結果。 多餘空間的分配 – weightx、weighty weightx與wieghty屬性用於控制當容器在水平方向或垂直方向有多餘空間時,GridBagLayout如何將這些水平或垂直方向的空間分配給元件所佔有的顯示空間。 兩屬性的預設值均為0.0,也就是有多餘空間時,不將空間分配給元件做為顯示空間。若所有元件的水平方向權重均設定為0.0時,則多餘空間將被分配到左右邊界,垂直方向則分配到上下邊界。 當改變前面範例之視窗的大小時,元件的顯示空間並不會隨著改變,您將看到所有元件將集中在視窗中間,如下圖所示 拉大視窗
19
範例2-7將修改自範例2-5,且僅增加以下這行程式敘述,設定所有元件分配多餘空間做為顯示空間的水平方向與垂直方向的權重均為1.0。
017 gbc.weightx = gbc.weighty = 1.0; //設定每個元件分配多餘空間的權重 所以,將視窗畫面拉大時,各元件的顯示空間將可分配到額外空間,分配到的空間將平均置於四週,如下圖所示。 拉大視窗 有一點請注意!某列只要有其中一個元件的垂直方向權重不為0.0,則該列的所有元件均可分配到垂直方向的多餘空間。同樣的,某行只要其中一個元件的水平方向權重不為0.0,則該行的所有元件均可分配到水平方向的多餘空間。下圖為範例2-8的執行結果。
20
範例2-8將混合運用weightx、weighty與anchor屬性控制元件。各元件的設定情況說明如下:
拉大視窗 範例2-8將混合運用weightx、weighty與anchor屬性控制元件。各元件的設定情況說明如下:
21
下圖將標示出當拉大視窗時,各元件所佔據的顯示空間,請與上表做個對照。
顯示空間橫跨的格數 – girdwidth、girdheight girdwidth與gridheight屬性用於設定元件之顯示空間寬度與高度橫跨的格數,設定值型別為整數,預設值均為1。請注意!當元件的顯示空間橫跨更多格數時,將使GridBagLayout動態產生更多欄、列。除了設定橫跨的格數外,您還可以運用下表所列的GridBagConstraints常數:
22
範例2-9將把7個按鈕元件加入容器,並以gridwidth、gridheight屬性配合anchor屬性,控制按鈕元件的顯示空間所橫跨的格數,以及元件在顯示空間的對齊方式。執行結果如下圖所示。
23
下表將說明在範例2-9裡,各按鈕元件之gridwidth、gridheight與anchor屬性的設定值。
請將上表與下圖做一個對照,從下圖各元件的顯示位置與方式,您就可以看出gridwidth、girdheight與anchor屬性如何控制元件的顯示空間,以及對齊方式。
24
範例2-10則介紹GridBagConstraints物件RELATIVE與REMAINDER常數的使用與效過,執行結果如下圖。
下表將說明容器內各元件的gridx、gridy、gridwidth與gridheight屬性的設定值。
25
請對照上表與下圖,從下圖各元件的顯示位置,您就可以看出使用GridBagConstraints物件的RELATIVE與REMAINDER常數設定gridwidth與girdheight屬性對於元件的顯示空間有什麼效果。 以下圖為修改範例2-10增加設定fill屬性(稍後介紹)的範例2-10-1之執行結果,您可更清楚看出GridBagConstraints物件的RELATIVE與REMAINDER常數的設定效果。
26
是否填滿 – fill fill屬性用於控制元件是否填滿顯示空間。設定常數有四種,分別代表四種填滿的方式: 可想而知的,要看出fill屬性的設定效果,顯示空間必須大於元件才行。所以,fill屬性必須配合weightx、weighty、gridwidth或gridheight屬性一起設定才有用,而從範例2-11的執行結果(如下圖),您可觀察出fill屬性配合前述四種屬性產生的效果。
27
下表將說明視窗內各元件之weightx、weighty、gridwidth、gridheight與fill屬性的設定值。
請將上表與右圖做一個對照,從右圖各元件的顯示位置與填滿方式,您可以看出gridwidth、girdheight與fill屬性如何控制元件。
28
CardLayout佈局管理員 拉大視窗將可以看出weightx、weighty與fill屬性如何控制元件。
29
下表為CardLayout切換顯示版面的各種方法。
30
BoxLayout佈局管理員 BoxLayout類別的繼承架構如下圖所示。 以下為BoxLayout的建構子的規格:
public BoxLayout(Container target, int axis) 範例2-12將運用BoxLayout佈局管理員與Box容器,完成如下圖所示的視窗介面。 除了可以運用BoxLayout管理版面外,Box類別則是使用BoxLayout配置版面的容器,功能相當於JPanel可用於群組元件。
31
下表將說明Box類別建構子的規格。 public Box(int axis)
32
SpringLayout佈局管理員 SpringLayout的配置方式 SpringLayout類別的繼承架構如下所示。
下表將分別說明SpringLayout、SpringLayout.Constraints與Spring的功能: Spring類別的繼承架構如圖所示。
33
元件邊界的計算 元件邊界的計算 前面提到SpringLayout.Constraints將由描述元件位置的X、Y座標與寬度、高度之Spring物件組成。但SpringLayout的配置方式將以描述元件四週邊界的方式達成,故SpringLayout.Constraints運用這些資訊,可透過以下公式計算出邊界。 WEST = x NORTH = y EAST = x + width SOUTH = y + height 過度設定的處理 當程式已設定元件的x座標、寬度時,又再設定EAST邊界。這種情況稱為過度設定,因為EAST邊界可以經由『x + width』取得。此時,Constraints物件會以較後(新)設定的值,去重新計算最早的設定值,因此,當發生前述的過度設定情形時,x座標將重新設定為『EAST - width』。
34
SpringLayout配置的設定方式 SpringLayout類別的常數、建構子與方法
下表將說明SpringLayout類別用於代表元件四個邊界的常數,型態為String類別。 下表將說明SpringLayout類別取得/設定控制元件配置之SpringLayout.Constraints物件的方法。
36
SpringLayout.Constraints類別的建構子與常用方法
38
Spring類別的常用方法 下表將介紹Spring類別的常用方法。
39
SpringLayout控制元件配置的方式
方法一、直接於呼叫add()方法將元件加入容器時,直接傳入已完成設定用於控制元件的SpringLayout.Constraints物件。 方法二、呼叫SpringLayout的getConstraints()方法取得控制容器內某元件的SpringLayout.Constraints物件,然後修正控制該物件的Spring物件。 方法三、呼叫SpringLayout的putConstraint()方法建立元件之某邊界與同容器內,另一元件之某邊界的關聯。 下圖為範例2-13的執行結果。
40
第一部分 直接將標籤與文字欄位加入容器,不使用SpringLayout.Constraints物件控制任何元件。 第二部分 第二部分裡,標籤的位置座標為(10, 10),寬度為50,喜好高度為35,最小為25,最大為45(第30~40行)。而文字欄位的座標為(55, 10),寬度為100,高度為30(第44~47行)。至於控制元件配置的方式,將運用方法一,於將元件加入容器時,同時傳入SpringLayout.Constraints物件。 第三部分 在第三部分裡,標籤的位置座標為(10, 10),寬度為35,高度為25。設定時,將先取得標籤的SpringLayout.Constraints物件(第60行)。然後,呼叫各種方法執行設定(第66~69行)。 第四部分 第四部分裡,標籤元件的位置配置方式為將元件加入容器時,直接傳入控制元件位置的SpringLayout.Constraints物件,設定標籤元件的位置為(10, 10)(第90、91行)。文字欄位的位置為WEST邊界距離標籤EAST邊界10像素(第98~100行), EAST、SOUTH、NORTH邊界亦設定距離容器之對應邊界10像素(第103~105行、第106~108行、第110~112行)。設定時,將呼叫SpringLayout類別的putConstraint()方法,指定兩元件邊界的距離。
41
運用SpringLayout格狀配置元件
本節將運用Java說明文件提供的SpringUtilities類別,以該類別的makeGrid()方法與makeCompactGrid()方法,以格狀方式配置容器內的元件。下圖為範例2-14的執行結果。
42
以下為makeGrid()方法與makeCompactGrid()方法的規格:
public static void makeGrid( Container parent, int rows, int cols, int initialX, int initialY, int xPad, int yPad)
43
檔案處理(2)
44
緩衝區的認識 有緩衝區的檔案處理方式 優點: 缺點: 存取時會先將資料放到緩衝區 不需要一直做磁碟讀取 增加程式執行的效率
有緩衝區的檔案處理流程 有緩衝區的檔案處理方式 存取時會先將資料放到緩衝區 不需要一直做磁碟讀取 優點: 增加程式執行的效率 缺點: 會佔用一塊記憶體空間 可能會因沒有關閉檔案或是系統當機而造成資料的流失
45
使用BufferedReader類別 下表列出BufferedReader類別常用的建構元與函數:
46
從緩衝區裡讀入資料 下面的範例說明如何從緩衝區讀入文字檔裡的資料:
47
使用BufferedWriter類別 下表列出BufferedWriter類別常用的建構元與函數:
48
將資料寫到緩衝區 下面的範例說明如何使用BufferedWriter類別: 由於亂數的關係,讀者執行時裡面的數字應和本例不同
49
FileInputStream類別 InputStream與OutputSteram類別可處理的資料
純文字檔 二進位檔(binary file) FileInputStream類別可處理 以「位元組」為主的輸入工作 下表列出FileInputStream類別的建構元:
50
FileInputStream類別的函數
51
讀取檔案 下面的範例示範如何使用FileInputStream類別:
52
使用FileOutputStraem類別
下表列出FileOutputStream類別的建構元與常用函數:
53
處理二進位檔案 (1/2) app14_6示範如何讀入一個圖檔,並將它另存新檔:
54
處理二進位檔案 (2/2) 查詢my_lena圖檔的大小:
55
輸入資料的基本架構 (1/3) 資料輸入的格式: 輸入資料的基本格式
56
輸入資料的基本架構 (2/3) 輸入資料時Scanner類別提供的函數: 使用Scanner類別輸入資料的範例:
57
輸入資料的基本架構 (3/3) 由鍵盤輸入字串的範例
58
輸入數值--不合型態的輸入 若是需要輸入數值,卻輸入字元 ‘k',則會出現類似下 列的錯誤訊息:
59
以Scanner類別輸入字元 用next() 取得字串後,再利用charAt(0) 函數取出字串中第0個字元即可:
60
Scanner 檔案輸入 (1) import java.io.*; // 載入java.io類別庫裡的所有類別
import java.util.Scanner; public class Fs { public static void main(String args[]) throws IOException FileReader fr=new FileReader("fnum.txt"); // 建立物件fr int age[]=new int [10]; Scanner scn=new Scanner(fr); System.out.println("The ages are = "); for (int i=0;i<10;i++){ age[i]=scn.nextInt(); // 輸入整數 if (i!=9) System.out.print(age[i]+", "); else System.out.println(age[i]+" "); } fr.close();
61
Scanner 檔案輸入 (2) import java.io.*; // 載入java.io類別庫裡的所有類別
import java.util.Scanner; public class Fs2 { public static void main(String args[]) throws IOException int i=0; FileReader fr=new FileReader("fnum2.txt"); // 建立物件fr int age[]=new int [10]; Scanner scn=new Scanner(fr); scn.useDelimiter(","); System.out.println("The ages are = "); while (scn.hasNext()){ age[i]=scn.nextInt(); //輸入整數 System.out.print(age[i]+" "); i++; } fr.close();
Similar presentations