69
Giáo trình Java Phần VI: Tạo ra một GUI với JFC/Swing TÓM TẮT Trong phần này sẽ hướng dẫn bạn cách tạo ra những giao diện người dùng đồ hoạ (GUIs) với JFC/Swing cho những ứng dụng và applets thông qua việc sử dụng những thành phần Swing. Những thành phần Swing, một bộ phận của Java TM Foundation Classes (JFC), có thể được sử dụng hoặc với JDK TM 1.1 hoặc Java TM 2 platform. Ghi chú: phần này không hướng dẫn bạn cách sử dụng những thành phần AWT 1. Nhập môn với Swing Trong phần này sẽ lướt qua nhanh và nhằm mục đích là cho bạn hình dung về JFC và Swing. Sau đó sẽ là cách để biên dịch và chạy chương trình - cho cả ứng dụng và các applets thông qua việc sử dụng các thành phần Swing bằng một chương trình đơn giản. 2. Các khái niệm và chức năng của Swing Cung cấp các thông tin cần thiết để sử dụng các thành phần Swing một cách có hiệu quả. Ví dụ như cách một chương trình Swing hiển thị giao diện đồ hoạ người dùng, cách quản lý các sự kiện như kích chuột và cuối cùng sẽ là việc sử dụng các khái niệm và chức năng như thế nào trong một chương trình thực sự. 3. Sử dụng các thành phần Swing Hướng dẫn cách sử dụng mỗi thành phần Swing – button, table, các thành phần text…(nhìn chung các thành phần Swing cung tương tự như các thành phần AWT. Tuy nhiên, chúng có một số tính năng mới. Ví dụ như button, label có thể nạp hình ảnh,...) 4. Sử dụng các chức năng khác của Swing. Nói thêm về các thành phần khác của Swing như actions, borders, icons, và timers. Ngoài ra sẽ còn hướng dẫn bạn cách tạo một chương trình đa tuyến (multithreaded) 5. Các thành phần Laying Out là đối tượng chứa. Hướng dẫn cách chọn một (layout manager), cách sử dụng của mỗi lớp layout manager mà Java cung cấp. 6. Cách viết một sự kiện Listener Hướng dẫn cách nắm bắt các sự kiện trong chương trình 7. Làm việc với đồ họa 9095883.doc 1

7045244 Creating GUI With JFC Swing

  • Upload
    saku-ra

  • View
    230

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Phần VI: Tạo ra một GUI với JFC/Swing

TOM TĂTTrong phân nay se hương dân ban cach tao ra nhưng giao diên ngươi dung đô hoa (GUIs) vơi JFC/Swing cho nhưng ưng dung va applets thông qua viêc sư dung nhưng thanh phân Swing. Nhưng thanh phân Swing, môt bô phân cua JavaTM

Foundation Classes (JFC), co thê đươc sư dung hoăc vơi JDKTM 1.1 hoăc JavaTM 2 platform.Ghi chu: phân nay không hương dân ban cach sư dung nhưng thanh phân AWT1. Nhập môn với SwingTrong phần này sẽ lướt qua nhanh và nhằm mục đích là cho bạn hình dung về JFC và Swing. Sau đó sẽ là cách để biên dịch và chạy chương trình - cho cả ứng dụng và các applets thông qua việc sử dụng các thành phần Swing bằng một chương trình đơn giản.

2. Cac khai niêm va chưc năng cua Swing

Cung câp cac thông tin cân thiêt đê sư dung cac thanh phân Swing môt cach co hiêu qua. Vi du như cach môt chương trinh Swing hiên thi giao diên đô hoa ngươi dung, cach quan ly cac sư kiên như kich chuôt va cuôi cung se la viêc sư dung cac khai niêm va chưc năng như thê nao trong môt chương trinh thưc sư.

3. Sư dung cac thanh phân Swing

Hương dân cach sư dung môi thanh phân Swing – button, table, cac thanh phân text…(nhin chung cac thanh phân Swing cung tương tư như cac thanh phân AWT. Tuy nhiên, chung co môt sô tinh năng mơi. Vi du như button, label co thê nap hinh anh,...)

4. Sư dung cac chưc năng khac cua Swing.

Noi thêm vê cac thanh phân khac cua Swing như actions, borders, icons, va timers. Ngoai ra se con hương dân ban cach tao môt chương trinh đa tuyên (multithreaded)

5. Cac thanh phân Laying Out la đôi tương chưa.

Hương dân cach chon môt (layout manager), cach sư dung cua môi lơp layout manager ma Java cung câp.

6. Cach viêt môt sư kiên Listener

Hương dân cach năm băt cac sư kiên trong chương trinh

7. Lam viêc vơi đô hoa

9095883.doc 1

Page 2: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Sư dung cac đương ve, cac text đê chê tao ra môt hinh anh, kê ca cac hinh anh đông.

8. Chuyên đôi thanh Swing

Hương dân cach chuyên đôi môt chương trinh sư dung AWT API 1.1 sang chương trinh sư dung cac thanh phân Swing.

Bai 1: Băt đâu vơi Swing

1. Đôi điêu vê JFC va Swing

JFC (Java Foundation Classes) la môt tâp hơp cac chưc năng giup ngươi dung xây dưng giao diên đô hoa (GUIs). JFC đươc công bô lân đâu tiên vao năm 1997 trong hôi nghi vê nhưng nha phat triên JavaOne, bao gôm nhưng chưc năng sau:

1. Cac thanh phân Swing

2. Hô trơ Pluggable Look and Feel

3. Truy câp API

4. Java 2D API (Java 2 Platform only)

5. Hô trơ Drag and Drop (Java 2 Platform only)

3 chưc năng đâu cua JFC đươc thưc hiên ma không cân bang ma quôc gia ma dưa vao cac ham API co trong JDK 1.1

Nhưng phiên ban co Swing API

Swing API đa đươc sư dung trong 2 dang sau:(1) La phân côt loi cua Java 2 Platform (phiên ban chuân cua v 1.2 va v 1.3)(2) JFC 1.1 (sư dung vơi JDK 1.1)

Vơi môi phiên ban sư dung, tuy thuôc vao viêc chung ta cân đên JDK 1.1 hay la Java 2 Platform va không cân phai thêm bât ky thư viên nao ma vân co thê sư dung đươc Swing API. Tuy nhiên, nêu cân sư dung JDK 1.1 thi thêm vao Swing API (sư dung JFC 1.1)Hang Sun đa phat hanh nhiêu phiên ban cua JFC 1.1 va đê nhân biêt no la phiên ban nao thi cân dưa vao phiên ban cua Swing API chưa trong no.Bang sau đây liêt kê cac thông tin vê Swing API.

Swing API Version

Tương ưng vơi phiên banJFC 1.1

Tương ưng vơi phiên ban Java 2 Platform (Standard Edition)

Chu thich

Swing 1.0.3 JFC 1.1 (with

Không Phiên ban cua JFC 1.1 bao gôm Java Plug-inTM 1.1.1.

9095883.doc 2

Page 3: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Swing 1.0.3)

Swing 1.1 JFC 1.1 (with Swing 1.1)

v 1.2, v 1.2.1

Phiên ban đâu tiên co đây đu Swing 1.1 API hô trơ đê sư dung cac san phâm thương mai. Java Plug-in 1.1.2 va Java Plug-in 1.2 cung câp applet hô trơ cho tưng JDK 1.1 + Swing 1.1 va Java 2 Platform v 1.2 tương ưng.

Swing 1.1.1 JFC 1.1 (with Swing 1.1.1)

v 1.2.2

Thêm vao cac tinh năng mơ rông, xư ly nhiêu lôi ky thuât, cac chưc năng mơi (API không cân thay đôi) cho Swing 1.1. Java Plug-in 1.1.3 va Java Plug-in 1.2.2 cung câp applet hô trơ choJDK 1.1 + Swing 1.1.1 va Java 2 Platform v 1.2.2, tương ưng.

Không co sư khac biêt vê "Swing" version

Không co v 1.3 Beta

Thêm vao cac tinh năng, xư ly nhiêu lôi ky thuât, cac chưc năng mơi. Bô sung thêm cac tinh năng va cac ham API mơi. Java Plug-in 1.3 Beta cung câp applet hô trơ cho phiên ban nay.

Cac goi Swing

Swing API vưa lơn manh, lai vưa mêm deo. Trong phiên ban 1.1 cua API co 15 goi dung chung: javax.accessibility, javax.swing, javax.swing.border, javax.swing.colorchooser, javax.swing.event, javax.swing.filechooser, javax.swing.plaf, javax.swing.plaf.basic, javax.swing.plaf.metal, javax.swing.plaf.multi, javax.swing.table, javax.swing.text, javax.swing.text.html, javax.swing.tree, and javax.swing.undo.Trong hâu hêt cac chương trinh chi sư dung môt phân nho cua API, chu yêu la cac goi Swing javax.swing, javax.swing.event.

Sư khac biêt giưa cac thanh phân Swing va AWT

Cac thanh phân AWT đươc cung câp trong JDK 1.0 va 1.1. Măc du Java 2 Platform vân con hô trơ cac thanh phân AWT, tuy nhiên, chung ta nên dung cac thanh phân Swing. Khi sư dung, co thê phân biêt cac thanh phân Swing vơi cac thanh phân AWT. Cac thanh phân Swing co tên băt đâu băng ky tư J. Vi du như, lơp AWT button class co tên la Button thi lơp Swing button co tên la Jbutton. Ngoai ra, cac thanh phân AWT thi năm trong goi java.awt, con cac thanh phân Swing thi năm trong goi javax.swing. Do đo, khi sư dung cac thanh phân Swing thi trong phân khai bao cua chương trinh, ta nhơ thêm vao dong lênh sau:

import javax.swing.*;

Sư khac biêt lơn nhât giưa cac thanh phân AWT va Swing đây la cac thanh phân Swing đươc thưc thi ma hoan toan không cân ma nguôn (with absolutely no native code). Kê tư khi cac thanh phân Swing không con bi han chê trong nhưng khuôn mâu thông thương, (the least common denominator), tưc la luc ma cac tinh năng cua no đa co măt hâu hêt trong cac phiên ban, thi cac chưc năng cua no đa mơ rông hơn nhiêu so vơi cac chưc năng cua cac thanh phân AWT. Do cac thanh phân Swing không co ma

9095883.doc 3

Page 4: 7045244 Creating GUI With JFC Swing

Giao trinh Java

nguôn (native code), nên chung co thê đươc thêm vao như la môt add-on cua JDK 1.1 hay như môt phân cua Java 2 Platform.

Ngay ca nhưng thanh phân Swing đơn gian nhât cung đa co nhưng kha năng vươt xa cac thanh phân AWT:

• Swing buttons va labels co thê hiên thi hinh anh va ca văn ban.

• Co thê dê dang thay đôi đương viên cua hâu hêt cac thanh phân Swing. Ta co thê dê dang thay đôi đương viên cua môt label hay môt đôi tương chưa nao đo.

• Co thê dê dang thay đôi hanh vi hay giao diên cua môt thanh phân Swing trong phương thưc điêu khiên cua no hoăc tao ra môt lơp con (subclass) cua chinh thanh phân đo.

• Thanh phân Swing không co hinh chư nhât. Do đo, cac nut lênh co thê co hinh tron hoăc bo goc.

• Ky thuât hô trơ (Assistive technologies) qua viêc đoc man hinh co thê dê dang lây thông tin tư cac thanh phân Swing.

2. Biên dich va thưc thi môt chương trinh Swing

Ðê viêt môt chương trinh sư dung cac thanh phân Swing, trươc tiên, ta phai co phiên ban cua JDK va JFC tương ưng. Biên dich va thưc thi môt chương trinh Swing con tuy thuôc vao viêc đang sư dung JDK 1.1 hay Java 2 Platform. Nêu sư dung Java 2 Platform thi se đơn gian hơn vi Swing đa đươc tich hơp.

2.1 Biên dich va thưc thi chương trinh vơi Java 2 Platform, v 1.2 or 1.3

Trong phân nay, chung ta se khao sat cac vân đê qua vi du SwingApplication.java co giao diên như sau:

Sau đây la cac bươc trinh tư cho viêc biên dich va thưc thi môt chương trinh Swing vơi Java 2 SDK, v 1.2 hay v 1.3:

1. Nêu chưa co, cai đăt vao may phiên ban Java 2 Platform.

2. Tao môt chương trinh sư dung cac thanh phân Swing.

3. Biên dich chương trinh.

4. Cho thưc thi chương trinh.

9095883.doc 4

Page 5: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Hiên nay, đang co 2 phiên ban cua Java 2 Platform, tât ca đêu miên phi do Sun cung câp (ban co thê vao đia chi nay đê đươc hô trơ: http://www.sun.com). Phiên ban thư nhât la v 1.2 (Java 2 SDK, Standard Edition v 1.2) va phiên ban thư hai la v 1.3 (Java 2 SDK, Standard Edition v 1.3).

Ðê tao môt chương trinh sư dung cac thanh phân Swing, co thê sư dung chương trinh mâu ma chung tôi cung câp sau đây SwingApplication.java. Cân lưu y la tên file phai chinh xac la: "SwingApplication.java"

import javax.swing.*; //This is the final package name.//import com.sun.java.swing.*; //Used by JDK 1.2 Beta 4 and all//Swing releases before Swing 1.1 Beta 3.import java.awt.*;import java.awt.event.*;

public class SwingApplication { private static String labelPrefix = "Number of button clicks: "; private int numClicks = 0;

public Component createComponents() { final JLabel label = new JLabel(labelPrefix + "0 ");

JButton button = new JButton("I'm a Swing button!"); button.setMnemonic(KeyEvent.VK_I); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); } }); label.setLabelFor(button);

/* * An easy way to put space between a top-level container * and its contents is to put the contents in a JPanel * that has an "empty" border. */ JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder( 30, //top 30, //left 10, //bottom 30) //right ); pane.setLayout(new GridLayout(0, 1)); pane.add(button);

9095883.doc 5

Page 6: 7045244 Creating GUI With JFC Swing

Giao trinh Java

pane.add(label);

return pane; }

public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { }

//Create the top-level container and add contents to it. JFrame frame = new JFrame("SwingApplication"); SwingApplication app = new SwingApplication(); Component contents = app.createComponents(); frame.getContentPane().add(contents, BorderLayout.CENTER);

//Finish setting up the frame, and show it. frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); }}

Bươc tiêp theo la biên dich. Viêc biên dich trơ nên đơn gian va dê dang vơi Java 2 SDKs khi cac goi Swing đươc tich hơp trong phiên ban Standard Edition cua Java 2 Platform. Câu lênh như sau:

javac -deprecation SwingApplication.java

Trương hơp khi biên dich không thanh công, co thê la do ban đang sư dung trinh biên dich JDK 1.1 thay vi v 1.2 hoăc v 1.3 hoăc đang sư dung ban beta cua Java 2 Platform.

Thưc thi chương trinh se đươc thưc hiên khi đa biên dich thanh công. Cân đam bao la trong class path đa chi đương dân đên file thưc thi:

Vd: java -classpath .;C:\java\lnfdir\newlnf.jar SwingApplication

Lưu y: không cân phai go phân đuôi mơ rông .cls. trinh thông dich cua phiên ban 1.2 hay 1.3 se tư đông do tim.

2.2 Biên dich va thưc thi chương trinh vơi JDK 1.1

9095883.doc 6

Page 7: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Cung tương tư như vơi Java 2 Platform, nhưng trinh biên dich sư dung ơ đây la JDK 1.1 va JFC 1.1.

3. Thưc thi cac Swing Applets

Đê viêt môt Swing Applets, trươc tiên la phai thưc thi đươc chung. Phân nay se giơi thiêu 2 applets.

Sau đây la phân ma cua applets HelloSwingApplet.java

import javax.swing.*; //This is the final package name.//import com.sun.java.swing.*; //Used by JDK 1.2 Beta 4 and all //Swing releases before Swing 1.1 Beta 3.import java.awt.*;

