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 JavaTM Foundation Classes (JFC), có thể được sử dụng hoặc với JDKTM 1.1 hoặc JavaTM 2 platform.
63 trang |
Chia sẻ: haohao89 | Lượt xem: 2701 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Giáo trình java gui swing, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
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 JavaTM Foundation Classes (JFC), có thể được sử dụng hoặc với JDKTM 1.1 hoặc JavaTM 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
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.
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ự.
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,...)
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)
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.
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
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.
Chuyển đổi thành Swing
Hướng dẫn cách chuyển đổi một chương trình sử dụng AWT API 1.1 sang chương trì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ây dựng giao diện đồ hoạ (GUIs). JFC được công bố lần đầu tiên vào năm 1997 trong hội nghị về những nhà phát triển JavaOne, bao gồm những chức năng sau:
Các thành phần Swing
Hỗ trợ Pluggable Look and Feel
Truy cập API
Java 2D API (Java 2 Platform only)
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ào cá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:
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)
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 được Swing API. Tuy nhiên, nếu cần sử dụng JDK 1.1 thì thêm vào Swing API (sử dụng JFC 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ản nà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.
Swing API Version
Tương ứng với phiên bảnJFC 1.1
Tương ứng với phiên bản Java 2 Platform (Standard Edition)
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 Plug-inTM 1.1.1.
Swing 1.1
JFC 1.1 (with Swing 1.1)
v 1.2, v 1.2.1
Phiên bản đầu tiên có đầy đủ Swing 1.1 API hổ trợ để sử dụng các sản phầm thương mại. 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 (with Swing 1.1.1)
v 1.2.2
Thêm vào các tính năng mở rộng, xữ lý nhiều lỗi kỹ thuật, các chức năng mới (API 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ói dù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ói Swing 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, ta nhớ 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ần Swing được thực thi mà hoàn toàn không cần mã nguồn (with absolutely no native code). Kể từ khi các thành phần Swing không còn bị hạn chế trong những khuôn mẫu thô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 so vớ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.1 hay 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 xa cá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 đó.
Có thể dễ dàng thay đổi hành vi hay giao diện của một thành phần Swing trong phương thức điều khiển của nó hoặc tạo ra một lớp con (subclass) của chí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ình trò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àng lấ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ên bả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òn tùy thuộc vào việc đang sử dụng JDK 1.1 hay Java 2 Platform. Nếu sử dụng Java 2 Platform 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 Swing với Java 2 SDK, v 1.2 hay v 1.3:
Nếu chưa có, cài đặt vào máy phiên bản Java 2 Platform.
Tạo một chương trình sử dụng các thành phần Swing.
Biên dịch chương trình.
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 cung cấp (bạn có thể vào địa chỉ này để được hổ trợ: 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ình mẫu mà chúng tôi cung cấp sau đây SwingApplication.java. Cần lưu ý là tên file phải chí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.*;
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);
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 là biên dịch. Việc biên dịch trở nên đơn giản và dể dàng với Java 2 SDKs khi các gói Swing được tích hợp trong phiên bản Standard Edition của Java 2 Platform. Câu lệnh như sau:
javac -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ên dị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 2 Platform.
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.2 hay 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à JDK 1.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ới thiệ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.
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 trình tự các bước sau:
Đả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úng là 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).
Nếu bạn đang sử dụng trình duyệt 1.1 không có Java Plug-in thì cần phải nạp file Swing JAR vào trình duyệt.
Kiểm tra lại xem trình duyệt của bạn đã hoàn chỉnh chưa. Trong phạm vi bài này thì hình dưới đây kiểm chứng cho trình duyệt của bạn là đã đáp ứng hoà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ấy cá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:
Importing Swing packages
Dòng lệnh sau sẽ import gói Swing chính:
import javax.swing.*;
Lư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.*;
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 and feel, ... Đoạn mã in đậm dưới đây sẽ chỉ ra cho bạn cách mà SwingApplication chỉ định “look and feel”:
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) { }
...//Create and show the GUI...
}
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ện việ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ực hiệ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ười sử dụng đóng frame thi ứng dụng 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);
}
}
Xác lập buttons và 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 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(). Nó xuất hiện ở đây giống như sự gợi ý về kỷ thuật hổ trợ trực tiếp (assistive technologies) mà thông qua đó, một label được mô tả như là một button.
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ộ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);
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ên gọ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ành phầ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 button và label vào trong panel có nghĩa là chúng sẽ được điều khiển bởi layout quản lý panel đó.
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 30 pixels 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.
Handling events
SwingApplication chứa 2 event handlers. Một nắm bắt sự kiện kích vào nút lệ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);
}
});
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 giao diệ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 đến một GUI trong cung fmột thời điểm.
Supporting assistive technologies
Hỗ trợ assistive technologies, một thiết bị giống như để đọc màn hình, cung cấp cách thức để xử lý thông tin trên GUI. Hỗ trợ này đã có trong hầu hết các thành phần Swing. Trong SwingApplication có một chỗ đề cập đến kỹ thuật nà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 quan tâ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 JLab