Giáo trình java gửi với Swing
Trang 1Phõ̀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ụngnhững thành phõ̀n Swing Những thành phõ̀n Swing, một bộ phọ̃n của JavaTM
Foundation Classes (JFC), có thờ̉ được sử dụng hoặc với JDKTM 1.1 hoặc JavaTM 2platform
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ả ứngdụ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ườidù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áckhá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õ̀ntext…(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 layoutmanager 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
Sử dụng các đường vẽ, các text đờ̉ chờ́ tạo ra một hình ảnh, kờ̉ cả các hình ảnhđộng
8. Chuyờ̉n đụ̉i thành Swing
Trang 2Hướng dẫn cách chuyển đổi một chương trình sử dụng AWT API 1.1 sang chươngtrình sử dụng các thành phần Swing.
Bài 1: Bắt đầu với Swing
1 Đôi điều về JFC và Swing
JFC (Java Foundation Classes) là một tập hợp các chức năng giúp người dùng xâydựng giao diện đồ hoạ (GUIs) JFC được công bố lần đầu tiên vào năm 1997 tronghội nghị về những nhà phát triển JavaOne, bao gồm những chức năng sau:
1 Các thành 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 của JFC được thực hiện mà không cần bảng mã quốc gia mà dựa vàocác hàm API có trong JDK 1.1
Những phiên bản có Swing API
Swing API đã được sử dụng trong 2 dạng sau:
(1) Là phần cốt lõi của Java 2 Platform (phiên bản chuẩn của v 1.2 và v 1.3)
(2) JFC 1.1 (sử dụng với JDK 1.1)
Với mỗi phiên bản sử dụng, tùy thuộc vào việc chúng ta cần đến JDK 1.1 hay là Java
2 Platform và không cần phải thêm bất kỳ thư viện nào mà vẫn có thể sử dụng đượcSwing API Tuy nhiên, nếu cần sử dụng JDK 1.1 thì thêm vào Swing API (sử dụngJFC 1.1)
Hãng Sun đã phát hành nhiều phiên bản của JFC 1.1 và để nhận biết nó là phiên bảnnào thì cần dựa vào phiên bản của Swing API chứa trong nó
Bảng sau đây liệt kê các thông tin về Swing API
Chú thích
Swing 1.0.3
JFC 1.1 (with Swing 1.0.3)
Không Phiên bản của JFC 1.1 bao gồm Java
Java Plug-in 1.1.2 và Java Plug-in 1.2
cung cấp applet hổ trợ cho từng JDK 1.1 + Swing 1.1 và Java 2 Platform v 1.2 tương ứng
Swing 1.1.1 JFC 1.1 v 1.2.2 Thêm vào các tính năng mở rộng, xữ lý
Trang 3(with Swing 1.1.1)
không cần thay đổi) cho Swing 1.1 Java Plug-in 1.1.3 và Java Plug-in 1.2.2 cung
cấp applet hổ trợ choJDK 1.1 + Swing 1.1.1 và Java 2 Platform v 1.2.2, tương ứng
Không có sự
khác biệt về
"Swing" version
Không có v 1.3 Beta
Thêm vào các tính năng, xữ lý nhiều lỗi kỹ thuật, các chức năng mới Bổ sung thêm các tính năng và các hàm API mới Java Plug-in 1.3 Beta cung cấp applet hổ trợ cho phiên bản này
Các gói Swing
Swing API vừa lớn mạnh, lại vừa mềm dẽo Trong phiên bản 1.1 của API có 15 góidùng 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 các chương trình chỉ sử dụng một phần nhỏ của API, chủ yếu là các góiSwing javax.swing, javax.swing.event
Sự khác biêt giữa các thành phần Swing và AWT
Các thành phần AWT được cung cấp trong JDK 1.0 và 1.1 Mặc dù Java 2 Platform
vẫn còn hỗ trợ các thành phần AWT, tuy nhiên, chúng ta nên dùng các thành phần
Swing Khi sử dụng, có thể phân biệt các thành phần Swing với các thành phần AWT.Các thành phần Swing có tên bắt đầu bằng ký tự J Ví dụ như, lớp AWT button class
có tên là Button thì lớp Swing button có tên là Jbutton Ngoài ra, các thành phần AWT thì nằm trong gói java.awt, còn các thành phần Swing thì nằm trong gói javax.swing.
Do đó, khi sử dụng các thành phần Swing thì trong phần khai báo của chương trình, tanhớ thêm vào dòng lệnh sau:
import javax.swing.*;
Sự khác biệt lớn nhất giữa các thành phần AWT và Swing đấy là các thành phầnSwing được thực thi mà hoàn toàn không cần mã nguồn (with absolutely no nativecode) Kể từ khi các thành phần Swing không còn bị hạn chế trong những khuôn mẫuthông thường, (the least common denominator), tức là lúc mà các tính năng của nó đãcó mặt hầu hết trong các phiên bản, thì các chức năng của nó đã mở rộng hơn nhiều sovới các chức năng của các thành phần AWT Do các thành phần Swing không có mãnguồn (native code), nên chúng có thể được thêm vào như là một add-on của JDK 1.1hay như một phần của Java 2 Platform
Ngay cả những thành phần Swing đơn giản nhất cũng đã có những khả năng vượt xacác thành phần AWT:
Swing buttons và labels có thể hiển thị hình ảnh và cả văn bản
Có thể dễ dàng thay đổi đường viền của hầu hết các thành phần Swing Ta cóthể dễ dàng thay đổi đường viền của một label hay một đối tượng chứa nàođó
Trang 4 Có thể dễ dàng thay đổi hành vi hay giao diện của một thành phần Swingtrong phương thức điều khiển của nó hoặc tạo ra một lớp con (subclass) củachính thành phần đó
Thành phần Swing không có hình chữ nhật Do đó, các nút lệnh có thể có hìnhtròn hoặc bo góc
Kỹ thuật hỗ trợ (Assistive technologies) qua việc đọc màn hình có thể dể dànglấy thông tin từ các thành phần Swing
2 Biên dịch và thực thi một chương trình Swing
Ðể viết một chương trình sử dụng các thành phần Swing, trước tiên, ta phải có phiênbản của JDK và JFC tương ứng Biên dịch và thực thi một chương trình Swing còntùy thuộc vào việc đang sử dụng JDK 1.1 hay Java 2 Platform Nếu sử dụng Java 2Platform thì sẽ đơn giản hơn vì Swing đã được tích hợp
2.1 Biên dịch và thực thi chương trình với Java 2 Platform, v 1.2 or 1.3
Trong phần này, chúng ta sẽ khảo sát các vấn đề qua ví dụ SwingApplication.java cógiao diện như sau:
Sau đây là các bước trình tự cho việc biên dịch và thực thi một chương trình Swingvới Java 2 SDK, v 1.2 hay v 1.3:
1 Nếu chưa có, cài đặt vào máy phiên bản Java 2 Platform
2 Tạo một chương trình sử dụng các thành phần Swing
3 Biên dịch chương trình
4 Cho thực thi chương trình
Hiện nay, đang có 2 phiên bản của Java 2 Platform, tất cả đều miễn phí do Sun cungcấp (bạn có thể vào địa chỉ này để được hổ trợ: http://www.sun.com) Phiên bản thứnhất là v 1.2 (Java 2 SDK, Standard Edition v 1.2) và phiên bản thứ hai là v 1.3 (Java
2 SDK, Standard Edition v 1.3)
Ðể tạo một chương trình sử dụng các thành phần Swing, có thể sử dụng chương trìnhmẫu mà chúng tôi cung cấp sau đây SwingApplication.java Cần lưu ý là tên file phảichính xác là: "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.*;
Trang 5public 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!");
* 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
//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
Trang 6javac -deprecation SwingApplication.java
Trường hợp khi biên dịch không thành công, có thể là do bạn đang sử dụng trình biêndịch JDK 1.1 thay vì v 1.2 hoặc v 1.3 hoặc đang sử dụng bản beta của Java 2Platform
Thực thi chương trình sẽ được thực hiện khi đã biên dịch thành công Cần đảm bảo làtrong class path đã chỉ đường dẫn đến file thực thi:
Vd: java -classpath ;C:\java\lnfdir\newlnf.jar SwingApplication
Lưu ý: không cần phải gỏ phần đuôi mở rộng cls trình thông dịch của phiên bản 1.2hay 1.3 sẽ tự động dò tìm
2.2 Biên dịch và thực thi chương trình với JDK 1.1
Cũng tương tự như với Java 2 Platform, nhưng trình biên dịch sử dụng ở đây là JDK1.1 và JFC 1.1
3 Thực thi các Swing Applets
Để viết một Swing Applets, trước tiên là phải thực thi được chúng Phần này sẽ giớithiệu 2 applets
Sau đây là phần mã của 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
Trang 7JLabel 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 trình tự các bước sau:
(1) Đảm bảo là đã có trình duyệt 1.1 hoặc 1.2 hoặc tải về Java Plug-in và chúnglà những phiên bản mới nhất Trường hợp không có các thứ trên, có thể sửdụng Applet Viewer (appletviewer)
(2) Nếu bạn đang sử dụng trình duyệt 1.1 không có Java Plug-in thì cần phảinạp file Swing JAR vào trình duyệt
(3) Kiểm tra lại xem trình duyệt của bạn đã hoàn chỉnh chưa Trong phạm vibài này thì hình dưới đây kiểm chứng cho trình duyệt của bạn là đã đáp ứnghoàn hay hay chưa Nếu trong trình duyệt của bạn xuất hiện applet như dướiđây thì OK Trường hợp chỉ thấy một thay vì hai applet hoặc không thấycác hình ảnh thì trình duyệt của bạn chưa thực sự sẵn sàng
4 Trao đổi thêm về một ứng dụng Swing
Trong phần này, chúng ta sẽ tìm hiểu thêm thông qua chương trình SwingApplication.SwingApplication sẽ hiển thị cửa sổ như sau:
Phần mã của SwingApplication.java thực hiện những công việc sau:
4.1 Importing Swing packages
Dòng lệnh sau sẽ import gói Swing chính:
import javax.swing.*;
Trang 8Lưu ý: JFC 1.1 và Java 2 SDK v 1.2 phiên bản beta sử dụng tên gọi
khác nhau cho gói Swing
Hầu hết các chương trình đều cần import hai gói chính của AWT là:
import java.awt.*;
import java.awt.event.*;
4.2 Choosing the look and feel
Swing cho phép bạn chỉ định rõ “look and feel” mà chương trình của bạn sửdụng Java look and feel, Windows look and feel, CDE/Motif look andfeel, Đoạn mã in đậm dưới đây sẽ chỉ ra cho bạn cách mà SwingApplicationchỉ định “look and feel”:
public static void main(String[] args) { try {
4.3 Xác lập đối tượng chứa mức đỉnh
Mỗi chương trình được trình diễn đều có giao diện với mức đơn giản nhất làmột đối tượng chứa thuộc thành phần của Swing ở mức đỉnh Ở hầu hết cácứng dụng, đối tượng chứa Swing ở mức đỉnh có thể là JFrame, JDialog, hoặc(cho applets) JApplet Mỗi đối tượng JFrame sẽ thực hiện một cửa sổ chính vàmỗi JDialog sẽ thực thi cho cửa sổ thứ hai Mỗi đối tượng JApplet thực hiệnviệc hiển thị của một applet bên trong một cửa sổ Các đối tượng chứa mứcđỉnh của Swing cung cấp các hổ trợ cần thiết để các thành phần Swing thựchiện việc vẽ và quản lý các hành vi
Ví dụ SwingApplication chỉ có đối tượng chứa mức đỉnh là JFrame Khi ngườisử dụng đóng frame thi ứng dụng sẽ thoát Đoạn mã sau đây xác lập và chohiể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
Trang 94.4 Xác lập buttons và labels
Giống như GUIs, giao diện của SwingApplication chứa một button và mộtlabel Đ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útlệ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útlệ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 ");
4.5 Thêm thành phần vào các đối tượng chứa
SwingApplication nhóm label và button vào trong một đối tượng chứa (JPanel)trước khi thêm vào frame một thành phần khác Đoạn mã sau đây khởi tạo mộtpanel:
(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);
Dòng (1) dùng để tạo một panel, khai báo một đối tượng có kiểu Jpanel với têngọi là pane
Dòng (2) để tạo đường viền bao bọc cho panel đó
Dòng (3) dùng đẻ tạo một đối tượng quản lý layout để giám sát tất cả các thànhphần có trong panel sẽ được hiển thị trên một cột
Dòng (4) và (5) dùng để đưa button và label vào trong panel Việc thêm buttonvà label vào trong panel có nghĩa là chúng sẽ được điều khiển bởi layout quảnlý panel đó
Trang 104.6 Thêm đường viền (borders) xung quanh một thành phần
Đoạn mã sau đây sẽ tạo một đường viền cho một panel:
pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
10, //bottom 30) //right );
đường viền này đơn giản chỉ cung cấp một vùng trống của panel Thêm 30pixels cho top, left, và right, và 10 pixels cho bottom Borders là tính năng màJPanel thừa kế từ lớp JComponent
4.7 Handling events
SwingApplication chứa 2 event handlers Một nắm bắt sự kiện kích vào nútlệnh(action events) Cái kia để nắm bắt sự kiện đóng cửa sổ (window events).Sau đây là đoạn mã quản lý các sự kiện của 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);
}});
4.8 Dealing with thread issues
Chương trình SwingApplication là một tiến trình an toàn Bởi vì, một khi giaodiện của nó đang được hiển thị (visible), thì thao tác trên giao diện của nó chỉxảy ra cho một event handler Không thể có hai tiến trình cùng truy xuất đếnmột GUI trong cung fmột thời điểm
4.9 Supporting assistive technologies
Hỗ trợ assistive technologies, một thiết bị giống như để đọc màn hình, cungcấp cách thức để xử lý thông tin trên GUI Hỗ trợ này đã có trong hầu hết cácthành phần Swing Trong SwingApplication có một chỗ đề cập đến kỹ thuậtnày:
label.setLabelFor(button);
Như đã nói, việc lấy thông tin từ các thành phần Swing là điều đang được quantâm, kỹ thuật trên đã giúp cho công việc này được thực hiện một cách dễ dàng:
JButton button = new JButton("I'm a Swing button!");
label = new JLabel(labelPrefix + "0 ");
Trang 11JFrame frame = new JFrame("SwingApplication");
Trang 12Bài 2: Các khái niệm và chức năng của Swing
Trong bài này sẽ giới thiệu các đặc trưng của Swing và giảng giải các kháiniệm cần thiết để bạn có thể nắm bắt và sử dụng các thành phần Swing mộtcách có hiệu quả Phần cuối của bài học này sẽ phân tích một chương trìnhSwing và đây sẽ là phần tổng kết lại những gì bạn đã học trong bài này
1 Các thành phần Swing và sự phân cấp giới hạn
Swing cung cấp rất nhiều thành phần GUI chuẩn như: buttons, lists, menus, vàtext areas, là những thành phần mà bạn sẽ phối hợp để tạo nên GUI cho chươngtrình của bạn Ngoài ra, còn có các đối tượng chứa như windows và 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 SwingApplication's
Ví dụ này sẽ đề cập đến một vài thành phần Swing thường dùng và cách thứcchú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 thành 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 thành phần khác thiết lập sự có mặt củamình trên vùng đó Ngoài ra còn có các thành phần khác thường được sử dụngđể 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
mục đích xác định vị trí của button và label Những đối tượng chứa mức trunggian khác còn có scroll panes (JScrollPane) và tabbed panes (JTabbedPane),chúng có ảnh hưởng lẫn nhau, tương tác với nhau rtong giao diện của mộtchương trình
button và label là những thành phần cơ bản (atomic components), những thành
phần mà không thể chứa các thành phần Swing khác AWT thông thường, cácthành phần cơ bản này sẽ là nơi để nhận thông tin đầu vào từ phía người dùng.Swing API cung cấp nhiều thành phần cơ bản, bao gồm combo boxes(JComboBox), text fields (JTextField), và tables (JTable)
Hình dưới đây là sơ đồ phân cấp giới hạn của các thành phần trong ví dụ
SwingApplication
Trang 13Như hình vẽ trên, ngay cả các chương trình Swing đơn giảnn nhất cũng cónhiều mức khác nhau Nhưng bao giờ gốc của sơ đồ vẫn là đối tượng chứa mứcđỉnh, nới để các thành phần Swing khác thể hiện sự tồn tại của mình
Mách nước: Để xem sự phân cấp của bất kỳ frame hay dialog nào, chỉ cần kích chuột vào border của nó để chọn, nhấn Control-Shift-F1
Mỗi một đối tượng chứa mức đỉnh đều gián tiếp chứa một đối tượng chứa trung
gian thường được gọi là content pane Khi làm việc, bạn không cần quan tâm
thế nào là đối tượng chứa mức đỉnh và cái nào là đối tượng chứa trung gian.Chương trình sẽ tự động quản lý cho bạn
pane contains, trực tiếp hoặc gián tiếp chứa tất cả các thành phần sẽ hiển thị
trong GUI Riêng đối với top-level container thì có menu bar, menu bar sẽ đứng trong một vùng đặc biệt nằm ngoài content pane
Để thêm một thành phần vào đối tượng chứa, có thể dùng nhiều cách khác nhau
của phương thức add() Phương thức add() có ít nhất 1 đối số (argument)
Đoạn mã sau đây sẽ thực hiện việc thêm một button và một label vào 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
Các đối tượng chứa sử dụng layout managers để xác lập kích thước và vị trí
của các thành phần chứa trong nó Borders sẽ ảnh hưởng đến layout của SwingGUIs bằng cách làm cho các thành phần lớn lên
Hình dưới đây hiển thị GUI của 5 chương trình GUI của chúng khác nhau là
do sử dụng các layout managers khác nhau để xác định kích thước và vị trí của
buttons
Trang 14Layout management là quá trình xác định kích thước và vị trí của các thành
phần Mặc định, mỗi đối tượng chứa sẽ có một layout manager
Java platform hỗ trợ sử dụng 5 layout managers thông thường nhất:
BorderLayout, BoxLayout, FlowLayout, GridBagLayout, và GridLayout.
Những layout managers được thiết kế để hiển thị đa thành phần trong cùng một thời điểm Và lớp thứ 6, CardLayout, là một trường hợp đặc biệt Nó được sử dụng để kết hợp các layout managers với nhau
Xác lập Layout Manager
Bạn có thể dể dàng thay đổi một layout managers trở thành một container để
sử dụng Đơn giản là chỉ cần gọi phương thức setLayout Đoạn mã sau đây sửdụng BorderLayout:
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
Một vài gợi ý về Component (Providing Hints about a Component)
Ta có thể sử dụng các phương thức sau để tùy biến kích thước và vị trí của cácthành phần: setMinimumSize, setPreferredSize, và setMaximumSize, hoặc cóthể xây dựng các lớp con của các thành phần để khai thác các phương thứcnhư: getMinimumSize, getPreferredSize, và getMaximumSize
Bên cạnh việc cung cấp các tùy biến về kích thước, ta cũng còn có thể cung cấpthêm các tùy biến về việc canh chỉnh, gồm các phương thức sau:setAlignmentX và setAlignmentY, getAlignmentX và getAlignmentY methods
How Layout Management Occurs
Ví dụ sau đây mô tả trình tự quá trình hiển thị của một frame (JFrame)
1 Khi GUI được xây dựng, JFrame sẽ gọi phương thức pack Việc chỉ
định này sẽ bảo đảm frame xuất hiện đúng với kích thước mà nó đã
được xác lập trước đó
2 To find the frame's preferred size, the frame's layout manager adds thesize of the frame's edges to the preferred size of the component directly
Trang 15contained by the frame This is the sum of the preferred size of theframe'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 thecontent pane's preferred size By default, this layout manager is aBorderLayout object However, let's assume that we replace it with aGridLayout object that's set up to create two columns, as in the bottomright 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 makethem as wide as the widest component's preferred width and as high ashighest 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 layoutmanager queries each component in the content pane for its preferredsize, 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 checkswhether the user specified a preferred size If so, it reports that size Ifnot, it queries its look and feel for the preferred size
3 Event Handling
Event handling thể hiện việc chương trình phản hồi các yêu cầu từ phía bên
ngoài, ví dụ như việc người dùng nhấn phím chuột Chương trình Swing sẽthực hiện tất cả các thao tác và nắm bắt các sự kiện (event handling) bằng cáchthực hiện tiến trình của sự kiện
Mỗi khi người dùng nhấn phím hay kích chuột, thì một sự kiện xảy ra Bất kểđối tượng nào cùng đều được gán bởi một sự kiện Các thành phần Swing cóthể tạo ra nhiều kiểu sự kiện khác nhau Bảng sau đây liệt kê một vài kiểu sựkiện:
User kích vào nút lệnh, nhấn phím Spacebar khi đanglàm việc trong text field, hoặc kích chọn vào menuitem
ActionListener
User đóng một frame (main window) WindowListener User nhấn một nút chuột trong khi đang rê chuột trên
User di chuyển chuột trên một thành phần MouseMotionList
ener
r Thành phần lấy trạng thái của keyboard FocusListener Việc chọn lựa trong Table hoặc list có thay đổi ListSelectionListener Mỗi sự kiện đều được đại diện bởi một đối tượng và đối tượng đó cung cấpthông tin về sự kiện cũng như nhận dạng được nơi phat ra sự kiện Nguồn của
Trang 16sự kiện thông thường là các thành phần, nhưng những kiểu đối tượng kháccũng có thể là nguồn của sự kiện Hình sau đây minh hoạ cho vấn đề này
Caption: Multiple listeners can register to be notified of events
of a particular type from a particular source.
Cách thực thi một Event Handler (How to Implement an Event Handler)
Mỗi event handler đòi hỏi có 3 bước như sau:
1 Trong phần khai báo cho lớp event handler, xác định rõ mỗi lớp sẽ thựcthi một listener interface hoặc kế thừa một lớp mà lớp đó thực thi mộtlistener interface Ví dụ:
2 public class MyClass implements ActionListener {
3 Đăng ký sự hiện diện của lớp event handler như là một listener trên mộthoặc nhiều thành phần Ví dụ:
4 someComponent.addActionListener(instanceOfMyClass);
5 Thực thi những phương thức trong listener interface Ví dụ:
6 public void actionPerformed(ActionEvent e) {
7 .//code that reacts to the action
8 } Hãy xem xét cách thức một nút lệnh (JButton) nắm bắt sự kiện kích chuột Đểxác định khi nào thì người dùng kích chuột lên nút lệnh (hoặc dùng các phím
nóng) thì một chương trình phải có đối tượng thực thi giao diện ActionListener.
Chương trình phải đăng ký đối tượng đó như là một action listener trên nút lệnh
(nguồn của sự kiện) bằng cách sử dụng phương thức addActionListener Khi
user kích lên nút lệnh, nút lệnh sẽ phát ra một hành vi của sự kiện Đây là yêu
cầu của phương thức actionPerformed Trong phương thức này, tham số sẽ là một đối tượng ActionEvent và tham số này sẽ cung cấp thông tin về sự kiện và
nguồn của sự kiện
Caption: Khi user vào nút lệnh, action listeners của nút lệnh được phát ra.
Tiến trình và Event Handling (Threads and Event Handling)
Mã của handling xảy ra trong một tiến trình đơn hay còn gọi là
event-dispatching thread Điều này nhằm đảm bảo là mỗi event handler hoàn thành
Trang 17việc thực hiện trước khi một event handler xảy ra Ở ví dụ minh hoạ trên,phương thức actionPerformed được xữ lỹ trong một tiến trình đơn
4 Painting
Painting nghĩa là vẽ các thành phần trên màn hình Mặc dầu việc tùy chọn các
thành phần được thực hiện một cách dễ dàng, nhưng hầu hết các chương trìnhđều bị làm phức tạp lên bằng cách tùy chọn đường viền cho các thành phần
Cách làm việc của Painting (How Painting Works)
Khi một Swing GUI cần vẽ lại giao diện của chính nó, hoặc khi cần làm tươinhững điều chỉnh về trạng thái của chương trình, nó sẽ khởi động thành phần ởmức cao nhất (top-level component) cần được vẽ lại và làm việc dần xuốngtheo luồng phân cấp Quá trình xữ lý này được thực hiện bởi hệ thống AWTnhàmư làm cho chương trình có vẽ hiệu quả và thích ứng hơn
Các thành phần Swing có thể vẽ lại chính nó bất kể khi nào cần thiết Khi gọi
phương thức setText trên một thành phần, thành phần đó sẽ tự động vẽ lại chính
nó, thay đổi kích thước,…
Cũng giống như event-handling, painting cũng được thực hiện trong một tiếntrình đơn Trong khi một sự kiện đang xảy ra thì quá trình vẽ lại không đượcthực hiện
Quá trình vẽ lại các thành phần sẽ không bị ngắt quảng bởi các sự kiện khác
Ví dụ minh hoạ về Painting (An Example of Painting)
Để minh hoạ cho quá trình painting, ta sử dụng lại chương trình
SwingApplication Hình dưới là giao diện của SwingApplication:
Sơ đồ phân cấp:
Khi GUI của SwingApplication được vẽ, quá trình đó xảy ra như sau:
1 Đối tượng chứa mức đỉnh, JFrame, sẽ vễ lại nó trước tiên
Trang 182 Các đối tượng chứa trung gian, trước hết là vẽ lại background, chứa nó.
Sau đó sẽ là JPane
3 JPanel trước hết sẽ vẽ lại background, sau đó là đường viền và sau cùnglà các thành phần con chứa trong nó
4 Để vẽ lại, JButton vẽ nền của nó, sau đó là dòng văn bản của chính nó
5 JLabel vẽ lại văn bản của nó
Điều này có nghĩa là, các thành phần sẽ vẽ lại chính bản thân nó trước khi nóđiều khiển các thành phần chứa trong nó vẽ lại Hình sau đây minh hoạ những
thành phần thừa kế từ JComponent và vẽ lại chính bản thân nó:
1 background (if opaque) 2 custom painting
(if any)
3 border (if any) 4 children (if any)
5 Threads and Swing
Nếu làm việc các thành phần mà những thành phần đó phụ thuộc hoặc ảnhhưởng đến trạng thái của nó, ta cần phải thực hiện chúng trong một tiến trìnhđơn Tuy nhiên, những chương trình khác cần sử dụng phương thức
invokeLater để thực hiện việc gọi cá thành phần có liên quan trong tiến trình
ấy
Nếu một chương trình tạo ra và chỉ làm việc trên GUI của chính nó, thì khôngcần quan tâm về tiến trình Ví dụ, chương trình là một applet, nó sẽ đảm bảo an
toàn khi lưu cấu trúc của nó trong phương thức init Thậm chí, khi chương trình
là một ứng dụng như dưới đây, thì vẫn đảm bảo được sự an toàn nói trên:
//Thread-safe examplepublic class MyApplication { public static void main(String[] args) {JFrame f = new JFrame( );
//Add components to the frame here
Trang 196 Những tính năng và khái niệm khác của Swing
Swing cung cấp nhiều tính năng Rất nhiều tính năng được cung cấp bởiJComponent class Một vài tính nằng thú vị sẽ không được đề cập đến trong bàihọc này như icons, actions, công nghệ Pluggable Look & Feel, assistivetechnologies, và separate models
6.1 Những tính năng của Jcomponent (Features that JComponent Provides)
Ngoại trừ đối tượng chứa mức đỉnh, tất cả các thành phần khác bắt đầu bằng ký
tự J đều được thừa kế từ lớp Jcomponent Hầu hết các thành phần đều có các
tính năng chung như tooltips và cấu hình về giao diện (look and feel) Ngoài ra,chúng còn thừa kế nhiều phương thức tiện lợi khác nữa
6.2 Icons
Nhiều thành phần Swing, đặt biệt là button và label, có thể hiển thị hình ảnh
Ta có thể chỉ định cho các hình ảnh này như là các đố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
xẽ dữ liệu và trạng thái giữa hai hoặc nhiều thành phần phát ra các sự kiện hànhđộng Ví dụ, khi ta có một button và một menu item cùng một chức năng, lúc
đos cần cân nhắc việc sử dụng đối tượng Action để xác định văn bản, icon và
trạng thái của hai thành phần
6.4 Support for Assistive Technologies
Assistive technologies such as screen readers can use the Accessibility API toget information from Swing components Because support for the AccessibilityAPI is built into the Swing components, your Swing program will probablywork just fine with assistive technologies, even if you do nothing special Withvery little extra effort, however, you can make your program function evenmore smoothly with assistive technologies, which might well expand itsmarket See How to Support Assistive Technologies for details
7 Phân tích một chương trình Swing
Bao gồm một ứng dụng nhỏ về Swing với tên gọi là Converter sẽ mô tả cáchmột chương trình Swing làm việc và mối quan hệ gắn kết nhau giữa các đoạn
mã trong chương trình
Converter là một ứng dụng dùng để chuyển đổi đơn vị đo lường giữa hai hệ
thống met và U.S units Để chạy được ứng dụng này thì phải biên dịch các tập
tin sau: Converter.java, ConversionPanel.java, ConverterRangeModel.java,
DecimalField.java, FollowerRangeModel.java,FormattedDocument.java và Unit.java.
Sau đây là hình ảnh minh hoạ về giao diện của Converter:
Trang 20Trong các bài học sau, chúng ta sẽ tìm hiểu chi tiết về các tính năng, khái niệm vềSwing Chắc chắn sẽ còn nhiều thú vị đang chờ đợi chúng ta
Trang 21Bài 3: Sử dụng các tính năng khác của Swing
Bài học này hướng dẫn cách sử dụng các tính năng khác của Swing
1 Cách sử dụng Actions
Với đối tượng Action, ta có thể sắp xếp và quản lý các trạng thái của hai hoặc nhiều thành phần tạo ra sự kiện của hành vi Ví dụ, bạn có thể sử dụng Action
để tạo ra và quản lý một button trên thanh công cụ, một menu biểu tượng cùngthực hiện một chức năng
Sau đây là ví dụ của việc sử dụng Action để tạo ra một button trên thanh công
cụ và một menu item cùng 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, để có được những hữu ích thực sự của việc sử
dụng Action, ta phải tạo thành phần sử dụng phương thức add(Action) của
JToolBar, JMenu, hoặc JPopupMenu Mặc định, không có hàm API nào tồn tại
ở bên trên addActionListener(ActionListener) để kết nối một Action với một
thành phần khác đang tồn tại thực sự
Để tạo một đối tượng Action, nói chung là ta phải tạo một lớp con của lớp
AbstractAction và thực thi nó trong lớp con này, ta cho thực hiện phương thức
actionPerformed để tác động ngược trở lại một cách thoả đáng khi hành vi sự
kiện xảy ra Sau đây là ví dụ của việc tạo và thực hiện lớp con của 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);
}};
Hình dưới đây là demo ứng dụng của việc sử dụng Action để thực hiện ba tínhnăng
Đây là những gì nhìn thấy khi menu "Go left" trở nên disabled:
Trang 22Đoạn mã của "Go left" action:
boolean selected = //true if the action should be enabled;
//false, otherwise
leftAction.setEnabled(selected);
Sau khi tạo ra thành phần sử dụng Action, ta có thể tùy biến chúng theo ý thích
của mình Ví dụ như khi muốn thêm vào dòng tooltip của một button, hoặc tùybiến việc xuất hiện hay biến mất của cá thành phần bằng cách thêm vào , xoá đicác icon, dòng văn bản:
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
Bảng sau đây liệt kê những phương thức và contructors thường dùng các
Action Các hàm API sử dụng đối tượng Action được chia thành hai loại như
sau:
Tạo và sử dụng một Action
Tạo một thành phần điều khiển Action (Action-Controlled Component)
Creating and Using an Action
Constructor or Method Purpose
AbstractAction()
AbstractAction(String)
AbstractAction(String,
Icon)
Tạo một đối tượng Action Thông qua các tham số
của phương thức hay Contructors, có thể xác lậpvăn bản hay icon trong thành phần ấy
void setEnabled(boolean)
boolean isEnabled()
Xác lập hay nhận biết cá thành phần có nhận đượctác động hay không Thông qua phương thức
setEnabled(false), vô hiệu tất cả các tác động lên
các thành phần Tương tự như vậy, sử dụng
phương thức setEnabled(true) để tác động lại hành
vi của các thành phần
Creating an Action-Controlled Component
Trang 23Tạo một đối tượng JMenuItem và đặt chúng vào
trong menu hay popup menu
JButton add(Action)
(in JToolBar)
Tạo một đối tượng Jbutton và đặt chúng lên thanh
công cụ
2 Thế nào là kỹ thuật hỗ trợ Assisive( Support Assistive Technologies )
Các thành phần Swing hỗ trợ kỹ thuật trợ giúp Chương trình của bạn sẽ đượchỗ trợ tốt hơn Ví dụ như dòng tooltip sẽ hiện lên chức năng của một nút lệnhnào đó khi ta di chuyển chuột lên nút lệnh đó
3 Cách sử dụng các đường viền(Border)
Borders sẽ đem lại cho chúng ta nhiều thuận lợi trong việc vẽ các đường thẳng,tiêu đề hay các vùng trống của một thành phần Trong các ví dụ của phần nàycó sử dụng rất nhiều border Ở đây, chúng ta sẽ tìm hiểu cách thêm một bordervào bất kỳ thành phần JComponent nào
4 Cách sử dụng Icons
Nhiều thành phần Swing có thể hiển thị icons( JLabel và JButton) Thường thìicons là trường hợp cá biệt của ImageIcon class
Một vài thành phần Swing như JLabel và JButton, có thể được trang trí bởi một
icon Icon là một đối tượng gắn kết chặt chẽ với giao diện Icon Swing cung
cấp cho giao diện Icon cách thực hiện rất đặt biệt và hiệu quả đẻ vẽ một Icon
tưg một tập tin ảnh có dạng thức GIF hoặc JPEG
Hình dưới đây minh hoạ một ứng dụng sử dụng một Icon để trang trí cho hailabel:
Trong phần mã của chương trình, câu lệnh (1) dùng để tạo icon sử dụng mộticon, câu lệnh (2) và (3) gán icon ấy vào trong hai label::
(1) ImageIcon icon = new ImageIcon("images/middle.gif", "a pretty but meaningless splat");
Trang 24Tham số thứ nhất trong ImageIcon constructor xác định tập tin ảnh để nạp lên,phần này phải đẻ ý đến đường dẫn tới thư mục có chứa tập tin class Tham sốthứ hai dùng để mô tả về icon ấy, giống như phần tooltip của các ứng dụng màchúng ta vẫn thường thấy
Nói chung, các applet nạp hính ảnh từ máy tính, nơi phục vụ cho applet ấy Cóhai lý do để làm như vậy, thứ nhất là không tin tưởng khi để các applet đọc cáctập tin hệ thông từ máy nó đang chạy Thứ hai là để kết hợp các lớp của appletvới tập tin dữ liệu với nhau Để nạp một hình ảnh từ server, một applet phải sửdụng URL như đoạn mã trong ví dụ dưới đây:
public class SomeClass extends JApplet {
protected String leftButtonFilename = "images/left.gif";
protected URL getURL(String filename) { URL codeBase = getCodeBase();
URL url = null;
try { url = new URL(codeBase, filename);
} 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, nó sử dụng một đối tượng image để để chứa dữ liệucủa hình ảnh và đối tượng MediaTracker được chia sẽ cho tất cả cácicon trong cùng một chương trình
Xác định hình ảnh nguồn (Specifying the Image Source)
Thường thì dữ liệu của một hình ảnh xuất phát từ một tập tin hình ảnh Có thểxác định nơi lưu trữ của tập tin thông qua tên tập tin hoặc sử dụng đối tượngURL Đối với ứng dụng, tên tập tin hoặc URL đều có liên quan đến thư mụcchứa chứa tập tin class của ứng dụng hoặc là đường dẫn Để chỉ định một URLliên quan đến đường dẫn của ứng dụng, ta có thể sử dụng phương thứcgetSystemResource như ở ví dụ dưới đây:
Trang 25ImageIcon 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 sẽ dò tìm trong thư mục và tập tin JAR trongđường dẫn của chương trình, trả về URL ngay khi nó tìm thấy Ví dụ, khi tađưa vào đường dẫn của ứng dụng tập tin jar có tên icons.jar, nếu tập tin JAR cóchứa images/middle.gif, thì dứat khoát, đường dẫn sẽ trả về một URL xác địnhcho images/middle.gif Tuy nhiên, có thể là URL đó không có bất cứ liên quannào về tập tin icons.jar
The Image Icon API
Bảng sau đây liệt kê những cấu trúc và phương thức sử dụng thông thường củaImageIcon constructors and methods Lưu ý là ImageIcon không có nguồn gốctừ JComponent hay thậm chí là từ Component
Setting, Getting, and Painting the Image Icon's Image
, Graphics, int, int)
Vẽ ảnh của icon trong vùng đồ hoạ đã được chỉ địnhPaintthe image icon's image in the specified graphics context.You would do this only if you're implementing a custom
Trang 26component that performs its own painting TheComponent object is used as an image observer You canrely on the default behavior provided by Componentclass and pass in any component The two int argmentsspecify the x and y coordinates, respectively.
Setting or Getting Information about the Image Icon
int getIconHeight() Get the width or height of the image icon in pixels.
Watching the Image Icon's Image Load
int getImageLoadStatus() Get the loading status of the image icon'simage The set of values returned by this
method are defined by MediaTracker
5 Sử dụng tiến trình( Threads )
Sử dụng tiến trình là một công việc khó khăn Do đó nếu có thể được thì bạnnên tránh phần này Tuy nhiên Thread có thể giúp cải tiến chương trình của bạnbằng cách quản lý sự thực thi
Nguyên tắc đầu tiên khi sử dụng threads là: tránh dùng chúng nếu như có thể.Threads có thể rất khó sử dụng và chúng có thể gây khó khăn khi chúng tadebug chương trình Để tránh trường hợp bị đình trệ của chương trình, cần phảiquan tâm ngay từ đầu rằng mỗi tiến trình được tạo ra không kêu gọi thực thi bấtkỳ một thành phần Swing nào
Mặc dù nguy hiểm, nhưng threads rất cso giá trị khi ta sử dụng chúng một cáchcẩn thận Ta có thể cải thiện việc thực hiện chương trình Đôi khi, một vài tiếntrình làm đơn giản mã hoặc cấu trúc của một chương trình Sau đây là một vàitình huống khi sử dụng tiến trình:
To move a time-consuming initialization task out of the main thread, sothat the GUI comes up faster Examples of time-consuming tasksinclude making extensive calculations and blocking for network or diskI/O (loading images, for example)
To move a time-consuming task out of the event-dispatching thread, sothat the GUI remains responsive
Trang 27 To perform an operation repeatedly, usually with some predeterminedperiod of time between operations
To wait for messages from other programs
Nếu tạo một thread, cần phải tránh những nguy hiểm khi thực thi một tiến trìnhvới các lớp tiện ích như SwingWorker hay Timer Đối tượng SwingWorker tạomột thread để thực thi một qui trình xữ lý về thời gian Sau khi qui trình hoànthành, SwingWorker cung cấp một vài tùy chọn để thực hiện việc gửi đi một sựkiện Đối tượng Timer thực thi một thread và sinh ra một hoặc nhiều hành vi sựkiện sau khi xác định được lặp lại
6 Sử dụng Timers
Với lớp Timer, bạn có thể cho thực hiện một tiến trình của việc thực thi mộthành động sau một khoảng thời gian xác định và lặp lại hành vi ấy
Có hai cách để thực hiện Timer:
Thực hiện một tác vụ, với thời gian lặp lại được xác định Ví dụ, tool tipmanager sử dụng timers để quyết định khi nào thì hiển thị và khi nào thìtắt nó đi
Thực hiện việc lặp đi lặp lại một tác vụ
Trong ví dụ dưới đây sử dụng đối tượng timer để thể hiện tiến trình làm việccủa một tác vụ
Và đây là đoạn mã của chương trình ProgressBarDemo.java
public final static int ONE_SECOND = 1000;
Khi user nhấn vào nút Start, chương trình khởi động timer:
Trang 28
}
The Timer API
Bảng sau đây liệt kê những cấu trúc và phương thức của Timer Các hàm APIvề sử dụng timers chia thành hai loại như sau:
Tạo và khởi động Timer
Running the Timer
Trang 29Bài 4: Bố trí các thành phần bên trong các đối tượng chứa
Bài học này sẽ hướng dẫn bạn cách quản lý việc bày trí mà Java Platform cungcấp, cách sử dụng vị trí tuyệt đối
1 Sử dụng Layout Managers
Phần này cung cấp các qui tắc tổng quan và chi tiết lệnh trong việc sử dụngviệc quản lý bố trí mà Java platform cung cấp
a Sử dụng Layout Managers
Sử dụng BorderLayout
Sau đây là một Applet cho thấy BorderLayout làm việc như thế nào
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 trọng: khi thêm một thành phần vào một Container sử dụng
BorderLayout, bạn nên dùng phương thức add() hai thông số, và thông số thứnhất phải là "North", "South", "East", "West", hoặc "Center" Nếu bạn sử dụngphương thức add()một thông số hay bạn không xác lập thông số thứ nhất thìthành phần đó sẽ không hiển thị
Theo mặc định, BorderLayout không đặt khoảng trống giữa các thành Muốnvậy, bạn phải xác lập nó bằng cách dùng cấu trúc sau:
public BorderLayout(int horizontalGap, int verticalGap)
Sử dụng CardLayout
Sau đây là một Applet cho thấy CardLayout làm việc như thế nào
//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);
cards.add(TEXTPANEL, p2);
Khi bạn thêm một thành phần vào một Container mà có sử dụng CardLayout,bạn phải sử dụng phương thức add() hai thông số: add(String name,Component comp) Thông số thứ nhất có thể bất kì chuỗi nào để nhận ra thànhphần được thêm vào
Sau đây là một đoạn mã ví dụ cho phương thức trên:
Trang 30//Where the container is initialized:
//Put the Choice in a Panel to get a nicer look
Panel cp = new Panel();
Choice c = new Choice();
public boolean action(Event evt, Object arg) {
if (evt.target instanceof Choice) { ((CardLayout)cards.getLayout()).show(cards,(String)arg);
return true;
} return false;
}Như đoạn mã trên, bạn có thể sử dụng phương thức show() của CardLayout đểxác lập thành phần hiển thị hiện tại Thông số thứ nhất của phương thức show()là Container mà CardLayout điều khiển thông số thứ hai là chuỗi để xác địnhthành phần hiển thị Chuỗi này giống như chuỗi của thành phần thêm vàoContainer
Theo sau là tất cả các phương thức của CardLayout mà có thể cho phép chọnmột thành phần cho mỗi phương thức, thông số thứ nhất Container choCardLayout là 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ử dụng FlowLayout
Sau đây là một Applet cho thấy FlowLayout hoạt động như thế nào
Trang 31đặc giữa các thành phần Nếu bạn không xác lập giá trị này, FlowLayout sẽ mặc địnhgiá tri 5 cho mỗi thông số.
Sử dụng GridLayout
Sau đây là một Aplet cho thấy GridLayout làm việc như thế nào
//Construct a GridLayout with 2 columns and an unspecified number ofrows
setLayout(new GridLayout(0,2));
setFont(new Font("Helvetica", Font.PLAIN, 14));
add(new Button("Button 1"));
public GridLayout(int rows, int columns)public GridLayout(int rows, int columns, int horizontalGap, int verticalGap)
Sử dụng GridBagLayout
Theo sau là một vài đoạn lệnh tiêu biểu trong một Container có sử dụngGridBagLayout
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);
Bạn có thể sử dụng lại một đối tượng của GridBagConstraints cho nhiều thànhphần khác nhau, ngay cả khi các thành phần đó có sự ràng buộc khác nhau.GridBagLayout rút ra một giá trị ràng buộc và không dùng lạiGridBagConstraints Bạn phải cẩn thận, tuy nhiên, để khởi tạo lại giá trị củamột đối tượng GridBagConstraints làm giá trị mặc định khi cần thiết
Bạn có thể xác lập các giá trị sau:
gridx, gridy
Xác định hàng và cột tại vị trí trên bên tái của thành phần Hầu hết cột trên bêntải có địc chỉ gridx=0, và hàng trên cùng có địa chỉ gridy=0 Sử dụngGridBagConstraints.RELATIVE (giá trị mặc định) để xác định rằng thành phầnđó chỉ ở bên phải hay ở phía dưới
gridwidth, gridheight
xác lập số cột hoặc số hàng trong vùng hiển thị của thành phần những giá trịnày xác định số Cell mà thành phần sử dụng, không phải số Pixel nó sử dụng.Mặc định là 1 Sử dụng GridBagConstraints.REMAINDER để xác định thànhphần đang ở hàng cuối cùng hay cột cuối cùng Sử dụng
Trang 32GridBagConstraints.RELATIVE để xác định bước kế tiếp của thaǹh phần làhàng cuối hay cột cuối cùng
fill
Được sử dụng khi vùng hiển thị của thành phần lớn hơn kich thước thành phầnđòi hỏi để quyết định khi nào hoặc thay đổi kích thước như thế nào các giá trịthích hợp là GridBagConstraints.NONE (mặc định),GridBagConstraints.HORIZONTAL, GridBagConstraints.VERTICAL vàGridBagConstraints.BOTH
ipadx, ipady
xác định phần phụ ở bên trong: bao nhiêu để thêm vào kích thước tối thiểu củathành phần giá trị mặc định là 0 Chiều rộng của thành phần tối thiểu nhất làbằng chiều rộng tối thiểu của nó cộng với ipadx*2 Similarly, chiều cao củathành phần tối thiểu nhất là bằng chiều cao tối thiểu của nó cộng với ipady*2 insets
xác định phần phụ bên ngoài của thành phần mặc định, mỗi thành phần khôngcó phần phụ bên ngoài
anchor
được sử dụng khi thành phần nhỏ hơn vùng hiển thị để quyết định khi nào đặtthành phần gái trị thích hợp là GridBagConstraints.CENTER (mặc định),GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST,GridBagConstraints.EAST, GridBagConstraints.SOUTHEAST,GridBagConstraints.SOUTH, GridBagConstraints.SOUTHWEST,GridBagConstraints.WEST, và GridBagConstraints.NORTHWEST
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;