public class HelloSwingApplet extends JApplet {

// This is a hack to avoid an ugly error message in 1.1. public HelloSwingApplet() { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); }

public void init() { JLabel label = new JLabel( "You are successfully running a Swing applet!"); label.setHorizontalAlignment(JLabel.CENTER);

//Add border. Should use createLineBorder, but then the bottom //and left lines don't appear -- seems to be an off-by-one error. label.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black));

getContentPane().add(label, BorderLayout.CENTER); }}

Đê thưc thi môt Swing Applets, theo trinh tư cac bươc sau:

(1) Đam bao la đa co trinh duyêt 1.1 hoăc 1.2 hoăc tai vê Java Plug-in va chung la nhưng phiên ban mơi nhât. Trương hơp không co cac thư trên, co thê sư dung Applet Viewer (appletviewer).

(2) Nêu ban đang sư dung trinh duyêt 1.1 không co Java Plug-in thi cân phai nap file Swing JAR vao trinh duyêt.

9095883.doc 7

Page 8: 7045244 Creating GUI With JFC Swing

Giao trinh Java

(3) Kiêm tra lai xem trinh duyêt cua ban đa hoan chinh chưa. Trong pham vi bai nay thi hinh dươi đây kiêm chưng cho trinh duyêt cua ban la đa đap ưng hoan hay hay chưa. Nêu trong trinh duyêt cua ban xuât hiên applet như dươi đây thi OK. Trương hơp chi thây môt thay vi hai applet hoăc không thây cac hinh anh thi trinh duyêt cua ban chưa thưc sư săn sang.

4. Trao đôi thêm vê môt ưng dung Swing

Trong phân nay, chung ta se tim hiêu thêm thông qua chương trinh SwingApplication. SwingApplication se hiên thi cưa sô như sau:

Phân ma cua SwingApplication.java thưc hiên nhưng công viêc sau:

Importing Swing packages

Dong lênh sau se import goi Swing chinh:

import javax.swing.*;

Lưu y: JFC 1.1 va Java 2 SDK v 1.2 phiên ban beta sư dung tên goi khac nhau cho goi Swing.

Hâu hêt cac chương trinh đêu cân import hai goi chinh cua AWT la: import java.awt.*;import java.awt.event.*;

Choosing the look and feel

Swing cho phep ban chi đinh ro “look and feel” ma chương trinh cua ban sư dung -- Java look and feel, Windows look and feel, CDE/Motif look and feel, ... Đoan ma in đâm dươi đây se chi ra cho ban cach ma SwingApplication chi đinh “look and feel”:

public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName());

9095883.doc 8

Page 9: 7045244 Creating GUI With JFC Swing

Giao trinh Java

} catch (Exception e) { }

...//Create and show the GUI...}

Xac lâp đôi tương chưa mưc đinh

Môi chương trinh đươc trinh diên đêu co giao diên vơi mưc đơn gian nhât la môt đôi tương chưa thuôc thanh phân cua Swing ơ mưc đinh. Ơ hâu hêt cac ưng dung, đôi tương chưa Swing ơ mưc đinh co thê la JFrame, JDialog, hoăc (cho applets) JApplet. Môi đôi tương JFrame se thưc hiên môt cưa sô chinh va môi JDialog se thưc thi cho cưa sô thư hai. Môi đôi tương JApplet thưc hiên viêc hiên thi cua môt applet bên trong môt cưa sô. Cac đôi tương chưa mưc đinh cua Swing cung câp cac hô trơ cân thiêt đê cac thanh phân Swing thưc hiên viêc ve va quan ly cac hanh vi.

Ví dụ SwingApplication chỉ có đối tượng chứa mức đỉnh là JFrame. Khi người sư dung đóng frame thi ưng dung sẽ thoát. Đoạn mã sau đây xác lập và cho hiển thị frame:

public class SwingApplication { ... public static void main(String[] args) {

... JFrame frame = new JFrame("SwingApplication"); //...create the components to go into the frame... //...stick them in a container named contents... frame.getContentPane().add(contents, BorderLayout.CENTER);

//Finish setting up the frame, and show it. frame.addWindowListener(...); frame.pack(); frame.setVisible(true); }}

Xac lâp buttons va labels

Giống như GUIs, giao diện của SwingApplication chứa một button và một label. Đoạn mã sau đây khởi tạo button đó:

(1) JButton button = new JButton("I'm a Swing button!");(2) button.setMnemonic(KeyEvent.VK_I);(3) button.addActionListener(...create an action listener...);

Dòng lệnh (1) để tạo một nút lệnh với tiêu đề "I'm a Swing button!". Dòng (2) xác lập key I đóng vai trò tương tự như sự kiện người dùng kích vào nút

9095883.doc 9

Page 10: 7045244 Creating GUI With JFC Swing

Giao trinh Java

lệnh(tức là khi người dùng nhấn Alt-i thì cùng tương tự như kích chuột vào nút lệnh). Dòng (3) đăng ký việc nắm bắt sự kiện cho việc kích nút lệnh

Đoạn mã sau đây khởi tạo và vận hành hoạt động của label:

..//where instance variables are declared:private static String labelPrefix = "Number of button clicks: ";private int numClicks = 0;...//in GUI initialization code:final JLabel label = new JLabel(labelPrefix + "0 ");...label.setLabelFor(button);...//in the event handler for button clicks:label.setText(labelPrefix + numClicks);

Đoạn mã trên đơn giản, ngoại trừ dòng khởi động phương thức setLabelFor(). No xuât hiên ơ đây giông như sư gơi y vê ky thuât hô trơ trưc tiêp (assistive technologies) ma thông qua đo, môt label đươc mô ta như la môt button.

Thêm thanh phân vao cac đôi tương chưa.

SwingApplication nhom label va button vao trong môt đôi tương chưa (JPanel) trươc khi thêm vao frame môt thanh phân khac. Đoan ma sau đây khơi tao môt panel:

(1) JPanel pane = new JPanel();(2) pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30));(3) pane.setLayout(new GridLayout(0, 1));(4) pane.add(button);(5) pane.add(label);

Dong (1) dung đê tao môt panel, khai bao môt đôi tương co kiêu Jpanel vơi tên goi la pane.

Dong (2) đê tao đương viên bao boc cho panel đo.

Dong (3) dung đe tao môt đôi tương quan ly layout đê giam sat tât ca cac thanh phân co trong panel se đươc hiên thi trên môt côt.

Dong (4) va (5) dung đê đưa button va label vao trong panel. Viêc thêm button va label vao trong panel co nghia la chung se đươc điêu khiên bơi layout quan ly panel đo.

Thêm đương viên (borders) xung quanh môt thanh phân.

Đoan ma sau đây se tao môt đương viên cho môt panel:

pane.setBorder(BorderFactory.createEmptyBorder( 30, //top

9095883.doc 10

Page 11: 7045244 Creating GUI With JFC Swing

Giao trinh Java

30, //left 10, //bottom 30) //right );

đương viên nay đơn gian chi cung câp môt vung trông cua panel. Thêm 30 pixels cho top, left, va right, va 10 pixels cho bottom. Borders la tinh năng ma JPanel thưa kê tư lơp JComponent.

Handling events

SwingApplication chưa 2 event handlers. Môt năm băt sư kiên kich vao nut lênh(action events). Cai kia đê năm băt sư kiên đong cưa sô (window events). Sau đây la đoan ma quan ly cac sư kiên cua SwingApplication:

button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); }});...frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {

System.exit(0); }});

Dealing with thread issues

Chương trinh SwingApplication la môt tiên trinh an toan. Bơi vi, môt khi giao diên cua no đang đươc hiên thi (visible), thi thao tac trên giao diên cua no chi xay ra cho môt event handler. Không thê co hai tiên trinh cung truy xuât đên môt GUI trong cung fmôt thơi điêm.

Supporting assistive technologies

Hô trơ assistive technologies, môt thiêt bi giông như đê đoc man hinh, cung câp cach thưc đê xư ly thông tin trên GUI. Hô trơ nay đa co trong hâu hêt cac thanh phân Swing. Trong SwingApplication co môt chô đê câp đên ky thuât nay:

label.setLabelFor(button);

Như đa noi, viêc lây thông tin tư cac thanh phân Swing la điêu đang đươc quan tâm, ky thuât trên đa giup cho công viêc nay đươc thưc hiên môt cach dê dang:

JButton button = new JButton("I'm a Swing button!");label = new JLabel(labelPrefix + "0 ");label.setText(labelPrefix + numClicks);JFrame frame = new JFrame("SwingApplication");

9095883.doc 11

Page 12: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bai 2: Cac khai niêm va chưc năng cua Swing

Trong bai nay se giơi thiêu cac đăc trưng cua Swing va giang giai cac khai niêm cân thiêt đê ban co thê năm băt va sư dung cac thanh phân Swing môt cach co hiêu qua. Phân cuôi cua bai hoc nay se phân tich môt chương trinh Swing và đây se la phân tông kêt lai nhưng gi ban đa hoc trong bai nay.

1. Cac thanh phân Swing va sư phân câp giơi han.

Swing cung câp rât nhiêu thanh phân GUI chuân như: buttons, lists, menus, va text areas, la nhưng thanh phân ma ban se phôi hơp đê tao nên GUI cho chương trinh cua ban. Ngoai ra, con co cac đôi tương chưa như windows va tool bars.

Trong phần này , chúng ta sẽ tiếp tục xem xét thông qua ví dụ SwingApplication đã được mô tả trong phần A Quick Tour of a Swing Application's.

Ví dụ này sẽ đề cập đến một vài thanh phân Swing thường dùng và cách thức chúng tương tác với nhau trong một GUI và của sự phân cấp giới hạn.

SwingApplication tạo 4 thanh phân Swing thường dùng như sau:

• một frame, hoặc một cửa sổ làm việc chính (JFrame)

• một panel, thông thường gọi là pane (JPanel)

• một button (JButton)

• một label (JLabel)

frame là đối tượng chứa ở mức đỉnh. is a top-level container. Sự hiện diện của frame nhằm cung câp một vùng để các thanh phân khác thiết lập sự có mặt của mình trên vùng đó. Ngoài ra còn có các thanh phân khác thường được sư dung để làm đối tượng chứa mức đỉnh là dialogs (JDialog) và applets (JApplet). panel là đối tượng chứa mức trung gian (intermediate container). panel nhăm muc đich xac đinh vi tri cua button va label. Nhưng đôi tương chưa mưc trung gian khac con co scroll panes (JScrollPane) va tabbed panes (JTabbedPane), chung co anh hương lân nhau, tương tac vơi nhau rtong giao diên cua môt chương trinh.

9095883.doc 12

Page 13: 7045244 Creating GUI With JFC Swing

Giao trinh Java

button va label la nhưng thanh phân cơ ban (atomic components), nhưng thanh phân ma không thê chưa cac thanh phân Swing khac AWT thông thương, cac thanh phân cơ ban nay se la nơi đê nhân thông tin đâu vao tư phia ngươi dung. Swing API cung câp nhiêu thanh phân cơ ban, bao gôm combo boxes (JComboBox), text fields (JTextField), va tables (JTable). Hinh dươi đây la sơ đô phân câp giơi han cua cac thanh phân trong vi du SwingApplication.

Như hinh ve trên, ngay ca cac chương trinh Swing đơn giann nhât cung co nhiêu mưc khac nhau. Nhưng bao giơ gôc cua sơ đô vân la đôi tương chưa mưc đinh, nơi đê cac thanh phân Swing khac thê hiên sư tôn tai cua minh.

Mach nươc: Đê xem sư phân câp cua bât ky frame hay dialog nao, chi cân kich chuôt vao border cua no đê chon, nhân Control-Shift-F1.

Môi môt đôi tương chưa mưc đinh đêu gian tiêp chưa môt đôi tương chưa trung gian thương đươc goi la content pane. Khi lam viêc, ban không cân quan tâm thê nao la đôi tương chưa mưc đinh va cai nao la đôi tương chưa trung gian. Chương trinh se tư đông quan ly cho ban. pane contains, trưc tiêp hoăc gian tiêp chưa tât ca cac thanh phân se hiên thi trong GUI. Riêng đôi vơi top-level container thi co menu bar, menu bar se đưng trong môt vung đăc biêt năm ngoai content pane. Đê thêm môt thanh phân vao đôi tương chưa, co thê dung nhiêu cach khac nhau cua phương thưc add(). Phương thưc add() co it nhât 1 đôi sô (argument)Đoan ma sau đây se thưc hiên viêc thêm môt button va môt label vao trong panel:

frame = new JFrame(...);button = new JButton(...);label = new JLabel(...);pane = new JPanel();pane.add(button);pane.add(label);frame.getContentPane().add(pane, BorderLayout.CENTER);

2. Layout Management

9095883.doc 13

Page 14: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Cac đôi tương chưa sư dung layout managers đê xac lâp kich thươc va vi tri cua cac thanh phân chưa trong no. Borders se anh hương đên layout cua Swing GUIs băng cach lam cho cac thanh phân lơn lên.

Hinh dươi đây hiên thi GUI cua 5 chương trinh. GUI cua chung khac nhau la do sư dung cac layout managers khac nhau đê xac đinh kich thươc va vi tri cua buttons.

Layout management la qua trinh xac đinh kich thươc va vi tri cua cac thanh phân. Măc đinh, môi đôi tương chưa se co môt layout manager.

Java platform hô trơ sư dung 5 layout managers thông thương nhât: BorderLayout, BoxLayout, FlowLayout, GridBagLayout, va GridLayout. Nhưng layout managers đươc thiêt kê đê hiên thi đa thanh phân trong cung môt thơi điêm. Va lơp thư 6, CardLayout, la môt trương hơp đăc biêt. No đươc sư dung đê kêt hơp cac layout managers vơi nhau.

Xac lâp Layout Manager

Ban co thê dê dang thay đôi môt layout managers trơ thanh môt container đê sư dung. Đơn gian la chi cân goi phương thưc setLayout. Đoan ma sau đây sư dung BorderLayout:

JPanel pane = new JPanel();pane.setLayout(new BorderLayout());

Môt vai gơi y vê Component (Providing Hints about a Component)

Ta co thê sư dung cac phương thưc sau đê tuy biên kich thươc va vi tri cua cac thanh phân: setMinimumSize, setPreferredSize, va setMaximumSize, hoăc co thê xây dưng cac lơp con cua cac thanh phân đê khai thac cac phương thưc như: getMinimumSize, getPreferredSize, va getMaximumSize.

9095883.doc 14

Page 15: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bên canh viêc cung câp cac tuy biên vê kich thươc, ta cung con co thê cung câp thêm cac tuy biên vê viêc canh chinh, gôm cac phương thưc sau: setAlignmentX va setAlignmentY, getAlignmentX va getAlignmentY methods.

How Layout Management Occurs

Vi du sau đây mô ta trinh tư qua trinh hiên thi cua môt frame (JFrame).

1. Khi GUI đươc xây dưng, JFrame se goi phương thưc pack. Viêc chi đinh nay se bao đam frame xuât hiên đung vơi kich thươc ma no đa đươc xac lâp trươc đo.

2. To find the frame's preferred size, the frame's layout manager adds the size of the frame's edges to the preferred size of the component directly contained by the frame. This is the sum of the preferred size of the frame's content pane, plus the size of the frame's menu bar, if any.

3. The content pane's layout manager is responsible for figuring out the content pane's preferred size. By default, this layout manager is a BorderLayout object. However, let's assume that we replace it with a GridLayout object that's set up to create two columns, as in the bottom right of the preceding snapshot. The interesting thing about grid layout is that it forces all components to be the same size, and it tries to make them as wide as the widest component's preferred width and as high as highest one's preferred height.

First, the grid layout manager queries the content pane for its insets -- the size of the content pane's border, if any. Next, the grid layout manager queries each component in the content pane for its preferred size, noting the largest preferred width and largest preferred height. Then it calculates the content pane's preferred size.

4. When each button is asked for its preferred size, the button first checks whether the user specified a preferred size. If so, it reports that size. If not, it queries its look and feel for the preferred size.

3. Event Handling

Event handling thê hiên viêc chương trinh phan hôi cac yêu câu tư phia bên ngoai, vi du như viêc ngươi dung nhân phim chuôt. Chương trinh Swing se thưc hiên tât ca cac thao tac va năm băt cac sư kiên (event handling) băng cach thưc hiên tiên trinh cua sư kiên.

Môi khi ngươi dung nhân phim hay kich chuôt, thi môt sư kiên xay ra. Bât kê đôi tương nao cung đêu đươc gan bơi môt sư kiên. Cac thanh phân Swing co

9095883.doc 15

Page 16: 7045244 Creating GUI With JFC Swing

Giao trinh Java

thê tao ra nhiêu kiêu sư kiên khac nhau. Bang sau đây liêt kê môt vai kiêu sư kiên:

Hanh đông Kiêu Listener User kich vao nut lênh, nhân phim Spacebar khi đang lam viêc trong text field, hoăc kich chon vao menu item

ActionListener

User đong môt frame (main window) WindowListener

User nhân môt nut chuôt trong khi đang rê chuôt trên môt thanh phân

MouseListener

User di chuyên chuôt trên môt thanh phân MouseMotionListener

Thanh phân hiên thi ComponentListener

Thanh phân lây trang thai cua keyboard FocusListener

Viêc chon lưa trong Table hoăc list co thay đôiListSelectionListener

Môi sư kiên đêu đươc đai diên bơi môt đôi tương va đôi tương đo cung câp thông tin vê sư kiên cung như nhân dang đươc nơi phat ra sư kiên. Nguôn cua sư kiên thông thương la cac thanh phân, nhưng nhưng kiêu đôi tương khac cung co thê la nguôn cua sư kiên. Hinh sau đây minh hoa cho vân đê nay.

Caption: Multiple listenerscan register to be notified of events of a particular type from a particular source.

Cach thưc thi môt Event Handler (How to Implement an Event Handler)

Môi event handler đoi hoi co 3 bươc như sau:

1. Trong phân khai bao cho lơp event handler, xac đinh ro môi lơp se thưc thi môt listener interface hoăc kê thưa môt lơp ma lơp đo thưc thi môt listener interface. Vi du:

2. public class MyClass implements ActionListener {

3. Đăng ky sư hiên diên cua lơp event handler như la môt listener trên môt hoăc nhiêu thanh phân. Vi du:

4. someComponent.addActionListener(instanceOfMyClass);

9095883.doc 16

Page 17: 7045244 Creating GUI With JFC Swing

Giao trinh Java

5. Thưc thi nhưng phương thưc trong listener interface. Vi du:

6. public void actionPerformed(ActionEvent e) {7. ...//code that reacts to the action...8. }

Hay xem xet cach thưc môt nut lênh (JButton) năm băt sư kiên kich chuôt. Đê xac đinh khi nao thi ngươi dung kich chuôt lên nut lênh (hoăc dung cac phim nong) thi môt chương trinh phai co đôi tương thưc thi giao diên ActionListener. Chương trinh phai đăng ky đôi tương đo như la môt action listener trên nut lênh (nguôn cua sư kiên) băng cach sư dung phương thưc addActionListener. Khi user kich lên nut lênh, nut lênh se phat ra môt hanh vi cua sư kiên. Đây la yêu câu cua phương thưc actionPerformed. Trong phương thưc nay, tham sô se la môt đôi tương ActionEvent va tham sô nay se cung câp thông tin vê sư kiên va nguôn cua sư kiên.

Caption: Khi user vao nut lênh, action listeners cua nut lênh đươc phat ra.

Tiên trinh va Event Handling (Threads and Event Handling)

Ma cua event-handling xay ra trong môt tiên trinh đơn hay con goi la event-dispatching thread. Điêu nay nhăm đam bao la môi event handler hoan thanh viêc thưc hiên trươc khi môt event handler xay ra. Ơ vi du minh hoa trên, phương thưc actionPerformed đươc xư ly trong môt tiên trinh đơn.

4. Painting

Painting nghia la ve cac thanh phân trên man hinh. Măc dâu viêc tuy chon cac thanh phân đươc thưc hiên môt cach dê dang, nhưng hâu hêt cac chương trinh đêu bi lam phưc tap lên băng cach tuy chon đương viên cho cac thanh phân.

Cach lam viêc cua Painting (How Painting Works)

Khi môt Swing GUI cân ve lai giao diên cua chinh no, hoăc khi cân lam tươi nhưng điêu chinh vê trang thai cua chương trinh, no se khơi đông thanh phân ơ mưc cao nhât (top-level component) cân đươc ve lai va lam viêc dân xuông theo luông phân câp. Qua trinh xư ly nay đươc thưc hiên bơi hê thông AWT nhamư lam cho chương trinh co ve hiêu qua va thich ưng hơn.

Cac thanh phân Swing co thê ve lai chinh no bât kê khi nao cân thiêt. Khi goi phương thưc setText trên môt thanh phân, thanh phân đo se tư đông ve lai chinh no, thay đôi kich thươc,…

9095883.doc 17

Page 18: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Cung giông như event-handling, painting cung đươc thưc hiên trong môt tiên trinh đơn. Trong khi môt sư kiên đang xay ra thi qua trinh ve lai không đươc thưc hiên.

Qua trinh ve lai cac thanh phân se không bi ngăt quang bơi cac sư kiên khac.

Vi du minh hoa vê Painting (An Example of Painting)

Đê minh hoa cho qua trinh painting, ta sư dung lai chương trinh SwingApplication. Hinh dươi la giao diên cua SwingApplication:

Sơ đô phân câp:

Khi GUI cua SwingApplication đươc ve, qua trinh đo xay ra như sau:

1. Đôi tương chưa mưc đinh, JFrame, se vê lai no trươc tiên.

2. Cac đôi tương chưa trung gian, trươc hêt la ve lai background, chưa no. Sau đo se la JPane.

3. JPanel trươc hêt se ve lai background, sau đo la đương viên va sau cung la cac thanh phân con chưa trong no.

4. Đê ve lai, JButton ve nên cua no, sau đo la dong văn ban cua chinh no.

5. JLabel ve lai văn ban cua no.

Điêu nay co nghia la, cac thanh phân se ve lai chinh ban thân no trươc khi no điêu khiên cac thanh phân chưa trong no ve lai. Hinh sau đây minh hoa nhưng thanh phân thưa kê tư JComponent va ve lai chinh ban thân no:

1. background (if opaque)

2. custom painting (if any)

3. border (if any)

4. children (if any)

9095883.doc 18

Page 19: 7045244 Creating GUI With JFC Swing

Giao trinh Java

5. Threads and Swing

Nêu lam viêc cac thanh phân ma nhưng thanh phân đo phu thuôc hoăc anh hương đên trang thai cua no, ta cân phai thưc hiên chung trong môt tiên trinh đơn. Tuy nhiên, nhưng chương trinh khac cân sư dung phương thưc invokeLater đê thưc hiên viêc goi ca thanh phân co liên quan trong tiên trinh ây.

Nêu môt chương trinh tao ra va chi lam viêc trên GUI cua chinh no, thi không cân quan tâm vê tiên trinh. Vi du, chương trinh la môt applet, no se đam bao an toan khi lưu câu truc cua no trong phương thưc init. Thâm chi, khi chương trinh la môt ưng dung như dươi đây, thi vân đam bao đươc sư an toan noi trên:

//Thread-safe examplepublic class MyApplication { public static void main(String[] args) {

JFrame f = new JFrame(...); ...//Add components to the frame here...

f.pack();f.setVisible(true);//Don't do any more GUI work here.

}

... //All manipulation of the GUI -- setText, getText, etc. -- //is performed in event handlers such as actionPerformed(). ...}

6. Nhưng tinh năng va khai niêm khac cua Swing

Swing cung câp nhiêu tinh năng. Rât nhiêu tinh năng đươc cung câp bơi JComponent class. Môt vai tinh năng thu vi se không đươc đê câp đên trong bai hoc nay như icons, actions, công nghê Pluggable Look & Feel, assistive technologies, va separate models.

6.1 Nhưng tinh năng cua Jcomponent (Features that JComponent Provides)

9095883.doc 19

Page 20: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Ngoai trư đôi tương chưa mưc đinh, tât ca cac thanh phân khac băt đâu băng ky tư J đêu đươc thưa kê tư lơp Jcomponent. Hâu hêt cac thanh phân đêu co cac tinh năng chung như tooltips va câu hinh vê giao diên (look and feel). Ngoai ra, chung con thưa kê nhiêu phương thưc tiên lơi khac nưa.

6.2 Icons

Nhiêu thanh phân Swing, đăt biêt la button va label, co thê hiên thi hinh anh. Ta co thê chi đinh cho cac hinh anh nay như la cac đôi tương icon

6.3 Actions

Vơi đôi tương Action, Swing API cung câp nhưng hô trơ đăc biêt cho viêc chia xe dư liêu va trang thai giưa hai hoăc nhiêu thanh phân phat ra cac sư kiên hanh đông. Vi du, khi ta co môt button va môt menu item cung môt chưc năng, luc đos cân cân nhăc viêc sư dung đôi tương Action đê xac đinh văn ban, icon va trang thai cua hai thanh phân.

6.4 Support for Assistive Technologies

Assistive technologies such as screen readers can use the Accessibility API to get information from Swing components. Because support for the Accessibility API is built into the Swing components, your Swing program will probably work just fine with assistive technologies, even if you do nothing special. With very little extra effort, however, you can make your program function even more smoothly with assistive technologies, which might well expand its market. See How to Support Assistive Technologies for details.

7. Phân tich môt chương trinh Swing

Bao gôm môt ưng dung nho vê Swing vơi tên goi la Converter se mô ta cach môt chương trinh Swing lam viêc va môi quan hê găn kêt nhau giưa cac đoan ma trong chương trinh.

Converter la môt ưng dung dung đê chuyên đôi đơn vi đo lương giưa hai hê thông met va U.S units. Đê chay đươc ưng dung nay thi phai biên dich cac tâp tin sau: Converter.java, ConversionPanel.java, ConverterRangeModel.java, DecimalField.java, FollowerRangeModel.java,FormattedDocument.java va Unit.java.

Sau đây la hinh anh minh hoa vê giao diên cua Converter:

9095883.doc 20

Page 21: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Trong cac bai hoc sau, chung ta se tim hiêu chi tiêt vê cac tinh năng, khai niêm vê Swing. Chăc chăn se con nhiêu thu vi đang chơ đơi chung ta

9095883.doc 21

Page 22: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bai 3: Sư dung cac tinh năng khac cua Swing

Bai hoc nay hương dân cach sư dung cac tinh năng khac cua Swing.

1. Cach sư dung Actions

Vơi đôi tương Action, ta co thê săp xêp va quan ly cac trang thai cua hai hoăc nhiêu thanh phân tao ra sư kiên cua hanh vi. Vi du, ban co thê sư dung Action đê tao ra va quan ly môt button trên thanh công cu, môt menu biêu tương cung thưc hiên môt chưc năng.

Sau đây la vi du cua viêc sư dung Action đê tao ra môt button trên thanh công cu va môt menu item cung thưc hiên môt chưc năng:

Action leftAction = new <a class that implements Action>(...);JButton button = toolBar.add(leftAction);JMenuItem menuItem = mainMenu.add(leftAction);

Đôi vơi button hay menu item, đê co đươc nhưng hưu ich thưc sư cua viêc sư dung Action, ta phai tao thanh phân sư dung phương thưc add(Action) cua JToolBar, JMenu, hoăc JPopupMenu. Măc đinh, không co ham API nao tôn tai ơ bên trên addActionListener(ActionListener) đê kêt nôi môt Action vơi môt thanh phân khac đang tôn tai thưc sư.

Đê tao môt đôi tương Action, noi chung la ta phai tao môt lơp con cua lơp AbstractAction va thưc thi no. trong lơp con nay, ta cho thưc hiên phương thưc actionPerformed đê tac đông ngươc trơ lai môt cach thoa đang khi hanh vi sư kiên xay ra. Sau đây la vi du cua viêc tao va thưc hiên lơp con cua lơp AbstractAction:

leftAction = new AbstractAction("Go left", new ImageIcon("images/left.gif")) { public void actionPerformed(ActionEvent e) { displayResult("Action for first button/menu item", e); }};

Hinh dươi đây la demo ưng dung cua viêc sư dung Action đê thưc hiên ba tinh năng.

9095883.doc 22

Page 23: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Đây la nhưng gi nhin thây khi menu "Go left" trơ nên disabled:

Đoan ma cua "Go left" action: boolean selected = ...//true if the action should be enabled; //false, otherwiseleftAction.setEnabled(selected);

Sau khi tao ra thanh phân sư dung Action, ta co thê tuy biên chung theo y thich cua minh. Vi du như khi muôn thêm vao dong tooltip cua môt button, hoăc tuy biên viêc xuât hiên hay biên mât cua ca thanh phân băng cach thêm vao , xoa đi cac icon, dong văn ban:

button = toolBar.add(leftAction);button.setText(""); //an icon-only buttonbutton.setToolTipText("This is the left button");menuItem = mainMenu.add(leftAction);menuItem.setIcon(null); //arbitrarily chose not to use icon in menu

The Action API

Bang sau đây liêt kê nhưng phương thưc va contructors thương dung cac Action. Cac ham API sư dung đôi tương Action đươc chia thanh hai loai như sau:

• Tao va sư dung môt Action

• Tao môt thanh phân điêu khiên Action (Action-Controlled Component)

Creating and Using an ActionConstructor or Method PurposeAbstractAction() AbstractAction(String) AbstractAction(String, Icon)

Tao môt đôi tương Action. Thông qua cac tham sô cua phương thưc hay Contructors, co thê xac lâp văn ban hay icon trong thanh phân ây.

void Xac lâp hay nhân biêt ca thanh phân co nhân đươc

9095883.doc 23

Page 24: 7045244 Creating GUI With JFC Swing

Giao trinh Java

setEnabled(boolean) boolean isEnabled()

tac đông hay không. Thông qua phương thưc setEnabled(false), vô hiêu tât ca cac tac đông lên cac thanh phân. Tương tư như vây, sư dung phương thưc setEnabled(true) đê tac đông lai hanh vi cua cac thanh phân.

Creating an Action-Controlled ComponentMethod PurposeJMenuItem add(Action) JMenuItem insert(Action, int) (in JMenu and JPopupMenu)

Tao môt đôi tương JMenuItem va đăt chung vao trong menu hay popup menu.

JButton add(Action) (in JToolBar)

Tao môt đôi tương Jbutton va đăt chung lên thanh công cu.

2. Thê nao la ky thuât hô trơ Assisive(Support Assistive Technologies)

Cac thanh phân Swing hô trơ ky thuât trơ giup. Chương trinh cua ban se đươc hô trơ tôt hơn. Vi du như dong tooltip se hiên lên chưc năng cua môt nut lênh nao đo khi ta di chuyên chuôt lên nut lênh đo.

3. Cach sư dung cac đương viên(Border)

Borders se đem lai cho chung ta nhiêu thuân lơi trong viêc ve cac đương thăng, tiêu đê hay cac vung trông cua môt thanh phân. Trong cac vi du cua phân nay co sư dung rât nhiêu border. Ơ đây, chung ta se tim hiêu cach thêm môt border vao bât ky thanh phân JComponent nao.

4. Cach sư dung Icons

Nhiêu thanh phân Swing co thê hiên thi icons(JLabel va JButton). Thương thi icons la trương hơp ca biêt cua ImageIcon class.

Môt vai thanh phân Swing như JLabel va JButton, co thê đươc trang tri bơi môt icon. Icon la môt đôi tương găn kêt chăt che vơi giao diên Icon. Swing cung câp cho giao diên Icon cach thưc hiên rât đăt biêt va hiêu qua đe ve môt Icon tưg môt tâp tin anh co dang thưc GIF hoăc JPEG.

Hinh dươi đây minh hoa môt ưng dung sư dung môt Icon đê trang tri cho hai label:

9095883.doc 24

Page 25: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Trong phân ma cua chương trinh, câu lênh (1) dung đê tao icon sư dung môt icon, câu lênh (2) va (3) gan icon ây vao trong hai label::

(1) ImageIcon icon = new ImageIcon("images/middle.gif", "a pretty but meaningless splat");...(2) label1 = new JLabel("Image and Text", icon, JLabel.CENTER);...(3) label3 = new JLabel(icon);

Tham sô thư nhât trong ImageIcon constructor xac đinh tâp tin anh đê nap lên, phân nay phai đe y đên đương dân tơi thư muc co chưa tâp tin class. Tham sô thư hai dung đê mô ta vê icon ây, giông như phân tooltip cua cac ưng dung ma chung ta vân thương thây. Noi chung, cac applet nap hinh anh tư may tinh, nơi phuc vu cho applet ây. Co hai ly do đê lam như vây, thư nhât la không tin tương khi đê cac applet đoc cac tâp tin hê thông tư may no đang chay. Thư hai la đê kêt hơp cac lơp cua applet vơi tâp tin dư liêu vơi nhau. Đê nap môt hinh anh tư server, môt applet phai sư dung URL như đoan ma trong vi du dươi đây:

public class SomeClass extends JApplet ... { protected String leftButtonFilename = "images/left.gif"; ... public void init() { ... URL leftButtonURL = getURL(leftButtonFilename); ... leftButtonIcon = new ImageIcon(leftButtonURL, "an arrow pointing left"); ... } ... protected URL getURL(String filename) { URL codeBase = getCodeBase(); URL url = null;

try { url = new URL(codeBase, filename);

9095883.doc 25

Page 26: 7045244 Creating GUI With JFC Swing

Giao trinh Java

} catch (java.net.MalformedURLException e) { System.err.println("Couldn't create image: " + "badly specified URL"); return null; } return url; } ...}

• Vơi môi image icon, no sư dung môt đôi tương image đê đê chưa dư liêu cua hinh anh va đôi tương MediaTracker đươc chia se cho tât ca cac icon trong cung môt chương trinh.

Xac đinh hinh anh nguôn (Specifying the Image Source)

Thương thi dư liêu cua môt hinh anh xuât phat tư môt tâp tin hinh anh. Co thê xac đinh nơi lưu trư cua tâp tin thông qua tên tâp tin hoăc sư dung đôi tương URL. Đôi vơi ưng dung, tên tâp tin hoăc URL đêu co liên quan đên thư muc chưa chưa tâp tin .class cua ưng dung hoăc la đương dân. Đê chi đinh môt URL liên quan đên đương dân cua ưng dung, ta co thê sư dung phương thưc getSystemResource như ơ vi du dươi đây:

ImageIcon icon = null;URL iconURL = ClassLoader.getSystemResource("images/middle.gif");if (iconURL != null) { icon = new ImageIcon(iconURL, "a beautiful yet meaningless icon");}

Phương thưc getSystemResource se do tim trong thư muc va tâp tin JAR trong đương dân cua chương trinh, tra vê URL ngay khi no tim thây. Vi du, khi ta đưa vao đương dân cua ưng dung tâp tin jar co tên icons.jar, nêu tâp tin JAR co chưa images/middle.gif, thi dưat khoat, đương dân se tra vê môt URL xac đinh cho images/middle.gif. Tuy nhiên, co thê la URL đo không co bât cư liên quan nao vê tâp tin icons.jar.

The Image Icon API

9095883.doc 26

Page 27: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bang sau đây liêt kê nhưng câu truc va phương thưc sư dung thông thương cua ImageIcon. constructors and methods. Lưu y la ImageIcon không co nguôn gôc tư JComponent hay thâm chi la tư Component.

Setting, Getting, and Painting the Image Icon's ImageMethod or Constructor

Purpose

ImageIcon() ImageIcon(byte[]) ImageIcon(byte[], String) ImageIcon(Image) ImageIcon(Image, String) ImageIcon(String)

ImageIcon(String, String) ImageIcon(URL) ImageIcon(URL, String)

Tao môt ImageIcon instance, khơi tao no đê chưa hinh anh đa đươc xac lâp. Tham sô thư nhât chi ra nguôn cua hinh anh như image, sô byte, tên tâp tin, hay URL. Tư đo hinh anh se đươc nap lên. Nguôn cua hinh anh phai co dang thưc file đươc hô trơ bơi lơp java.awt.Image co đuôi la GIF hoăc JPEG.

void setImage(Image) Image getImage()

Xac lâp hoăc lây image hiên thi bơi image icon.

void paintIcon(Component, Graphics, int, int)

Ve anh cua icon trong vung đô hoa đa đươc chi đinhPaint the image icon's image in the specified graphics context. You would do this only if you're implementing a custom component that performs its own painting. The Component object is used as an image observer. You can rely on the default behavior provided by Component class and pass in any component. The two int argments specify the x and y coordinates, respectively.

Setting or Getting Information about the Image IconMethod Purposevoid setDescription(String) String getDescription()

Set or get a description of the image. This description is intended for use by assistive technologies.

int getIconWidth()

Get the width or height of the image icon in pixels.

9095883.doc 27

Page 28: 7045244 Creating GUI With JFC Swing

Giao trinh Java

int getIconHeight()Watching the Image Icon's Image LoadMethod Purposevoid setImageObserver(ImageObserver) ImageObserver getImageObserver()

Set or get an image observer for the image icon.

int getImageLoadStatus()Get the loading status of the image icon's image. The set of values returned by this method are defined by MediaTracker.

5. Sư dung tiên trinh(Threads)

Sư dung tiên trinh la môt công viêc kho khăn. Do đo nêu co thê đươc thi ban nên tranh phân nay. Tuy nhiên Thread co thê giup cai tiên chương trinh cua ban băng cach quan ly sư thưc thi.

Nguyên tăc đâu tiên khi sư dung threads la: tranh dung chung nêu như co thê. Threads co thê rât kho sư dung va chung co thê gây kho khăn khi chung ta debug chương trinh. Đê tranh trương hơp bi đinh trê cua chương trinh, cân phai quan tâm ngay tư đâu răng môi tiên trinh đươc tao ra không kêu goi thưc thi bât ky môt thanh phân Swing nao.

Măc du nguy hiêm, nhưng threads rât cso gia tri khi ta sư dung chung môt cach cân thân. Ta co thê cai thiên viêc thưc hiên chương trinh. Đôi khi, môt vai tiên trinh lam đơn gian ma hoăc câu truc cua môt chương trinh. Sau đây la môt vai tinh huông khi sư dung tiên trinh:

• To move a time-consuming initialization task out of the main thread, so that the GUI comes up faster. Examples of time-consuming tasks include making extensive calculations and blocking for network or disk I/O (loading images, for example).

• To move a time-consuming task out of the event-dispatching thread, so that the GUI remains responsive.

• To perform an operation repeatedly, usually with some predetermined period of time between operations.

• To wait for messages from other programs.

Nêu tao môt thread, cân phai tranh nhưng nguy hiêm khi thưc thi môt tiên trinh vơi cac lơp tiên ich như SwingWorker hay Timer. Đôi tương SwingWorker tao môt thread đê thưc thi môt qui trinh xư ly vê thơi gian. Sau khi qui trinh hoan thanh, SwingWorker cung câp môt vai tuy chon đê thưc hiên viêc gưi đi môt sư

9095883.doc 28

Page 29: 7045244 Creating GUI With JFC Swing

Giao trinh Java

kiên. Đôi tương Timer thưc thi môt thread va sinh ra môt hoăc nhiêu hanh vi sư kiên sau khi xac đinh đươc lăp lai.

6. Sư dung Timers

Vơi lơp Timer, ban co thê cho thưc hiên môt tiên trinh cua viêc thưc thi môt hanh đông sau môt khoang thơi gian xac đinh va lăp lai hanh vi ây.

Co hai cach đê thưc hiên Timer:

• Thưc hiên môt tac vu, vơi thơi gian lăp lai đươc xac đinh. Vi du, tool tip manager sư dung timers đê quyêt đinh khi nao thi hiên thi va khi nao thi tăt no đi.

• Thưc hiên viêc lăp đi lăp lai môt tac vu.

Trong vi du dươi đây sư dung đôi tương timer đê thê hiên tiên trinh lam viêc cua môt tac vu.

Va đây la đoan ma cua chương trinh ProgressBarDemo.java. public final static int ONE_SECOND = 1000;...timer = new Timer(ONE_SECOND, new ActionListener() { public void actionPerformed(ActionEvent evt) {

//...Perform a task... } });

Khi user nhân vao nut Start, chương trinh khơi đông timer: timer.start();

Va khi tac vu hoan thanh, action listener cua timer se dưng timer: if (/* task is done */) { ... timer.stop(); ...}

The Timer API

9095883.doc 29

Page 30: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bang sau đây liêt kê nhưng câu truc va phương thưc cua Timer. Cac ham API vê sư dung timers chia thanh hai loai như sau:

• Tao va khơi đông Timer

• Chay môt Timer

Creating and Initializing the TimerMethod or Constructor

Purpose

Timer(int, ActionListener)

Tao môt timer. Tham sô int chi ro thơi gian dưng (milliseconds) giưa hai hanh vi sư kiên. Sư dung setDelay đê thay đôi đô trê. Tham sô thư hai la môt action listener, la môt constructor dung đê nhân biêt vơi môt timer. Ngoai ra, con co thê đăng ky action listeners vơi addActionListener va gơ bo chung băng removeActionlistener.

void setDelay(int) int getDelay()

Xac lâp hoăc lây sô milliseconds.

void setInitialDelay(int) int getInitialDelay()

Xac lâp hoăc lây sô milliseconds chơ trươc khi băt đâu hanh vi sư kiên thư nhât.

void setRepeats(boolean) boolean isRepeats()

Xac lâp hoăc chi ra timer co lăp lai hay không. Măc đinh co gia tri true. Goi setRepeats(false) đê khơi đâu cho môt timer khơi đông va kêt thuc môt hanh.

void setCoalesce(boolean) boolean isCoalesce()

Xac lâp hoăc chi ra timer co liên tuc hay không. Gưi môt hanh vi sư kiên vao môt hanh vi sư kiên đơn. Măc đinh co gai tri true.

Running the TimerMethod Purposevoid start() void restart()

Khơi đông timer. restart con co thê thoat bât ky môt hanh vi sư kiên nao đươc gưi tơi.

void stop() Dưng hoat đông cua môt timer.boolean isRunning() Kiêm tra xem co timer.

9095883.doc 30

Page 31: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bai 4: Bô tri cac thanh phân bên trong cac đôi tương chưa

Bai hoc nay se hương dân ban cach quan ly viêc bay tri ma Java Platform cung câp, cach sư dung vi tri tuyêt đôi.

1. Sư dung Layout Managers

Phân nay cung câp cac qui tăc tông quan va chi tiêt lênh trong viêc sư dung viêc quan ly bô tri ma Java platform cung câp.

a. Sư dung Layout Managers Sư dung BorderLayout

Sau đây la môt Applet cho thây BorderLayout lam viêc như thê nao. setLayout(new BorderLayout());setFont(new Font("Helvetica", Font.PLAIN, 14)); add("North", new Button("North"));add("South", new Button("South"));add("East", new Button("East"));add("West", new Button("West"));add("Center", new Button("Center"));

Quan trong: khi thêm môt thanh phân vao môt Container sư dung BorderLayout, ban nên dung phương thưc add() hai thông sô, va thông sô thư nhât phai la "North", "South", "East", "West", hoăc "Center". Nêu ban sư dung phương thưc add()môt thông sô hay ban không xac lâp thông sô thư nhât thi thanh phân đo se không hiên thi. Theo măc đinh, BorderLayout không đăt khoang trông giưa cac thanh. Muôn vây, ban phai xac lâp no băng cach dung câu truc sau: public BorderLayout(int horizontalGap, int verticalGap)

Sư dung CardLayout Sau đây la môt Applet cho thây CardLayout lam viêc như thê nao.

//Where instance variables are declared:Panel cards;final static String BUTTONPANEL = "Panel with Buttons";final static String TEXTPANEL = "Panel with TextField";

//Where the container is initialized:cards = new Panel();cards.setLayout(new CardLayout()); ...//Create a Panel named p1. Put buttons in it....//Create a Panel named p2. Put a text field in it.

cards.add(BUTTONPANEL, p1);

9095883.doc 31

Page 32: 7045244 Creating GUI With JFC Swing

Giao trinh Java

cards.add(TEXTPANEL, p2);Khi ban thêm môt thanh phân vao môt Container ma co sư dung CardLayout, ban phai sư dung phương thưc add() hai thông sô: add(String name, Component comp). Thông sô thư nhât co thê bât ki chuôi nao đê nhân ra thanh phân đươc thêm vao. Sau đây la môt đoan ma vi du cho phương thưc trên:

//Where the container is initialized:. . . //Put the Choice in a Panel to get a nicer look. Panel cp = new Panel(); Choice c = new Choice(); c.addItem(BUTTONPANEL); c.addItem(TEXTPANEL); cp.add(c); add("North", cp);

. . .

public boolean action(Event evt, Object arg) { if (evt.target instanceof Choice) { ((CardLayout)cards.getLayout()).show(cards,(String)arg); return true; } return false;}

Như đoan ma trên, ban co thê sư dung phương thưc show() cua CardLayout đê xac lâp thanh phân hiên thi hiên tai. Thông sô thư nhât cua phương thưc show() la Container ma CardLayout điêu khiên. thông sô thư hai la chuôi đê xac đinh thanh phân hiên thi. Chuôi nay giông như chuôi cua thanh phân thêm vao Container. Theo sau la tât ca cac phương thưc cua CardLayout ma co thê cho phep chon môt thanh phân. cho môi phương thưc, thông sô thư nhât Container cho CardLayout la môt Layout Manager.

public void first(Container parent)public void next(Container parent)public void previous(Container parent)public void last(Container parent)

public void show(Container parent, String name)Sư dung FlowLayout

Sau đây la môt Applet cho thây FlowLayout hoat đông như thê nao. setLayout(new FlowLayout());setFont(new Font("Helvetica", Font.PLAIN, 14));add(new Button("Button 1"));add(new Button("2"));

9095883.doc 32

Page 33: 7045244 Creating GUI With JFC Swing

Giao trinh Java

add(new Button("Button 3"));add(new Button("Long-Named Button 4"));add(new Button("Button 5"));

Lơp FlowLayout co ba câu truc: public FlowLayout()public FlowLayout(int alignment)public FlowLayout(int alignment, int horizontalGap, int verticalGap)

thông sô alignment phai la cac gia tri FlowLayout.LEFT, FlowLayout.CENTER, hoăc FlowLayout.RIGHT. Thông sô horizontalGap va verticalGap xac đinh sô Pixel đăc giưa cac thanh phân. Nêu ban không xac lâp gia tri nay, FlowLayout se măc đinh gia tri 5 cho môi thông sô.

Sư dung GridLayout Sau đây la môt Aplet cho thây GridLayout lam viêc như thê nao.

//Construct a GridLayout with 2 columns and an unspecified number of rows.setLayout(new GridLayout(0,2));setFont(new Font("Helvetica", Font.PLAIN, 14)); add(new Button("Button 1"));add(new Button("2"));add(new Button("Button 3"));add(new Button("Long-Named Button 4"));add(new Button("Button 5"));

Câu truc trên cho thây lơp GridLayout tao môt đôi tương co hai côt va nhiêu hang. Đây la môt trong hai câu truc cho GridLayout. Sau đây la cach khai bao cho ca hai câu truc nay:

public GridLayout(int rows, int columns)public GridLayout(int rows, int columns, int horizontalGap, int verticalGap)

Sư dung GridBagLayout Theo sau la môt vai đoan lênh tiêu biêu trong môt Container co sư dung GridBagLayout.

GridBagLayout gridbag = new GridBagLayout();GridBagConstraints c = new GridBagConstraints();setLayout(gridbag);

//For each component to be added to this container://...Create the component...//...Set instance variables in the GridBagConstraints instance...gridbag.setConstraints(theComponent, c);add(theComponent);

Ban co thê sư dung lai môt đôi tương cua GridBagConstraints cho nhiêu thanh phân khac nhau, ngay ca khi cac thanh phân đo co sư rang buôc khac nhau.

9095883.doc 33

Page 34: 7045244 Creating GUI With JFC Swing

Giao trinh Java

GridBagLayout rut ra môt gia tri rang buôc va không dung lai GridBagConstraints. Ban phai cân thân, tuy nhiên, đê khơi tao lai gia tri cua môt đôi tương GridBagConstraints lam gia tri măc đinh khi cân thiêt. Ban co thê xac lâp cac gia tri sau: gridx, gridy Xac đinh hang va côt tai vi tri trên bên tai cua thanh phân. Hâu hêt côt trên bên tai co đic chi gridx=0, va hang trên cung co đia chi gridy=0. Sư dung GridBagConstraints.RELATIVE (gia tri măc đinh) đê xac đinh răng thanh phân đo chi ơ bên phai hay ơ phia dươi. gridwidth, gridheight xac lâp sô côt hoăc sô hang trong vung hiên thi cua thanh phân. nhưng gia tri nay xac đinh sô Cell ma thanh phân sư dung, không phai sô Pixel no sư dung. Măc đinh la 1. Sư dung GridBagConstraints.REMAINDER đê xac đinh thanh phân đang ơ hang cuôi cung hay côt cuôi cung. Sư dung GridBagConstraints.RELATIVE đê xac đinh bươc kê tiêp cua thanh phân la hang cuôi hay côt cuôi cung. fill Đươc sư dung khi vung hiên thi cua thanh phân lơn hơn kich thươc thanh phân đoi hoi đê quyêt đinh khi nao hoăc thay đôi kich thươc như thê nao. cac gia tri thich hơp la GridBagConstraints.NONE (măc đinh), GridBagConstraints.HORIZONTAL, GridBagConstraints.VERTICAL va GridBagConstraints.BOTH.ipadx, ipady xac đinh phân phu ơ bên trong: bao nhiêu đê thêm vao kich thươc tôi thiêu cua thanh phân. gia tri măc đinh la 0. Chiêu rông cua thanh phân tôi thiêu nhât la băng chiêu rông tôi thiêu cua no công vơi ipadx*2. Similarly, chiêu cao cua thanh phân tôi thiêu nhât la băng chiêu cao tôi thiêu cua no công vơi ipady*2. insets xac đinh phân phu bên ngoai cua thanh phân. măc đinh, môi thanh phân không co phân phu bên ngoai. anchor đươc sư dung khi thanh phân nho hơn vung hiên thi đê quyêt đinh khi nao đăt thanh phân. gai tri thich hơp la GridBagConstraints.CENTER (măc đinh), GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST, GridBagConstraints.EAST, GridBagConstraints.SOUTHEAST, GridBagConstraints.SOUTH, GridBagConstraints.SOUTHWEST, GridBagConstraints.WEST, va GridBagConstraints.NORTHWEST. Vi du :Sau đây la môt Applet chi cho thây GridBagLayout hoat đông như thê nao. Sau đây la môt đoan lênh tao môt GridBagLayout va cac thanh phân no quan li

protected void makebutton(String name, GridBagLayout gridbag, GridBagConstraints c) { Button button = new Button(name);

9095883.doc 34

Page 35: 7045244 Creating GUI With JFC Swing

Giao trinh Java

gridbag.setConstraints(button, c); add(button);}

public GridBagWindow() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); setFont(new Font("Helvetica", Font.PLAIN, 14)); setLayout(gridbag); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; makebutton("Button1", gridbag, c); makebutton("Button2", gridbag, c); makebutton("Button3", gridbag, c);

c.gridwidth = GridBagConstraints.REMAINDER; //end of row makebutton("Button4", gridbag, c);

c.weightx = 0.0; //reset to the default makebutton("Button5", gridbag, c); //another row

c.gridwidth = GridBagConstraints.RELATIVE; //next to last in row makebutton("Button6", gridbag, c);

c.gridwidth = GridBagConstraints.REMAINDER; //end of row makebutton("Button7", gridbag, c);

c.gridwidth = 1; //reset to the default c.gridheight = 2; c.weighty = 1.0; makebutton("Button8", gridbag, c);

c.weighty = 0.0; //reset to the default c.gridwidth = GridBagConstraints.REMAINDER; //end of row c.gridheight = 1; //reset to the default makebutton("Button9", gridbag, c); makebutton("Button10", gridbag, c);}

9095883.doc 35

Page 36: 7045244 Creating GUI With JFC Swing

Giao trinh Java

2. Tao môt Custom Layout Manager

Thay vi sư dung cach quan ly ma Java platform cung câp, ta co thê viêt môt chương trinh quan ly cua chinh minh. Quan ly bô tri phai thưc thi LayoutManager interface, nơi chi đinh năm phương thưc phai đươc đinh nghia. Viêc quan ly cach bô tri co thê thưc thi LayoutManager2, la môt giao diên con cua LayoutManager.

Năm phương thưc đươc thưc thi la:

(1) void addLayoutComponent(String, Component) (2)void removeLayoutComponent(Component) (3)Dimension preferredLayoutSize(Container) (4)Dimension minimumLayoutSize(Container) (5)void layoutContainer(Container)

public void addLayoutComponent(String name, Component comp) Chi đươc goi băng phương thưc add(name, component) cua Container. public void removeLayoutComponent(Component comp) Goi bơi nhưng phương thưc remove() va removeAll() cua Container.public Dimension preferredLayoutSize(Container parent) Goi bơi phương thưc preferredSize() cua Container, co thê tư goi dươi moi tinh huông. public Dimension minimumLayoutSize(Container parent) Goi bơi phương thưc minimumSize() cua Container, co thê tư goi dươi moi tinh huông. public void layoutContainer(Container parent) Goi khi Container hiên thi lân đâuis first displayed, va moi luc no tahy đôi kich thươc.

3. Lam viêc không co Layout Manager(Absolute Positioning)

If necessary, you can position components without using a layout manager. Generally, this solution is used to specify absolute sizes and positions for components.

Măc du co thê lam viêc ma không cân Layout Manager, ban nên dung Layout Manager nêu co thê. Layout managers dê thay đôi kich thươc cua Container va điêu chinh hinh dang cua cac thanh phân phu thuôc vao Platform. No cung co thê đươc sư dung la bơi cac Container va cac chương trinh khac. nêu Custom Container se không tai sư dung, không thê thay đôi kich thươc, va hoan toan co thê điêu khiên đươc cac thông sô phu thuôc vao hê thông như Font va hinh dang cac thanh phân. Vi du:

public class NoneWindow extends Frame { . . .

9095883.doc 36

Page 37: 7045244 Creating GUI With JFC Swing

Giao trinh Java

private boolean laidOut = false; private Button b1, b2, b3;

public NoneWindow() { super(); setLayout(null); setFont(new Font("Helvetica", Font.PLAIN, 14));

b1 = new Button("one"); add(b1); b2 = new Button("two"); add(b2); b3 = new Button("three"); add(b3); }

public void paint(Graphics g) { if (!laidOut) { Insets insets = insets(); /*

* We're guaranteed that insets() will return a valid Insets * if called from paint() -- it isn't valid when called from * the constructor.

* * We could perhaps cache this in an ivar, but insets can

* change, and when they do, the AWT creates a whole new

* Insets object; the old one is invalid. */

b1.reshape(50 + insets.left, 5 + insets.top, 50, 20); b2.reshape(70 + insets.left, 35 + insets.top, 50, 20); b3.reshape(130 + insets.left, 15 + insets.top, 50, 30);

laidOut = true; } } . . .

}

9095883.doc 37

Page 38: 7045244 Creating GUI With JFC Swing

Giao trinh Java

4. Giai quyêt cac vân đê vê Layout

Môt vai vân đê thông thương vê layout ma thương la cac thanh phân hiên thi qua nho hoăc không hiên thi. Trong phân nay se giup chung ta xư ly nhưng vân đê nay.

Bai toan: Lam thê nao đê xac đinh đươc chinh xac kich thươc cua môt thanh phân?

• Đâu tiên, chăc chăn ban thât sư muôn xac lâp kich thươc chinh xac cua thanh phân. nhưng thanh phân chuân co kich thươc khac nhau, phu thuôc vao Platform ma thanh phân đo đang chay va Font no sư dung, vi vây thwongf chi lam theo cam giac đê xac đinh kich thươc chinh xac cua cac thanh phân. Đôi vơi nhưng Custom Component co kich thươc xac đinh, xac đinh kich thươc chinh xac chi la cam giac chu quan. Ban cân bo qua cac phương thưc minimumSize() va preferredSize() cua thanh phân đê tra vê môt kich thươc đung cho thanh phân đo. Đê thay đôi kich thươc cua thanh phân khi thanh phân đo đang hiên thi, xem bai toan tiêp theo.

Bai toan: Lam thê nao đê thay đôi kich thươc cua môt thanh phân? • Môt khi thanh phân đa hiên thi, ban co thê thay đôi kich thươc cua no

băng phương thưc resize(). Rôi ban goi phương thưc validate() đê Container ve lai.

Bai toan: Thanh phân đang co kich thươc qua nho. • Thanh phân đo co thưc thi nhưng phương thưc preferredSize() va

minimumSize() hay không? Nêu vây, no co tra vê gia tri đung hay không?

• Khi ba dung Layout manager, ban co thê dung không gian săn co hay không?

Bai 5: Viêt sư kiên Listeners

Trong bai hoc nay se trinh bay môt cach chi tiêt đê lam thê nao viêt môt sư kiên listeners. Đê hiêu phân nay thi ban phai co kiên thưc vê Event Handling.

1. Môt vai vi du vê Event-Handling

Cac applets trong phân nay se minh hoa cho cac sư kiên va qua trinh tiên hanh cua sư kiên.

2. Tông quan vê Writing Event Listeners

Cung câp thông tin cân thiêt vê tât ca cac kiêu cua sư kiên. Môt trong nhưng tiêu đê trong phân nay la trinh bay cach lam sao đê giam bơt công sưc va sư không cân thiêt cua viêc viêt code cho chương trinh băng cach sư dung cac lơp trong đê thưc thi cac sư kiên.

9095883.doc 38

Page 39: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Đê co thê năm băt phân nay môt cach dê dang, xem như ban đa co nhưng kiên thưc cơ ban vê cac sư kiên listener trong phân Event Handling. Chăng han như ta co thê găn môt đa listeners vao nguôn cua môt đơn sư kiên. Nhưng quan trong hơn hêt la cac phương thưc event-listener se đươc xư ly môt cach nhanh chong. Bơi vi tât ca cac event-handling va cac phương thưc ve đêu đươc thưc hiên trong cung môt tiên trinh.

Trong phân nay, chung ta se ban vê EventObject, môt lơp con cho tât ca cac sư kiên AWT va Swing

Lây thông tin sư kiên: Event Objects (Getting Event Information: Event Objects)

Môi môt phương thưc event-listener đêu co môt đôi sô đơn, môt đôi tương thưa kê tư lơp EventObject. method has a single argument -- an object that inherits from the EventObject class. Măc du đôi sô luôn xuât phat tư EventObject, vơi kiêu tông quan đê co thê thưc hiên chinh xac hơn. Vi du như khi năm băt sư kiên cua chuôt, đôi sô cho phương thưc nay se lây tư MouseEvent, môt lơp con cua EventObject.

Lơp EventObject đinh nghia môt phương thưc rât hưu ich như sau:

Object getSource() Phương thưc nay tra vê môt đôi tương năm băt sư kiên. Chu y răng phương thưc getSource cung tra vê môt đôi tương. Lơp Event đôi khi cung đinh nghia môt phương thưc giông như getSource, nhưng kiêu cua gia tri tra vê hơi bi han chê. Vi du như lơp ComponentEvent đinh nghia phương thưc getComponent, giông như getSource, tra vê đôi tương năm băt sư kiên. Cai khac nhau ơ đây la getComponent luôn luôn tra vê môt Component. Thương thi môt lơp sư kiên nao đo đinh nghia môt phương thưc va tra vê thông tin cua sư kiên.

Khai niêm: Low-Level Events and Semantic Events

Cac sư kiên co thê đươc phân chia thanh 2 loai: low-level events va semantic events. Low-level events mô ta window-system xay ra hoăc dư liêu vao ơ mưc thâp (low-level input). Tât ca cac sư kiên con lai thuôc loai semantic event.

Sư kiên mouse va key, ca hai đêu la kêt qua trưc tiêp tư phia ngươi dung, la nhưng sư kiên low-level. Nhưng sư kiên low-level khac bao gôm component, container, focus, va window events. Sư kiên component cho phep thay đôi vi tri, kich thươc va sư hiên thi cua thanh phân. Sư kiên container quan ly đê năm băt đươc thanh phân nao khi đươc thêm vao hay gơ bo khoi cac đôi tương chưa. Focus events se bao cho biêt khi nao môt thanh phân la co hoăc không keyboard focus, kha năng nhân biêt ky tư đươc go tai ban phim. Window

9095883.doc 39

Page 40: 7045244 Creating GUI With JFC Swing

Giao trinh Java

events giup đê năm băt nhưng trang thai căn ban nhât cua bât ky Window nao, chăng han như Dialog hay môt Frame.

Semantic events bao gôm action events, item events, va list selection events. Hanh đông cua môi semantic event co thê khac nhau do thanh phân. Vi du như môt button co thê năm băt sư kiên khi ngươi dung kich chuôt lên no. Nhưng môt text field năm băt sư kiên khi ngươi dung nhân Return.

Sư dung Adapters and Inner Classes đê năm băt cac sư kiên

Phân nay hương dân ban sư dung cac lơp adapters va inner đê lam giam bơt sư lôn xôn trong đoan ma cua chương trinh ban. Hâu hêt cac giao diên AWT listener, không như ActionListener, chưa nhiêu hoăc môt phương thưc. Vi du, giao diên MouseListener chưa năm phương thưc: mousePressed, mouseReleased, mouseEntered, mouseExited, va mouseClicked. Du la ban chi quan tâm vê nhân chuôt, nêu lơp ban đang sư dung thưc thi MouseListener thi ban phai thưc thi tât ca 5 phương thưc.Vi du :

//An example with cluttered but valid code.public class MyClass implements MouseListener { ...

someObject.addMouseListener(this); ... /* Empty method definition. */ public void mousePressed(MouseEvent e) { }

/* Empty method definition. */ public void mouseReleased(MouseEvent e) { }

/* Empty method definition. */ public void mouseEntered(MouseEvent e) { }

/* Empty method definition. */ public void mouseExited(MouseEvent e) { }

public void mouseClicked(MouseEvent e) {...//Event handler implementation goes here...

}}Đang tiêc la kêt qua cua sư lưa chon cac phương thưc rông co thê kho đoc va duy tri. Đê giup ban tranh đươc cac lôn xôn vơi nhưng phương thưc rông trong chương trinh,

9095883.doc 40

Page 41: 7045244 Creating GUI With JFC Swing

Giao trinh Java

AWT cung câp lơp adapter class cho môi listener interface vơi nhiêu hơn môt phương thưc. Đê sư dung adapter, ban tao môt lơp con cho no, thay vi phai thưc thi môt listener interface.

/* * An example of extending an adapter class instead of * directly implementing a listener interface. */public class MyClass extends MouseAdapter { ...

someObject.addMouseListener(this); ... public void mouseClicked(MouseEvent e) {

...//Event handler implementation goes here... }}

Gia du ban muôn viêt môt applet, va ban muôn Applet cua ban chưa vai đoan ma đê năm băt cac sư kiên cua chuôt. Tư khi ngôn ngư Java khhong cho phep đa thưa kê thi ban không thê mơ rông ca 2 lơp Applet and MouseAdapter. Giai phap la đinh nghia môt lơp inner -- môt lơp năm trong Aplet -- that extends the MouseAdapter class,

//An example of using an inner class.public class MyClass extends Applet { ...

someObject.addMouseListener(new MyAdapter()); ... class MyAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) {

...//Event handler implementation goes here... } }

}

3. Hô trơ Listeners cua cac thanh phân Swing

Co thê noi răng loai cua sư kiên môt thanh phân co thê đươc phân loai băng cach dưa vao loai cua sư kiên listeners ma ta đăng ky trên thanh phân đo. Vi du như lơp Component đinh nghia nhýÞng phương thưc listener nhý sau:

• addComponentListener

• addFocusListener

• addKeyListener

• addMouseListener

• addMouseMotionListener

9095883.doc 41

Page 42: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Do vây, môi thanh phân hô trơ component, focus, key, mouse, va mouse-motion listeners. Tuy nhiên, môt thanh phân khơi đông nhưng sư kiên ma listeners co đăngky trên no. Vi du, môt mouse listener đươc đăng ky trên môt thanh phân riêng biêt, nhưng thanh phân ây không co listeners khac, thi thanh phân đo se khơi đông chi môi sư kiên mouse events, không co cac sư kiên component, focus, key, or mouse-motion.

Listeners that All Swing Components Support

Vi tât ca cac thanh phân Swing đêu xuât phat tư lơp AWT Component, cho nên ta phai khai bao nhưng listeners sau trên bât ky thanh phân Swing nao:

component listener Năm băt sư thay đôi vê kich thươc, vi tri va sư hiên thi cua thanh phân. focus listener Năm băt cac thanh phân co nhân hay không tac đông tư ban phim. key listener Năm băt đông tac ân phim; sư kiên key chi khơi tao bơi cac thanh phân đang co trang thai măc đinh cua ban phim. mouse events Năm băt sư kiên kich chuôt va di chuyên chuôt trên thanh phân. mouse-motion events Năm băt sư thay đôi vê vi tri cua con tro trên thanh phân.

Cac Listeners khac ma cac thanh phân Swing hô trơ

Bang sau đây liêt kê cac thanh phân Swing va listeners đươc hô trơ. Trong nhiêu trương hơp, cac sư kiên đươc khơi đông trưc tiêp tư thanh phân. Nhưng trương hơp khac, cac sư kiên đươc khơi đông tư dư liêu cua thanh phân hoăc tư cac kiêu mâu đươc chon.

Component

Listener

action caret change

document,undoable edit

item listselection

window

other

button X X X check box X X X color chooser X combo box X X dialog X

editor pane X X

hyperlink

file chooser X frame X internal frame inte

9095883.doc 42

Page 43: 7045244 Creating GUI With JFC Swing

Giao trinh Java

rnal frame

list X list data

menu menu

menu item X X X

menu key

menu drag mouse

option pane password field X X X

popup menu

popup menu

progress bar X radio button X X X slider X tabbed pane X

table X

table model table column model

cell editor

9095883.doc 43

Page 44: 7045244 Creating GUI With JFC Swing

Giao trinh Java

text area X X text field X X X

text pane X X

hyperlink

toggle button X X X

tree

tree expansion tree will expand tree model tree selection

viewport (used by scrollpane)

X

4. Thưc hiên Listeners cho cac Handled Events thông thương

Phân nay sa bao gôm cac chi tiêt vê vi du va thông tin cua viêc viêt nhưng sư kiên listener thông thương.

Viêt môt Action Listener Khi ngươi sư dung kich chuôt vao Button, đup chuôt vao ListItem, chon MenuItem, hoăc nhân phim trong TextField, môt sư kiên se xay ra. Kêt qua đo la môt thông bao actionPerformed đươc gơi đi đên tât ca cac action listener va no đăng ki vơi cac thanh phân co liên quan.Cac phương thưc, sư kiên cua hanh đôngGiao diên ActionListener chưa môt phương thưc đơn, va do đo no không co lơp adapter tương ưng. Đây la phương thưc ActionListener cô đôc: void actionPerformed(ActionEvent) Môt vi du vê năm băt cac sư kiên cua hanh đông Môt vi du đơn gianpublic class Beeper ... implements ActionListener { ... //where initialization occurs:

9095883.doc 44

Page 45: 7045244 Creating GUI With JFC Swing

Giao trinh Java

button.addActionListener(this); ... public void actionPerformed(ActionEvent e) {

...//Make a beep sound... }}

Viêt môt Adjustment Listener Các sự kiện Adjustment thông báo cho bạn biết sự thay đổi giá trị trong các thành phần. Đối tượng Adjustable có một giá trị nguyên, và nó trả về các các sự kiện adjustment bất cứ khi nào giá trị đó thay đổi. Chỉ có một lớp của AWT thực thi Adjustable là lớp Scrollbar. Có 5 loại sự kiện adjustment:track người sử dụng hoàn toàn thay đổi giá trị của thành phần. unit increment, unit decrement người sử dụng chỉ biểu thị sự thay đổi nhỏ về giá trị của thành phần. block increment, block decrement người sử dụng biểu thị sự thay đổi giá trị của thành phần với số lượng lớn.Cac phương thưc sư kiên cua AdjustmentGiao diện Adjustment Listener chứa một phương thức đơn, và vì thế nó không có lớp mô phỏng tương ứng. Sau đây là phương thức đó: void adjustmentValueChanged(AdjustmentEvent) Được gọi bởi AWT vừa sau khi thay đổi giá trị của thành phần.Vi du vê Handling Adjustment Events class ConversionPanel ... implements AdjustmentListener ... { ... Scrollbar slider; ... ConversionPanel(...) { ... slider.addAdjustmentListener(this); } ... /** Respond to the slider. */ public void adjustmentValueChanged(AdjustmentEvent e) { textField.setText(String.valueOf(e.getValue())); controller.convert(this); } ...}Lơp AdjustmentEvent

Phương thức adjustmentValueChanged có một thông số: một đối tượng AdjustmentEvent. Lớp AdjustmentEvent định nghĩa các phương thức sau: Adjustable getAdjustable()

9095883.doc 45

Page 46: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Trả về thành phần mà sinh ra sự kiện đó. Bạn có thể dùng nó thay vì dùng phương thức getSource. int getAdjustmentType() Trả về kiểu của adjustment được tìm thấy. giá trị trả về là một trong những giá trị sau được định nghĩa trong lớp AdjustmentEvent: UNIT_INCREMENT, UNIT_DECREMENT, BLOCK_INCREMENT, BLOCK_DECREMENT, TRACK. int getValue() Trả về giá trị của thành phần ngay sau khi adjustment được tìm thấy.Viêt môt Component Listener là một trong những sự kịen của thành phần được phát ra bởi đối tượng Component ngay sau khi thành phần đó mất đi, làm ẩn đi, chuyển vị trí hoặc thay đổi kích thướcCac phương thưc, sư kiên cua thanh phânGiao diện ComponentListener và lớp mô phỏng tương ứng, ComponentAdapter, chứa 4 phương thức:void componentHidden(ComponentEvent) được gọi bởi AWT sau khi thành phần biến mất bởi phương thức setVisible. void componentMoved(ComponentEvent) được gọi bởi AWT sau khi thành phần di chuyển, nó quan hệ với đối tượng chứa nó. void componentResized(ComponentEvent) được gọi bởi AWT sau khi thành phần thay đổi kích thước. void componentShown(ComponentEvent) được gọi bởi AWT sau khi thành phần xuất hiện bởi phương thức setVisible.Ví dụ về Handling Component Eventspublic class ComponentEventDemo ... implements ComponentListener { ... //where initialization occurs: aFrame = new Frame("A Frame"); ComponentPanel p = new ComponentPanel(this); aFrame.addComponentListener(this); p.addComponentListener(this); ...

public void componentHidden(ComponentEvent e) {displayMessage("componentHidden event from "

+ e.getComponent().getClass().getName()); }

public void componentMoved(ComponentEvent e) {displayMessage("componentMoved event from "

+ e.getComponent().getClass().getName()); }

public void componentResized(ComponentEvent e) {displayMessage("componentResized event from "

+ e.getComponent().getClass().getName());

9095883.doc 46

Page 47: 7045244 Creating GUI With JFC Swing

Giao trinh Java

}

public void componentShown(ComponentEvent e) {displayMessage("componentShown event from "

+ e.getComponent().getClass().getName()); }}

class ComponentPanel extends Panel ... { ... ComponentPanel(ComponentEventDemo listener) { ...//after creating the label and checkbox: label.addComponentListener(listener); checkbox.addComponentListener(listener); } ...}Lơp ComponentEvent Mỗi một phương thức của sự kiện các thành phần có một thông số đơn: đối tượng ComponentEvent lớp ComponentEvent định nghĩa một phương thức hay dùng, getComponent, trả về thành phần mà phát ra sự kiện.Viêt môt Container Listener Nhưng sư kiên cua Container đươc phat ra ngay sau khi môt thanh phân đươc thêm vao Container hoăc chuyên đi khoi Container.Cac phương thưc, sư kiên cua ContainerGiao diên ContainerListener va lơp mô phong tương ưng, ContainerAdapter chưa hai phương thưc: void componentAdded(ContainerEvent) đươc goi sau khi môt thanh phân đươc thêm vao Container. void componentRemoved(ContainerEvent) đươc goi sau khi môt thanh phân đươc chuyên đi khoi Container.Vi du vê Handling Container Eventspublic class ContainerEventDemo ... implements ContainerListener ... { ...//where initialization occurs:

buttonPanel = new Panel();buttonPanel.addContainerListener(this);

... public void componentAdded(ContainerEvent e) {

displayMessage(" added to ", e); }

public void componentRemoved(ContainerEvent e) {displayMessage(" removed from ", e);

}

9095883.doc 47

Page 48: 7045244 Creating GUI With JFC Swing

Giao trinh Java

void displayMessage(String action, ContainerEvent e) {display.append(((Button)e.getChild()).getLabel()

+ " was" + action + e.getContainer().getClass().getName() + "\n");

} ...}Lơp ContainerEventMôi phương thưc cua Container Event co môt thông sô đơn: đôi tương ContainerEvent. Lơp ContainerEvent đinh nghia hai phương thưc thương dung sau: Component getChild() Tra vê thanh phân đươc thêm hay chuyên khoi Container trong sư kiên nay. Container getContainer() Tar vê Container sinh ra sư kiên nay.Viêt môt Focus Listener Cac sư kiên Focus đươc phat ra khi môt thanh phân co hoăc mât đi sư tâp trung vao no. Cac phương thưc, sư kiên cua FocusGaio diên FocusListener va lơp mô phong tương ưng, FocusAdapter, chưa hai phương thưc: void focusGained(FocusEvent) đươc goi sau khi thanh phân co sư tâp trung. void focusLost(FocusEvent) đươc goi sau khi thanh phân mât sư tâp trung.Vi du vê Handling Focus Eventspublic class FocusEventDemo ... implements FocusListener ... {

...//where initialization occurswindow = new FocusWindow(this);

... public void focusGained(FocusEvent e) {

displayMessage("Focus gained", e); }

public void focusLost(FocusEvent e) {displayMessage("Focus lost", e);

}

void displayMessage(String prefix, FocusEvent e) {display.append(prefix

+ ": " + e.getSource() //XXX

9095883.doc 48

Page 49: 7045244 Creating GUI With JFC Swing

Giao trinh Java

+ "\n"); } ...}

class FocusWindow extends Frame { ... public FocusWindow(FocusListener listener) {

super("Focus Demo Window");this.addFocusListener(listener);...Label label = new Label("A Label");label.addFocusListener(listener);...Choice choice = new Choice();...choice.addFocusListener(listener);...Button button = new Button("A Button");button.addFocusListener(listener);...List list = new List();...list.addFocusListener(listener);

}}Lơp FocusEventMôi phương thưc Focus Event co môt thông sô đơn : đôi tương FocusEvent. Lơp FocusEvent đinh nghia môt phương thưc, isTemporary, tra vê gia tri True khi sư kiên mât sư tâp trung đo la tam thơi.Moi thông bao thông thương ma ban gơi tơi đôi tương FocusEvent la getComponent (đươc đinh nghia trong ComponentEvent), no tra vê thanh phân gây ra sư kiên nay.Viêt môt Item Listener Cac sư kiên cua Item đươc phat ra khi thưc thi giao diên ItemSelectable.Cac phương thưc, sư kiên cua ItemGiao diên ItemListener vhi co môt phương thưc, vi vây no không co lơp mô phong tương ưng: void itemStateChanged(ItemEvent) đươc goi sau khi thay đôi trang thai cua thanh phân.Vi du vê Handling Item Eventspublic void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { label.setVisible(true); } else {

9095883.doc 49

Page 50: 7045244 Creating GUI With JFC Swing

Giao trinh Java

label.setVisible(false); }}Lơp ItemEventMôi phương thưc cua Item event co môt thông sô đơn: đôi tương ItemEvent. Lơp ItemEvent đinh nghia cac phương thưc sau: Object getItem() Tra vê Item đơc tâp trung trong sư kiên nay. ItemSelectable getItemSelectable() Tar vê thanh phân phat ra sư kiên. int getStateChange() tra vê trang thai mơi cua Item. Lơp ItemEvent đinh nghia hai trang thai: SELECTED va DESELECTED.Viêt môt Key Listener Đưoc phat ra khi ngươi sư dung đanh phim. Đăc biêt Key events phat ra bơi đôi tương ma dang đươc tâp trung khi ngươi dung nhân hoăc nha phim.Cac phương thưc sư kiên cua KeyGiao diên KeyListener va lơp mô phong tương ưng, KeyAdapter, chưa ba phương thưc: void keyTyped(KeyEvent) đưoc goi sau khi phim đưoc đanh. void keyPressed(KeyEvent) đươc goi sau khi môt phim đươc ân. void keyReleased(KeyEvent) đươc goi sau khi môt phim đươc nha.Vi du vê Handling Key Eventspublic class KeyEventDemo ... implements KeyListener ... { ...//where initialization occurs:

typingArea = new TextField(20);typingArea.addKeyListener(this);

... /** Handle the key typed event from the text field. */ public void keyTyped(KeyEvent e) {

displayInfo(e, "KEY TYPED: "); }

/** Handle the key pressed event from the text field. */ public void keyPressed(KeyEvent e) {

displayInfo(e, "KEY PRESSED: "); }

/** Handle the key released event from the text field. */ public void keyReleased(KeyEvent e) {

displayInfo(e, "KEY RELEASED: "); }

9095883.doc 50

Page 51: 7045244 Creating GUI With JFC Swing

Giao trinh Java

... protected void displayInfo(KeyEvent e, String s){

...char c = e.getKeyChar();int keyCode = e.getKeyCode();int modifiers = e.getModifiers();...tmpString = KeyEvent.getKeyModifiersText(modifiers);

...//display information about the KeyEvent... }}Lơp KeyEventMôi phương thưc Key Event co môt thông sô đơn: đôi tương KeyEvent. Lơp KeyEvent đinh nghianhưng phương thưc thương dung sau: int getKeyChar() void setKeyChar(char) Nhân hoăc xac lâp ki tư liên quan vơi sư kiên nay. int getKeyCode() void setKeyCode(int) nhân hoăc xac lâp ma cua phim liên quan vơi sư kiên nay. void setModifiers(int) xac lâp tang thai cua phim liên quan tơi sư kiên nay int getModifiers() Ta vê trang thai cua phim trong sư kiên nay.Viêt môt Mouse Listener Cac sư kiên đươc phat ra khi ngươi sư dung dung chuôt tac đông đên môt thanh phân.Cac phương thưc, sư kiên cua MouseGiao diên MouseListener va lơp mô phong tương ưng, MouseAdapter, chưa ba phương thưc: void mouseClicked(MouseEvent) đươc goi sau nkhi ngươi sư dung kich hoat chuôt vao môt thanh phân. void mouseEntered(MouseEvent) đươc goi sau khi con tro chuôt năm trong đia phân cua thanh phân. void mouseExited(MouseEvent) đươc goi sau khi con tro chuôt ra khoi đia phân cua thanh phân. void mousePressed(MouseEvent) đươc goi sau khi con chuôt đươc ân trên đia phân cua thanh phân. void mouseReleased(MouseEvent) đươc goi sau khi con chuôt đươc nha trên đia phân cua thanh phân. Vi du vê Handling Mouse Eventspublic class MouseEventDemo ... implements MouseListener {

...//where initialization occurs: //Register for mouse events on blankArea and applet (panel). blankArea.addMouseListener(this);

9095883.doc 51

Page 52: 7045244 Creating GUI With JFC Swing

Giao trinh Java

addMouseListener(this); ...

public void mousePressed(MouseEvent e) { saySomething("Mouse button press", e); }

public void mouseReleased(MouseEvent e) { saySomething("Mouse button release", e); }

public void mouseEntered(MouseEvent e) { saySomething("Cursor enter", e); }

public void mouseExited(MouseEvent e) { saySomething("Cursor exit", e); }

public void mouseClicked(MouseEvent e) { saySomething("Mouse button click", e); }

void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + ".\n"); textArea.setCaretPosition(maxInt); //scroll to bottom }}Lơp MouseEventMôi phương thưc Mouse Event co môt thông sô đơn: đôi tương MouseEvent. Lơp MouseEvent đinh nghia cac phương thưc thương dung sau: int getClickCount() tra vê sô lân nhân liên tiêp cua ngươi sư dung. int getX() int getY() Point getPoint() Tra vê vi tri cua con tro tro chuôt, vi tri nay phu thuôc vao thanh phân. boolean isPopupTrigger() tra vê gia tri True khi sư kiên nay lam xuât hiên Popup Menu.Viêt môt Mouse Motion Listener Cac sư kiên Mouse motion phat ra ki ngươi sư dung dung chuôt di chuyên trên man hinh.

9095883.doc 52

Page 53: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Cac phương thưc, sư kiên cua Mouse MotionGiao diên MouseMotionListener va lơp mô phong tương ưng, MouseMotionAdapter, chưa hai phương thưc: void mouseDragged(MouseEvent) đươc goi sau khi ngươi sư dung di chuyên chuôt trong khi chuôt đang đươc nhân. void mouseMoved(MouseEvent) đươc goi sau khi ngươi sư dung di chuyên chuôt khi con chuôt chưa bi nhân.Vi du vê Handling Mouse Motion Events...//where initialization occurs: MyListener myListener = new MyListener(); addMouseListener(myListener); addMouseMotionListener(myListener);...class MyListener extends MouseAdapter implements MouseMotionListener { public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); currentRect = new Rectangle(x, y, 0, 0); repaint(); }

public void mouseDragged(MouseEvent e) { updateSize(e); }

public void mouseMoved(MouseEvent e) { //Do nothing. }

public void mouseReleased(MouseEvent e) { updateSize(e); }

void updateSize(MouseEvent e) { int x = e.getX(); int y = e.getY(); currentRect.setSize(x - currentRect.x, y - currentRect.y); repaint(); }}

9095883.doc 53

Page 54: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Cac phương thưc, sư kiên đươc sư dung bơi Mouse-Motion ListenersMôi phương thưc Mouse Motion Event co môt thông sô đơn, va no không đơc goi la MouseMotionEvent! Thay vao đo, phương thưc Mouse Motion Event sư dung đôi tương MouseEvent.Viêt môt Text Listener Cac sư kiên Text tra vê sau khi chuôi trong thanh phân Text co sư thay đôi.Cac phương thưc, sư kiên cua TextGiao diên TextListener chi co môt phương thưc nên không co lơp mô phong tương ưng: void textValueChanged(TextEvent) đươc goi sau khi chuôi trong thanh phân Text thay đôi.Examples of Handling Text Eventspublic class TextEventDemo ... { TextField textField; TextArea textArea; TextArea displayArea; ... //where initialization occurs:

textField = new TextField(20);...textField.addTextListener(new MyTextListener("Text Field"));

textArea = new TextArea(5, 20);textArea.addTextListener(new MyTextListener("Text Area"));...

}

class MyTextListener implements TextListener {String preface;

public MyTextListener(String source) { preface = source

+ " text value changed.\n" + " First 10 characters: \"";

}

public void textValueChanged(TextEvent e) { TextComponent tc = (TextComponent)e.getSource(); String s = tc.getText(); ...//truncate s to 10 characters...

displayArea.append(preface + s + "\"\n"); ...}

}

9095883.doc 54

Page 55: 7045244 Creating GUI With JFC Swing

Giao trinh Java

...}Lơp TextEventMôi phương thưc Text Event co môt thông sô đơn : đôi tương TextEvent. Lơp TextEvent đinh nghia môt phương thưc. Phương thưc getSource ma TextEvent thưa kê tư EventObject, ban co thê nhân đươc thanh phân Text liên quan đên sư kiên nay va gơi thông điêp cho no.Viêt môt Window Listener Cac sư kiên cua Window đươc phat ra sau khi Window mơ, đong, thu nho, phong to, hoat đông va không hoat đông.Cac phương thưc, sư kiên cua WindowGiao diên WindowListener va lơp mô phong tương ưng, WindowAdapter, chưa cac phương thưc sau: void windowOpened(WindowEvent) đươc goi au khi Window đươc mơ lân đâu. void windowClosing(WindowEvent) đươc goi sau khi ngươi sư dung đong Window. void windowClosed(WindowEvent) đươc goi sau khi Window đong lai.void windowIconified(WindowEvent) void windowDeiconified(WindowEvent) đươc goi sau khi Window phong to hay thu nho. void windowActivated(WindowEvent) void windowDeactivated(WindowEvent) đươc goi sau khi Window hoat đông hay không hoat đông.Vi du vê Handling Window Eventspublic class WindowEventDemo ... implements WindowListener { ...//where initialization occurs: //Create but don't show window. window = new Frame("Window Event Window"); window.addWindowListener(this); window.add("Center", new Label("The applet listens to this window" " for window events.")); window.pack(); }

public void windowClosing(WindowEvent e) { window.setVisible(false); displayMessage("Window closing", e); }

public void windowClosed(WindowEvent e) { displayMessage("Window closed", e); }

9095883.doc 55

Page 56: 7045244 Creating GUI With JFC Swing

Giao trinh Java

public void windowOpened(WindowEvent e) { displayMessage("Window opened", e); }

public void windowIconified(WindowEvent e) { displayMessage("Window iconified", e); }

public void windowDeiconified(WindowEvent e) { displayMessage("Window deiconified", e); }

public void windowActivated(WindowEvent e) { displayMessage("Window activated", e); }

public void windowDeactivated(WindowEvent e) { displayMessage("Window deactivated", e); }

void displayMessage(String prefix, WindowEvent e) { display.append(prefix + ": " + e.getWindow() + newline); } ...}Lơp WindowEventMôi phương thưc Window Event co môt thông sô đơn: đôi tương WindowEvent. Lơp WindowEvent đinh nghia môt phương thưc, getWindow, tra vê Window phat ra sư kiên nay.

5. Tông kêt vê Listener API

Phân nay This section features a quick-reference table that shows each listener, its adapter class (if any), and its methods.

6. Giai quyêt cac vân đê vê Event-Handling

If you're having some hard-to-debug problems related to handling events, you might find the solution here.

9095883.doc 56

Page 57: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bai 6: Lam viêc vơi đô hoa

Trong bai hoc nay, se hương dân ban cach hiên thi văn ban, cac hinh, anh đơn gian, sư dung API lam viêc trong JDK 1.1 va 1.2. Ngoai ra con co vi du vê viêc tư tao môt thanh phân, sư dung cac API đê tao môt đương viên hay môt icon. Cac kiên thưc vê hoat hinh se kêt thuc bai hoc nay.

1. Tông quan vê đô hoa

Giơi thiêu tông quat vê nhưng thông tin cân thiêt cho viêc băt đâu thưc thi viêc ve trong cac thanh phân.

2. Sư dung đô hoa nguyên ban

Trong phân nay se hương dân ban cach ve cac hinh đơn gian va hiên thi text môt cach co hiêu qua. Bao gôm cac vi du cua viêc sư dung cac lơp Graphics, Font, va FontMetrics classes.

3. Sư dung hinh anh

Java platform hô trơ hinh anh như thê nao se đươc ban bac trong phân nay va cach đê nap va hiên thi hinh anh.

4. Thưc hiên hoat canh (Performing Animation)

Nhiêu chương trinh thưc hiên hoat canh, hoăc la hoat hinh cua chu vit Duke đang tung tăng bơi lôi hay chi đơn gian la môt hinh anh chuyên đông trên man hinh. Trong phân nay se noi vê cach thưc hiên hinh anh đông, cach sư dung đôi tương Timer đê thưc hiên hoat canh.

Tao vong lăp cho hoat canh vơi đôi tương Timer(Creating an Animation Loop with Timer)

Bươc quan trong nhât đê tao môt chương trinh hoat hinh chinh la khơi tao cac framework môt cach chinh xac. Ngoai trư cac hoat hinh thưc hiên trưc tiêp cac đap ưng cho cac sư kiên mơ rông (vi du như viêc ngươi dung keo môt đôi tương trên man hinh), môt chương trinh thưc hiên hoat canh cân co môt vong lăp cua hoat hinh.

Minh hoa cho muc nay co trong cac vi du AnimatorAppletTimer.java va AnimatorApplicationTimer.java. Sau đây la phân tom lươc chung nhât cua ca hai vi du. Đây cung la xươn cua môt chương trinh hoat canh:

public class AnimatorClass ... implements ActionListener { int frameNumber = -1; Timer timer; boolean frozen = false;

9095883.doc 57

Page 58: 7045244 Creating GUI With JFC Swing

Giao trinh Java

JLabel label;

//In initialization code: //From user-specified frames-per-second value, determine //how long to delay between frames. ... //Set up a timer that calls this object's action handler. timer = new Timer(delay, this); ... //Set up the components in the GUI.

public synchronized void startAnimation() { ... timer.start(); ... }

public synchronized void stopAnimation() { ... timer.stop(); ... }

public void actionPerformed(ActionEvent e) { //Advance the animation frame. frameNumber++;

//Request that the frame be painted. label.setText("Frame " + frameNumber); } ... //When the application's GUI appears: startAnimation(); ...}

Tao chuyên đông cho môt hinh anh trên man hinh (Moving an Image Across the Screen)

Cach đơn gian nhât đê tao hoat canh la di chuyên môt hinh anh trên man hinh. Trong thê giơi cua hoat canh truyên thông, điêu nay đươc goi la cutout animation.

Co hai hinh ma applet sư dung.

9095883.doc 58

Page 59: 7045244 Creating GUI With JFC Swing

Giao trinh Java

rocketship.gif:

starfield.gif:

Va đây la giao diên cua applet. Cân lưu y la đê khơi đông hay dưng applet thi click chuôt lên applet.

This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window.

Lưu y: hinh rocketship co anh nên la transparent.

Đoan ma đê thưc hiên hoat canh nay không mây phưc tap. Noi chung, no cung giông như xươn đưa ra ơ bên trên. Thay vi sư dung môt label đê thưc hiên hoat canh thi no sư dung môt thanh phân tuy biên. Thanh phân tuy biên ơ đây la lơp con cua JPanel nhăm thưc thi viêc ve ca hai hinh anh ơ trên:

...//Where the images are initialized:Image background = getImage(getCodeBase(), "images/rocketship.gif");Image foreground = getImage(getCodeBase(), "images/starfield.gif");...public void paintComponent(Graphics g) { super.paintComponent(g); //paint any space not covered //by the background image int compWidth = getWidth(); int compHeight = getHeight();

//If we have a valid width and height for the //background image, paint it. imageWidth = background.getWidth(this); imageHeight = background.getHeight(this); if ((imageWidth > 0) && (imageHeight > 0)) { g.drawImage(background,

9095883.doc 59

Page 60: 7045244 Creating GUI With JFC Swing

Giao trinh Java

(compWidth - imageWidth)/2, (compHeight - imageHeight)/2, this); }

//If we have a valid width and height for the //foreground image, paint it. imageWidth = foreground.getWidth(this); imageHeight = foreground.getHeight(this); if ((imageWidth > 0) && (imageHeight > 0)) { g.drawImage(foreground, ((frameNumber*5) % (imageWidth + compWidth)) - imageWidth, (compHeight - imageHeight)/2, this); }}

Co thê ban se cho răng viêc xoa anh nên la không cân thiêt khi sư dung môt anh nên nao đo. Tuy nhiên, viêc xoa hinh nên ơ đây vân đươc quan tâm, bơi le applet luôn luôn khơi đông viêc ve trươc khi hinh đươc nap đây đu. Nêu hinh rocketship đươc nap trươc hinh nên thi ta se thây nhưng phân khac nhau nay cua chương trinh.

Hiên thi tuân tư cac hinh anh (Displaying a Sequence of Images)

Trong vi du cua phân nay se cung câp nhưng bươc cơ ban cua viêc hiên thi tuân tư cac hinh anh đê no thât giông như hoat canh ma ta thương thây. Dươi đây la 10 hinh anh ma applet se sư dung:

T1.gif: T2.gif: T3.gif: T4.gif: T5.gif:

T6.gif: T7.gif: T8.gif: T9.gif: T10.gif:

Ma cua vi du nay co trong tâp tin ImageSequenceTimer.java, vi du nay đơn gian hơn vi du vưa mô ta ơ trên, chi đơn gian la tao môt vong lăp đê hiên thi

9095883.doc 60

Page 61: 7045244 Creating GUI With JFC Swing

Giao trinh Java

thư tư hêt hinh nay đên hinh kia thay vi di chuyên môt hinh anh. Dươi đây la sư khac biêt đo:

. . .//In initialization code:Image[] images = new Image[10];for (int i = 1; i <= 10; i++) { images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif");}

. . .//In the paintComponent method:g.drawImage(images[ImageSequenceTimer.frameNumber % 10], 0, 0, this);

Cach khac đê thưc hiên vi du nay la dung môt label đê hiên thi cac hinh anh. Thay vi sư dung đoan lênh đê ve lai hinh thi ta dung phương thưc setIcon đê thay đôi hinh đươc hiên thi.

Cai tiên giao diên va thưc hiên hoat canh (Improving the Appearance and Performance of Image Animation)

Lưu y hai viêc trong vân đê hoat canh ơ trên:

• Trong khi môt bưc anh đang đươc nap, chương trinh se hiên thi môt phân cua toan bô bưc anh, cac phân khac co thê chưa đươc hiên thi.

• Nap môt bưc anh se cân môt thơi gian tương đôi dai.

Sư dung lơp MediaTracker co thê giai quyêt đươc vân đê vê hiên thi hinh anh. MediaTracker con co thê giam thiêu lương thơi gian đê nap hinh anh. Cach khac đê cai tiên thơi gian nap hinh la thay đôi dang thưc cua tâp tin anh. Trong phân nay se đê câp tơi vân đê nay.

Sư dung MediaTracker đê nap va nap hinh anh (Using MediaTracker to Download Images and Delay Image Display)

Lơp MediaTracker cho phep nap dư liêu cua môt nhom cac tâp tin anh va kêt thuc khi hinh anh đa đươc nap đây đu. Noi chung, dư liêu cua môt hinh anh chưa đươc tai vê khi no đươc ve trong lân đâu tiên. Đê yêu câu dư liêu cua cac hinh anh đươc chuân bi trươc đê tai vê, ta co thê sư dung cac phương thưc cua MediaTracker như sau: checkID(anInt, true) hoăc checkAll(true). Đê nap dư liêu vê môt cach đông bô, sư dung phương thưc waitForID hoăc waitForAll. Phương thưc MediaTracker sư dung tiên trinh cua hê thông đê tai dư liêu vê, do đo co thê tăng tôc đô cua đương truyên.

Đê kiêm tra trang thai cua viêc nap dư liêu vê, ta dung phương thưc MediaTracker statusID hoăc statusAll. Cach đơn gian nhât đê kiêm tra xem dư liêu cua hinh anh co đang đươc tai vê hay không thi dung phương thưc checkID hoăc checkAll.

9095883.doc 61

Page 62: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Chương trinh MTImageSequenceTimer.java la môt vi du vê viêc sư dung phương thưc MediaTracker waitForAll va checkAll. Applet vân hiên thi dong chư "Please wait..." cho đên khi tât ca cac hinh anh đêu đươc nap đây đu.

Nhưng thay đôi vê ma dươi đây sư dung MediaTracker đê hiên thi hinh anh. Nhưng sư khac nhau đươc in đâm.

...//Where instance variables are declared:MediaTracker tracker;

tracker = new MediaTracker(this);

...//In the init method:for (int i = 1; i <= 10; i++) { images[i-1] = getImage(getCodeBase(), "images/duke/T"+i+".gif");}

...//In the buildUI method, //which is called by init and main, //allowing us to run the sample //as an applet or an application:for (int i = 1; i <= 10; i++) { tracker.addImage(images[i-1], 0);}

...//At the beginning of the actionPerformed method:try { //Start downloading the images. Wait until they're loaded. tracker.waitForAll();} catch (InterruptedException e) {}

...//In the paintComponent method://If not all the images are loaded, just clear the background//and display a status string.if (!tracker.checkAll()) { g.clearRect(0, 0, d.width, d.height); g.drawString("Please wait...", 0, d.height/2);}

//If all images are loaded, paint.else { ...//same code as before...}

9095883.doc 62

Page 63: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Tăng tôc viêc nap hinh anh (Speeding Up Image Loading)

Cho du co hay không sư dung MediaTracker, viêc nap hinh anh sư dung URLs (cach cac applets thơng lam) luôn luôn tôn nhiêu thơi gian. Hâu hêt thơi gian ây la đê khơi tao sư kêt nôi HTTP. Môi môt tâp tin hinh anh đoi hoi môt kêt nôi HTTP khac nhau, va môi môt kêt nôi ây co thê tiêu tôn vai giây đê khơi tao. Cho nên, thơi gian keo dai la chuyên đương nhiên.

Cach thưc đê tranh xay ra phiên phưc trên la nên đăt tât ca cac hinh anh vao trong môt tâp tin anh. Co thê sư dung tâp tin JAR đê thưc hiên điêu nay.

5. Giai quyêt cac vân đê vê đô hoa

Mô ta môt vai vân đê liên quan đên đô hoa, giai phap đê giai quyêt cac vân đê nay.

9095883.doc 63

Page 64: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Bai 7: Chuyên đôi qua Swing

Trong bai nay se trinh bay cach thưc đê chuyên đôi môt chương trinh tư AWT sang sư dung cac thanh phân Swing. Nêu môt chương trinh đươc viêt đê sư dung vơi JDK 1.0, nghia la thay vi sư dung hê thông cac sư kiên listening đươc giơi thiêu trong JDK 1.1 thi lai sư dung cac phương thưc như la handleEvent va action, luc đo, điêu trươc tiên la chuyên đôi chương trinh đê sư dung hê thông cac sư kiên mơi hơn.

1. Tai sao phai chuyên đôi

Cac thanh phân Swing cung câp cho cac nha lâp trinh va ngươi dung đâu cuôi nhiêu thuân tiên. Trư khi ban co môt ly do nao đo thât chinh đang, con lai thi tât ca nên chuyên đôi sang sư dung cac thanh phân Swing.

The strongest reason to convert to Swing is because it offers many benefits to programmers and end users. Among them:

The rich set of ready-made components means that you can easily add some snazzy features to your programs -- image buttons, tool bars, tabbed panes, HTML display, images in menu items, color choosers, ... The list goes on and on.

You might be able to replace or reimplement some custom components with more reliable, extensible Swing components.

Having separate data and state models makes the Swing components highly customizable, and enables sharing data between components.

Swing's Pluggable Look & Feel architecture gives you a wide choice of look-and-feel options. Besides the usual platform-specific looks and feels, you can also use the Java Look & Feel, add an accessory look and feel (such as an audio "look and feel"), or use a third-party look and feel.

Swing components have built-in support for accessibility, which makes your programs automatically usable with assistive technologies.

The Swing components will continue to be enhanced in the future.

It's reasonable to put off converting if you don't think your users will be able run Swing programs conveniently. For example, if your program is an applet and you want anyone on the Internet to be able to use it, then you have to consider how many Web surfers have browsers that can run Swing programs. As of this writing, the major browsers don't have Swing support built in; the user must add it by downloading and installing Java Plug-in .

You have the choice of upgrading to Java 2 (JDK 1.2) when you convert to Swing. However, you don't need to decide right now whether to upgrade. Programs written with JDK 1.1 and Swing generally work just fine in Java 2.

9095883.doc 64

Page 65: 7045244 Creating GUI With JFC Swing

Giao trinh Java

For information about new and improved features of Java 2, see Tables of JDK Features .

2. Chuyên đôi như thê nao?

Trong phân nay se phac thao vê trinh tư cac bươc cua viêc chuyên đôi chương trinh cua ban sang dung cac thanh phân Swing. Viêc chuyên đôi nay đươc ap dung giông nhau cho ca ưng dung va applets, trư phi co nhưng lưu y khac. Hoan toan tôt đep khi thưc hiên viêc chuyên đôi môt chương trinh AWT sư dung JDK 1.1.

Sau đây la trinh tư cac bươc:

Bươc 1: Lưu dư phong môt ban copy cua chương trinh se chuân bi chuyên đôi.

Copy tât ca cac tâp tin cua chương trinh, kê ca tâp tin .java va .class. Nhưng ban copy nay se hưu dung cho chung sta trong môt sô trương hơp sau:

- Cân tham chiêu đên phân ma nguôn trong qua trinh chuyên đôi diên ra.

- Sau khi chuyên đôi, co thê chay ca hai ban đê co thê so sanh giưa chung vơi nhau.

- Môt vai chương trinh ngươi dung co thê chưa săn sang nâng câp VM lên phiên ban co hô trơ lơp Swing. Do đo, co thê la tam thơi sư dung chương trinh vơi AWT.

Bươc 2: Xoa bo tât ca nhưng tham chiêu đên goi java.awt.

Trong bươc nay, trinh biên dich se lam viêc cho ban. Đê thưc hiên viêc nay, cân vô hiêu tât ca cac dong import hoăc cac đoan lênh liên quan đên goi java.awt, trinh bêin dich se nhăc nhơ môi khi ta dung môt vai lơp nap đo cua goi AWT. Tuy nhiên, vân co môt vai lơp thuôc goi AWT vân dung đươc, vi du như layout managers, nhưng tôt nhât thi chương trinh cua ban không nên dung cac thanh phân cua AWT. Sau đây la môt đoan lênh cân đươc xoa bo:

//import java.awt.*; //temporarily remove this import

or

//import java.awt.Button; //temporarily remove this import

import java.awt.Color; //it's OK to leave this in, since

//Color isn't a component

...

/*java.awt.*/Frame = new /*java.awt.*/Frame(...);

9095883.doc 65

Page 66: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Trương hơp không co tham chiêu đên goi AWT, tinh biên dich se phat môt lôi "not found" khi phat hiên trong chương trinh co sư dung cac thanh phân AWT. Điêu nay giup cho viêc chuyên đôi de dang hơn la phai ngôi do tưng dong lênh trong cai rưng ma ban vưa mơi tao ra. Luc đo, chi viêc thay đôi cac thanh phân AWT sang cac thanh phân Swing môt cach dê dang. Trong bươc thư 9, ta se tim hiêu cach thêm vao lai cac lơp thuôc goi AWT nêu cân.

Step 3: Nêu chương trinh la môt applet, gơ bo dong lênh import java.applet.* (nêu co) va bât ky tham chiêu nao liên quan đên java.applet.Applet.

Ta không cân tham chiêu đên lơp Applet vi Swing applet đa trơ thanh môt lơp con cua lơp JApplet cua Swing. Nêu chương trinh đang sư dung AppletContext, AppletStub, hoăc AudioClip thi cân phai giư lai nhưng lơp nay trong goi java.applet. Sau đây la môt vi du:

//import java.applet.*; //temporarily remove this import

import java.applet.AppletContext; //add this if necessary

Bươc 4: Import the goi Swing.

Thêm dong fllenh sau đay vao chương trinh.

import javax.swing.*;

Dong lênh se imports cac thanh phân Swing cung vơi môt sô lơp Swing khac.

Bươc 5: Kiêm nhân môt tiên trinh an toan!

Trươc khi tiêp tuc, cân lưu y răng: Although AWT is thread-safe, Swing is not.

Hâu hêt cac chương trinh đêu đinh nghia cac thanh phân trong cac phương thưc event-handling va painting, la nhưng phương thưc đươc goi tư tiên trinh event-dispatching. Đinh nghia môt thanh phân trong nhưng phương thưc la an toan. Tuy nhiên, nêu chương trinh cân đinh nghia môt thanh phân ơ bât cư nơi nao khac nưa, vi du như trong môt tiên trinh chinh sau khi GUI đa hiên thi, hoăc trong ma lênh, thi nhât thiêt phai lam cho no la thread-safe.

Bươc 6: Thay đôi môi thanh phân AWT thanh nhưng thanh phân Swing tương ưng.

Trong nhiêu trương hơp, cac thanh phân AWT va cac thanh phân Swing tương ưng đêu tương thich vê ma lênh, chi cân thay đôi rât đơn gian vê tên goi cua cac thanh phân ma thôi. Vi du như đê thay đôi môt AWT button sang môt Swing button, chi cân thưc hiên như trong bang dươi đây:

AWT Code:

Button button = new Button("A Button");

9095883.doc 66

Page 67: 7045244 Creating GUI With JFC Swing

Giao trinh Java

button.addActionListener(this);

Swing Code:

JButton button = new JButton("A Button"); button.addActionListener(this);

Môt vai thanh phân Swing co ma nguôn không tương thich vơi thanh phân AWT tương ưng. Do đo, co môt vai thanh phân AWT phai viêt lai ma lênh khi chuyên sang sư dung cac thanh phân Swing.

Bươc 7: Chuyên đôi cach goi phương thưc add va setLayout.

Chương trinh sư dung cac thanh phân AWT, ta co thê thêm trưc tiêp cac thanh phân AWT vao trong frames, dialogs, va applets. Tương tư, ta cung co thê xac lâp cac layout manager trưc tiêp vao cac đôi tương chưa trên. Trong trương hơp ngươc lai, khi sư dung cac phiên ban Swing co chưa cac đôi tương trên, khi thêm cac thanh phân thi goi content pane. Cac vi du đơn gian sau:

AWT Code:

frame.add(panel, BorderLayout.CENTER);

Swing Code:

frame.getContentPane().add(panel, BorderLayout.CENTER);

Va đây la phân chi tiêt:

AWT Code:

frame.setLayout(new FlowLayout()); frame.add(button); frame.add(label); frame.add(textField);

Swing Code:

Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(button); contentPane.add(label); contentPane.add(textField);

Đoan ma sau minh hoa cach chuyên đôi ma cua môt applet. Chu y răng layout manager măc đinh cua môt content pane la BorderLayout chư không phai FlowLayout đươc sư dung trong Applet.

9095883.doc 67

Page 68: 7045244 Creating GUI With JFC Swing

Giao trinh Java

AWT Code:

setLayout(new BorderLayout()); add(button, BorderLayout.NORTH); add(panel, BorderLayout.CENTER);

Swing Code:

Container contentPane = getContentPane(); contentPane.add(button, BorderLayout.NORTH); contentPane.add(panel, BorderLayout.CENTER);

Bươc 8: Di chuyên ma lênh cua viêc ve ra khoi cac phương thưc paint va update.

Vơi cac thanh phân Swing, viêc thưc hiên painting trong ma lênh đươc thê hiên trong phương thưc paintComponent. Cach khac đê thưc hiên painting la sư dung cac icon chuân hoăc tư tao va đương viên.

Nêu trong chương trinh co cac lơp con Frame, Dialog, hoăc Applet thưc thi viêc lam tươi hay ve thi cân phai di chuyên cac ma lênh vao trong môt thanh phân khac. Con viêc xac đinh chinh xac thanh phân nao thi lai phu thuôc kiêu cua painting. Nêu môt đôi tương chưa co thê thưc hiên môt icon thi co thê thay thê thanh phân đo băng môt label. Ngoai ra, cac thanh phân khac co thê thay thê bơi cac lơp con cua lơp Jpanel. Co thê thêm cac thanh phân vao cac content pane cua frame, dialog, hoăc applet như đa mô ta ơ bươc 7.

Bươc 9: Sư dung trinh biên dich đê tim kiêm cac thay đôi cân thiêt khac.

Sau khi đa phân ma nguôn như đa mô ta ơ cac bươc trên, nên sư dung trinh biên dich đê vưa biên dich vưa kiêm tra lai chương trinh. Không nên sư dung trinh biên dich trong lân đâu đôi vơi chương trinh cua minh ma chưa co sư chinh sưa nao ca.

Trinh biên dich giup chung ta cac công viêc như sau:

Tim kiêm cac thanh phân AWT ma chung ta đa bo sot trong qua trinh chuyên đôi sang Swing. Nêu như ta đa xoa tât ca cac dong lênh tham chiêu đên java.awt như ơ bươc 2 thi trinh biên dich se xuât hiên câu thông bao lôi như sau:

TextEventDemo.java:23: Class Button not found

Trong phân khai bao.

Button button = new Button("Clear");

^

9095883.doc 68

Page 69: 7045244 Creating GUI With JFC Swing

Giao trinh Java

Đên thơi điêm nay, viêc nhân dang cac lơp AWT trong chương trinh vân con cân thiêt. Nêu như ta đa xoa tât ca cac dong lênh tham chiêu đên java.awt, trinh biên dich hiên thi thông bao như sau:

TextEventDemo.java:17: Class BorderLayout not found

Trong phân khai bao.

BorderLayout layout = new BorderLayout();

^

Cac lơp AWT co thê vân con đươc sư dung bơi Swing trong chương trinh.

Bươc 10: Chay chương trinh Swing.

Thưc hiên giông như đa mô ta trong phân biên dich va chay chương trinh Swing. Chương trinh se phat ra lôi trương hơp chung ta không nhơ thêm vao hay setLayout, cac lôi như sau:

java.lang.Error: Do not use javax.swing.JFrame.add() use

javax.swing.JFrame.getContentPane().add() instead

at javax.swing.JFrame.createRootPaneException(JFrame.java:333)

at javax.swing.JFrame.addImpl(JFrame.java:355)

at java.awt.Container.add(Container.java:212)

at AppletDemo.main(AppletDemo.java:121)

Quay trơ lai phân ma nguôn va điêu chinh cac phân cho phu hơp.

Bươc11: So sanh hai chương trinh Swing va AWT, cai tiên chương trinh theo kha năng cua Swing.

Măc du cac phiên ban cua Swing va AWT la giông nhau, nhưng viêc cai tiên triêt đê theo Swing la cân thiêt. Cân lưu y la co môt khac biêt, trư khi ban thưc hiên viêc copy ban JDK vơi tâp tin swing.properties đa đươc xac lâp, con lai thi hâu hêt chương trinh đêu sư dung môt look and feel mơi: the Java Look & Feel. Ta co thê xac lâp môt look and feel khac nêu muôn.

Step 12: Clean up!

Bây giơ la luc tinh gon phân ma lênh.

9095883.doc 69