Giáo trình Lập trình Java cơ bản (Phần 2) - Trình độ: Cao đẳng - Trường Cao đẳng nghề kỹ thuật công nghệ
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình Java cơ bản (Phần 2) - Trình độ: Cao đẳng - Trường Cao đẳng nghề kỹ thuật công nghệ", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- giao_trinh_lap_trinh_java_co_ban_phan_2_trinh_do_cao_dang_tr.pdf
Nội dung text: Giáo trình Lập trình Java cơ bản (Phần 2) - Trình độ: Cao đẳng - Trường Cao đẳng nghề kỹ thuật công nghệ
- Bài 3: Applet Mã bài: MĐCNTT 20.1 Mục tiêu: - Trình bày được khái niệm Java Applet - Phân biệt được applet và các ứng dụng Application - Mô tả được chu kỳ sống của một applet - Tạo được applet - Hiển thị được các hình ảnh sử dụng applet. - Truyền được tham số cho Applet. Nội dung chính 1. Khái niệm Java Applet Applet là một chương trình Java có thể chạy trong trình duyệt web. Tất cả các applet đều là các lớp con của lớp ‘Applet’. Lớp Applet thuộc package ‘java.applet’. Lớp Applet bao gồm nhiều phương thức để điều khiển quá trình thực thi của applet. Để tạo applet, bạn cần import hai gói sau: - java.applet - java.awt 2. Cấu trúc của một Applet Một Applet định nghĩa cấu trúc của nó từ 4 sự kiện xảy ra trong suốt quá trình thực thi. Đối với mỗi sự kiện, một phương thức được gọi một cách tự động. Các phương thức này được minh hoạ trong bảng 3.1 Điều quan trọng là không phải lúc nào applet cũng bắt đầu từ ban đầu. Mà nó bắt đầu từ vị trí tiếp theo của quá trình thực thi trước đó. Ngoài những phương thức cơ bản này, còn có những phương thức ‘paint()’ và ‘repaint()’. Phương thức paint() dùng để hiển thị một đường thẳng (line), text, hoặc một hình ảnh trên màn hình. Đối số của phương thức này là đối tượng của lớp Graphics. Lớp này thuộc gói java.awt. Câu lệnh sau được dùng để import lớp Graphics: import java.awt.Graphics; Phương thức Chức năng init() Được gọi trong quá trình khởi tạo applet. Trong quá trình khởi tạo, nó sẽ tạo đối tượng để cung cấp cho applet. Phương thức này được dùng để tải các hình ảnh đồ hoạ, khởi tạo các biến và tạo các đối tượng. start() Được gọi gọi khi một applet bắt đầu thực thi.Một khi quá trình khởi tạo hoàn tất, thì applet được khởi động. Phương thức này được dùng để khởi động lại applet sau khi nó đã ngừng trước đó stop() Được gọi khi ngừng thực thi một applet. Một applet bị ngừng trước khi nó bị huỷ. destroy() Được dùng để huỷ một applet. Khi một applet bị huỷ, thì bộ nhớ, thời gian thực thi của vi xử lý, không gian đĩa được trả về cho hệ thống. 32
- Bảng Các phương thức của một applet Phương thức ‘repaint()’ được dùng khi cửa sổ cần cập nhật lại. Phương thức này chỉ cần một thông số. Tham số này là đối tượng của lớp Graphics. Applet sử dụng phương thức ‘showStatus()’ để hiển thị thông tin trên thanh trạng thái. Phương thức có tham số thuộc kiểu dữ liệu String. Để lấy các thông tin của applet, user có thể overide phương thức ‘getAppletInfo()’ của lớp Applet. Phương thức này trả về 1 đối tượng kiểu String. Các phương thức của applet init(), start(), stop(), destroy(), và paint() được thừa kế từ một applet. Nhưng mặc định những phương thức này không thực thi một thao tác nào cả. Đây là ví dụ đơn giản của applet. Câu lệnh sau tạo một lớp có tên là ‘Applet1’, lớp này sẽ kế thừa tất cả các phương thức và biến của lớp ‘applet’. public class Applet1 extends Applet Phương thức init() và paint() thường được dùng để thực hiện một số hàm để khởi tạo và vẽ applet. Phương thức ‘g.drawstring()’ chỉ ra vị trí mà đoạn văn bản được vẽ ở đâu trên màn hình. Chương trình hiển thị một chuổi ở dòng 70 và cột 80: Chương trình import java.awt.*; import java.applet.*; public class Applet1 extends Applet { int num; public void init() { num = 6; } public void paint (Graphics g) { g.drawString (“Hello to Applet. Chapter ” + num, 70, 80); showStatus (getAppletInfo()); //Hiển thị một chuổi được trả về từ hàm getAppletInfo() trên thanh trạng thái } public String getAppletInfo() //user overrides { return “Created by Aptech”; 33
- } } Sử dụng cú pháp sau để dịch một Applet: javac Applet1.java Để thực thi một applet, ta cần tạo một file HTML. File HTML này sử dụng thẻ applet. Thẻ applet này lấy tham số đầu tiên là đường dẩn của file applet. Thẻ applet có hai thuộc tính sau: - Width - Height Để truyền tham số vào applet, sử dụng param, sau đó là thẻ value. Sau đây là ví dụ của thẻ applet: Lúc này, ta có thể thực thi applet này bằng cách dùng trình xem applet. Đây là công cụ của JDK. Để chạy file HTML trong trình xem applet, ta gõ câu lệnh sau: Appletviewer abc.html // ‘abc.html’ là tên của file HTML Một tuỳ chọn khác của applet là ta thêm thẻ applet như là một dòng chú thích trong đoạn code. Lúc đó, applet được dịch, và thực thi bằng cách sử dụng lệnh sau: Appletviewer Applet1.java Sau đây là kết quả của chương trình trên: Hình Applet 2.1 Sự khác nhau giũa Application và Applet Sau đây là sự khác nhau giữa application và applet: Ø Để thực thi các application chúng ta dùng trình thông dịch Java, trong khi đó applet có thể chạy được trên các trình duyệt (có hổ trợ Java) hay sử dụng công 34
- cụ AppletViewer, công cụ này đi kèm với JDK. Ø Quá trình thực thi của application bắt đầu từ phương thức ‘main()’. Tuy nhiên applet thì không làm như vậy. Ø Các application sử dụng ‘System.out.println()’ để hiển thị kết quả ra màn hình trong khi đó applet sử dụng phương thức ‘drawstring()’ để xuất ra màn hình. Một điều đáng lưu ý là một chương trình Java đơn lẻ thì có thể vừa là application vừa là applet. Chức năng của applet được bỏ qua khi nó được thực thi như là một application và ngược lại. Chương trình sẽ minh họa điều này Chương trình import java.applet.Applet; import java.awt.*; /* */ public class both extends Applet { Button btn; public void init() { btn = new Button ("Click"); } public void paint (Graphics g) { g.drawString ("Applet", 70, 50); } public static void main (String args[]) { both app = new both(); app.init(); System.out.println("Application Main"); } } 35
- Sau khi biên dịch chương trình, nó có thể được thực thi như là một applet bằng cách sử dụng cú pháp sau: appletviewer both.java Kết quả như sau: Hình Applet Nếu chạy chương trình trên như một application, thì sử dụng cú pháp sau: java both Kết quả là: Hình Application Khi applet chạy trên trình duyệt web, đặc điểm này thực sự hữu ích khi bạn muốn tải applet trong một frame mới. Ví dụ: trong applet được tạo để chat, một số website sử dụng một cửa sổ chat riêng biệt để chat. Bạn cũng có thể kết hợp các đặc điểm của frame và applet vào trong một chương trình. 2.2 Những giới hạn bảo mật trên applet Có một số hạn chế mà applet không thể làm được. Bởi vì các applet của Java có thể phá hỏng toàn bộ hệ thống của user. Các lập trình viên Java có thể viết các applet để xoá file, lấy các thông tin các nhân của hệ thống Vì thế, các applet của java không thể làm các việc sau: Ø Không thể đọc hoặc ghi file trên hệ thống file của user. Ø Không thể giao tiếp với các site internet, nhưng chỉ có thể với các trang web có applet mà thôi. Ø Không thể chạy bất cứ chương trình gì trên hệ thống của người đọc. 36
- Ø Không thể tải bất cứ chương trình được lưu trữ trong hệ thống của user. Những giới hạn trên chỉ đúng khi các applet được chạy trên trình duyệt Netscape Navigator hoặc Microsoft Internet Explorer. 3. Chu trình sống của một Applet Chu trình sống của một Applet được mô tả ở sơ đồ dưới đây: Destroy Stop Creation Starting Initalization Hình Chu trình sống của một applet Trước tiên, applet được tạo. Bước kế tiếp là khởi tạo. Điều này xảy ra khi một applet được nạp. Quá trình này bao gồm việc tạo các đối tượng mà applet cần. Phương thức init() được override để cung cấp các hành vi để khởi tạo. Một khi applet được khởi tạo, applet sẽ được khởi động. Applet có thể khởi động ngay cả khi nó đã được ngừng trước đó. Ví dụ, nếu trình duyệt nhảy đến một liên kết nào đó ở trang khác, lúc đó applet sẽ bị ngừng, và được khởi động trở lại khi user quay về trang đó. Sự khác nhau giữa quá trình khởi tạo và quá trình khởi động là một applet có thể khởi động nhiều lần, nhưng qúa trình khởi tạo thì chỉ xảy ra một lần. Phương thức ‘start()’ được override để cung cấp các thao tác khởi động cho applet. Phương thức ‘stop()’ chỉ được gọi khi user không còn ở trang đó nữa, hoặc trang đó đã được thu nhỏ lại ở dưới thanh taskbar. Kế tiếp là phương thức ‘destroy()’. Phương thức này giúp applet dọn dẹp trước khi nó được giải phóng khỏi vùng nhớ, hoặc trước khi truyệt duyệt kết thúc. Phương thức này được dùng để huỷ những luồng (thread) hay quá trình đang chạy. Phương thức ‘destroy()’ khác với phương thức finalize() là phương thức destroy() chỉ dùng cho applet, trong khi finalize() là cách tổng quát để dọn dẹp applet. Phương thức paint() cũng là một phương thức quan trọng khác. Phương thức này cho phép ta hiển thị một cái gì đó trên màn hình. Có thể là text, đường thẳng, màu nền, hoặc hình ảnh. Phương thức này xảy ra nhiều lần trong suốt quá trình applet tồn tại. 37
- Phương thức này thực thi một lần sau khi applet được khởi tạo. Nó sẽ lặp đi lặp lại khi di chuyển từ cửa sổ trình duyệt sang cửa sổ khác. Nó cũng xảy ra khi cửa sổ trình duyệt thay đổi vị trí của nó trên màn hình. Phương thức ‘paint()’ có một tham số. Tham số này là đối tượng của lớp Graphics. Lớp Graphics thuộc lớp java.awt, chúng ta phải import trong đoạn code của applet. Chúng ta có thể sử dụng đoạn mã sau: import java.awt.Graphics; 4 Truyền tham số cho Applet Trong chương trình sau, chúng ta sẽ truyền tham số cho applet. Thành phần nút ‘bNext’ có tên được truyền như là một tham số. Phương thức ‘init()’ sẽ kiểm tra tham số có thên là ‘mybutton’. Sau đó, nó tạo một nút với chuổi đó như là tên của nút. Nếu không có tham số truyền vào, nút đó có tên mặc định là ‘Default’. Bây giờ chúng ta định nghĩa thẻ trong đoạn mã HTML như sau: /* */ Chương trình import java.awt.*; import java.applet.*; /* */ public class Mybutton1 extends Applet { Button bNext; public void init() { /*getParameter returns the value of the specified pareameter in the form of a String object*/ String str = getParameter("mybutton"); //when no parameter is passed 38
- if (str==null) str = new String ("Default"); //when parameter is passed bNext = new Button(str); add (bNext); } } Sau đây là kết quả của chương trình trên: truyền tham số cho applet Bây giờ chúng ta sẽ sử dụng lớp Graphics để vẻ các hình chẳng hạn như: đường thẳng, hình oval, và hình chữ nhật. Chúng ta sẽ học lớp Font trong các phần sau. Lớp này có thể dùng để in văn bản bằng bất cứ font nào. 5. Lớp Graphics Java cung cấp gói AWT cho phép ta vẽ các hình đồ hoạ. Lớp Graphics bao gồm tập hợp rất nhiều phương thức. Nhưng phương thức này được sử dụng để vẽ bất cứ hình nào trong các hình sau: - Oval - Rectangle - Square - Circle - Lines - Text Bạn có thể vẽ những hình này bằng bất cứ màu nào. Frame, Applet và canvas là các môi trường để hiển thị đồ hoạ. Để vẽ bất cứ hình ảnh nào chúng ta cần phải có nền đồ hoạ (Graphical Background). Để có được một nền đồ ho ạ, chúng ta goi phương thức ‘getGraphics()’ hay bất cứ phương thức nào trong các phương thức sau đây: - repaint() Được gọi khi cần vẽ lại những đối tượng đã vẽ. 39
- - update(Graphics g) Được gọi một cách tự động bởi phương thức ‘repaint()’. Phương thức này sẽ xoá những đối tượng đã vẽ, và truyền nó cho đối tượng của lớp Graphics để gọi phương thức ‘paint()’; - paint(Graphics g) Được gọi bởi phương thức update(). Đối tượng được truyền cho phương thức này được dùng để vẽ. Phương thức này dùng để vẽ các hình ảnh đồ hoạ khác nhau. Việc gọi phương thức paint() lặp đi lặp lại thông qua phương thức repaint() sẽ xoá đi các hình đã vẽ trước đó. Để vẽ các hình mới mà vẫn giữ lại những hình đã vẽ trước đó, chúng ta cần override lại phương thức upate(). Public void update (Graphics g) { paint (g); } Ở đây, phương thức update() sẽ không xoá những đối tượng đã vẽ, nhưng chỉ gọi phương thức paint(). Để làm được điều này, nó truyền đối tương của lớp Graphics hoặc GraphicsContext cho phương thức paint(). Ở đây, đối tượng của lớp Graphics là ‘g’. 5.1 Vẽ các chuỗi, các ký tự và các byte Chương trình sau minh hoạ các vẽ các chuỗi, ký tự và các byte. Để vẽ hoặc in một chuỗi, lớp Graphics cung cấp phương thức ‘drawString()’. Cú pháp như sau: DrawString (String str, int xCoor, int yCoor); Ba tham số là: - Chuỗi cần vẽ. - Toạ độ X trên frame, nơi chuỗi cần được vẽ. - Toạ độ Y trên frame, nơi chuỗi cần được vẽ. Để vẽ hoặc xuất các ký tự trên frame, lớp Graphics cung cấp phương thức ‘drawChars’. Cú pháp như sau: DrawChars (char array[], int offset, int length, int xCoor, int yCoor); Chú thích các tham số: - Mảng các ký tự. - Vị trí bắt đầu, nới các ký tự được vẽ. - Số các ký tự cần được vẽ. 40
- - Toạ độ X, nơi các ký tự cần được vẽ. - Toạ độ Y, nơi các ký tự cần được vẽ. Lớp Graphics cung cấp phương thức ‘drawBytes()’ để vẽ hoặc in các byte ra frame. Cú pháp của phương thức này như sau: DrawBytes (byte array[], int offset, int length, int xCoor, int yCoor); 5 tham số của phương thức trên là: - Mảng các byte. - Vị trí offset hay vị trí bắt đầu. - Số byte cần vẽ. - Toạ độ X. - Toạ độ Y. Đối với một ký tự hoặc một mảng các byte, chúng ta có thể in một phần của mảng mà thôi. Ở đây, toạ độ x và y là toạ độ tính theo dòng. Chương trình 6.4 minh hoạ cách vẽ chuỗi, các ký tự và các byte. Chương trình import java.awt.*; public class DrawStrings extends Frame { public DrawStrings() { super ("Draw strings, characters, bytes"); setSize (300, 300); setVisible (true); } public void paint(Graphics g) { g.drawString ("Good Morning", 50, 50); g.drawString ("Good Afternoon", 50, 75); g.drawString ("Good Night", 50, 100); char ch[] = {}; } public static void main (String args[]) { new DrawStrings(); 41
- } } Chương trình trên vẽ chuỗi, ký tự từ một mảng ký tự, và vẽ các byte từ mảng các byte. Bạn phải import gói java.awt để sử dụng các phương thức đồ hoạ có sẳn trong gói này. Ta phải làm điều này vì lớp Graphics nằm trong gói này. Sau đây là kết quả của chương trình trên: Strings, characters và bytes 5.2 Vẽ đường thẳng (Line) và Oval Sau đây là cú pháp của các phương thức được sử dụng để vẽ đường thẳng và hình oval: - drawLine (int x1, int y1, int x2, int y2); - drawOval (int xCoor, int yCoor, int width, int height); - setColor (Color c); - fillOval (int xCoor, int yCoor, int width, int height); Phương thức ‘drawLine()’ nhận các tham số sau: - Toạ độ X, nơi bắt đầu vẽ (x1). - Toạ độ Y, nơi bắt đầu vẽ (y1). - Toạ độ X, nơi kết thúc vẽ (x2). - Toạ độ Y, nơi kết thúc vẽ (y2). Phương thức này bắt đầu vẽ tại toạ độ ‘x1’ và ‘y1’, và kết thúc tại toạ độ ‘x2’ và ‘y2’. Để vẽ nhưng đường thẳng có màu, chúng ta thiết lập một màu nào đó. Phương thức ‘setColor’ dùng để thiết lập màu cho hình ảnh đồ hoạ. Trong chương trình này, chúng ta sử dụng câu lệnh sau để chọn màu xanh: g.setColor (Color.blue); Phương thức ‘drawOval()’ nhận 4 thông số sau: - Toạ độ X. 42
- - Toạ độ Y. - Chiều rộng của hình Oval. - Chiều cao của hình Oval. Đối với hình oval rộng, thì giá trị của chiều rộng lớn hơn chiều cao, và ngược lại đối với hình oval cao. Phương thức ‘fillOval()’ nhận 4 thông số, nhưng nó sẽ tô hình oval. Sử dụng phương thức setColor để tô hình oval; g.setColor(Color.cyan); Ở đây, hình oval sẽ được tô với màu cyan. Lớp Color cung cấp các màu khác nhau mà hệ thống có hổ trợ. 5.3 Vẽ hình chữ nhật (Rectangle) và hình chữ nhật bo góc (Rounded Rectangle) Sau đây là cú pháp của các phương thức được dùng để vẽ hình chữ nhật và hình chữ nhật bo góc: - drawRect (int xCoor, int yCoor, int width, int height); - fillRect (int xCoor, int yCoor, int width, int height); - drawRoundRect (int xCoor, int yCoor, int width, int height, int arcwidth, int archeight); - fillRoundRect (int xCoor, int yCoor, int width, int height, int arcwidth, int archeight); Phương thức ‘drawRect()’ được dùng để vẽ hình chữ nhật đơn giản. Phương thức này nhận 4 tham số sau: - Toạ độ X - Toạ độ Y - Chiều rộng của hình chữ nhật - Chiều cao của hình chữ nhật Phương thức này vẽ hình chữ nhật có chiều rộng và chiều cao cho trước, bắt đầu tại toạ độ X, Y. Chúng ta có thể thiết lập màu của hình chữ nhật. Ở đây, chúng ta chọn màu đỏ. Câu lệnh sẽ như sau: g.setColor (Color.red); Phương thức ‘drawRoundRect()’ vẽ hình chữ nhật có các góc tròn. Phương thức này nhận 6 tham số, trong đó 4 tham số đầu thì giống với phương thức drawRect. Hai tham số khác là: - arcwidth của hình chữ nhật - archeight của hình chữ nhật Ở đây, ‘arcwidth’ làm tròn góc trái và góc phải của hình chữ nhật. ‘archeight’ làm tròn góc trên đỉnh và góc đáy của hình chữ nhật. Ví dụ, arcwidth = 20 có nghĩa là hình chữ 43
- nhật được làm tròn cạnh trái và cạnh phải mỗi cạnh 10 pixel. Tương tự, archeight = 40 sẽ tạo ra hình chữ nhật được làm tròn từ đỉnh đến đáy 20 pixel. Pìxel là đơn vị đo. Nó là đơn vị nhỏ nhất trong vùng vẽ. Để tô hay vẽ hình chữ nhật và hình chữ nhật bo góc, chúng ta sử dụng phương thức ‘fillRect()’ và ‘fillRoundRect()’. Những phương thức này nhận các tham số giống với phương thức drawRect() và drawRoundRect(). Những phương thức này vẽ các hình ảnh với một màu cho trước hoặc mới màu hiện hành. Lệnh sau dùng để vẽ hình với màu xanh: g.setColor(Color.green); 5.4 Vẽ hình chữ nhật 3D và vẽ hình cung (Arc) Sau đây là cú pháp của các phương thức dùng để vẽ hình chữ nhật 3D và hình cung: - draw3Drect (int xCoord, int yCoord, int width, int height, boolean raised); - drawArc(int xCoord, int yCoord, int width, int height, int arcwidth, int archeight); - fillArc(int xCoord, int yCoord, int width, int height, int arcwidth, int archeight); Phương thức ‘draw3Drect()’ nhận 5 tham số. 4 tham số đầu thì tương tự với phương thức để vẽ hình chữ nhật. Tuy nhiên, giá trị của tham số thứ 5 quyết định là hình chữ nạh6t này có 3 chiều hay không. Tham số thứ 5 có kiểu dữ liệu là Boolean. Giá trị này True có nghĩa là hình chữ nhật là 3D. Phương thức ‘drawArc()’ nhận 6 tham số sau: - Toạ độ x - Toạ độ y - Chiều rộng của cung được vẽ. - Chiều cao của cung được vẽ. - Góc bắt đầu. - Độ rộng của cung so với góc ban đầu. Phương thức ‘fillArc()’ cũng nhận 6 tham số giống như phương thức drawArc(), nhưng nó vẽ cung và tô cung với màu hiện thời. 5.5 Vẽ hình PolyLine Chương trình sau lấy các điểm từ hai mảng để vẽ một loạt các đường thẳng. Cú pháp của phương thức này như sau: - drawPolyline (int xArray[], int yArray[], int totalPoints); - g.setFont (new Font(“Times Roman”, Font.BOLD, 15)); Phương thức ‘drawPolyline()’ nhận 3 tham số sau: - Mảng lưu trữ toạ độ x của các điểm. - Mảng lưu trữ toạ độ y của các điểm. 44
- - Tổng số điểm cần vẽ. Để vẽ các đường thẳng ta lấy các điểm từ hai mảng như sau: (array1[0], array2[0]) (array1[1], array2[1]) (array1[2], array2[2]) . Số đường thẳng vẽ được luôn nhỏ hơn số truyền vào thông số thứ 3 của phương thức drawPoyline(). Ví dụ như: totalPoints - 1 Chương trình minh hoạ các vẽ polyline. Chương trình import java.awt.*; class PolyLines extends Frame { int x1[] = {50, 75, 95, 115, 135}; int y1[] = {50, 30, 60, 75, 60}; int x2[] = {67, 82, 95, 120, 135}; int y2[] = {150, 130, 160, 155, 180}; public PolyLines()//constructor { super ("Poly Lines"); setSize (300, 300); setVisible (true); } public void paint (Graphics g) { g.drawPolyline (x1, y1, 5); g.setFont (new Font("Times Roman", Font.BOLD, 15)); g.drawString("Current Color is black", 100, 100); g.setColor(Color.blue); g.drawPolyline (x2, y2, 5); g.drawString ("Current Color is blue", 100, 200); } public static void main (String args[]) { new PolyLines(); } 45
- } Kết quả của chương trình được minh hoạ ở hình sau 5.6 Vẽ và tô đa giác (Polygon) Lớp Graphics cung cấp hai phương thức để vẽ đa giác. Phương thức đầu tiên nhận một đối tượng của lớp Polygon. Phương thức thức 2 lấy hai mảng điểm, và tổng số điểm cần vẽ. Chúng ta sẽ sử dụng phương thức 2 để vẽ đa giác. Cú pháp của drawPolygon() như sau: drawPolygon(int x[], int y[], int numPoints); Cú pháp của fillPolygon() như sau: fillPolygon (int x[], int y[], int numPoints); Chương trình dưới đây lấy các điểm từ 2 mảng để vẽ đa gíac. Phương thức ‘drawPolygon()’ nhận 3 tham số sau giống như phương thức drawPolyline() Ø Mảng lưu trữ toạ độ x của các điểm. Ø Mảng lưu trữ toạ độ y của các điểm. Ø Tổng số điểm cần vẽ. Chương trình import java.awt.*; class PolyFigures extends Frame { int x1[] = {50, 25, 40, 100, 80}; int x2[] = {80, 30, 50, 150, 100, 170}; int y1[] = {50, 70, 120, 120, 80}; int y2[] = {150, 170, 200, 220, 240,190}; 46
- public PolyFigures() { super ("Poly figures"); setSize(300, 300); setVisible (true); } public void paint (Graphics g) { g.drawPolygon (x1, y1, 5); g.setColor (Color.cyan); g.fillPolygon (x2, y2, 6); } public static void main (String args[]) { new PolyFigures(); } } Sau đây là kết quả của chương trình trên: Hình Polygon 6. Điều khiển màu và font 6.1. Điều khiển màu Trong Java, chúng ta điều khiển màu bằng cách dùng 3 màu chính là đỏ (red), xanh lá cây (green), xanh dương (blue). Java sử dụng mô kiểu màu RGB. Đối tượng của lớp 47
- Color chứa 3 số nguyên cho các tham số red, green, blue. Bảng sau trình bày giá trị có thể có của các màu đó: Thành phần Phạmvi Red 0-255 Green 0-255 Blue 0-255 Bảng Phạm vi giá trị của các thành phần màu Sử dụng các giá trị trên để tạo ra một màu tuỳ thích. Cú pháp của hàm dựng để tạo ra một màu như sau: color (int red, int green, int blue); Bảng sau hiển thị các giá trị của các màu thường gặp: Màu Red Green Blue White 255 255 255 Light Gray 192 192 192 Gray 128 128 128 Dark Gray 64 64 64 Black 0 0 0 Pink 255 175 175 Orange 255 200 0 Yellow 255 255 0 Magenta 255 0 255 Bảng Các giá trị RGB Các đối tượng màu khác nhau có thể được tạo bằng những giá trị này. Những đối này có thể được dùng để vẽ hoặc tô các đối tượng đồ hoạ. Ví dụ, để tạo màu hồng, ta dùng lệnh sau: color c = new Color (255, 175, 175); Ta có thể thiết lập màu bằng cách dùng lệnh sau: g.setColor (c); //g là đối tượng của lớp Graphics Sử dụng kết hợp các giá trị RGB để tạo ra một màu tuỳ ý. Để cho dể hơn, lớp Color cung cấp sẳn một số màu. color.white color.black 48
- color.orange color.gray color.lightgray color.darkgray color.red color.green color.blue color.pink color.cyan color.magenta color.yellow Bảng Các màu thường gặp Đoạn mã sau minh hoạ cách tạo một màu tuỳ ý: Color color1 = new Color (230, 140, 60); Color color4 = new Color (90, 210, 130); g.setColor (color1); int myred = color1.getRed (); int mygreen = color1.getGreen (); int myblue = color1.getBlue(); color1 = color1.darker(); color4 = color4.brighter(); 6.2 Điều khiển Font Java cung cấp lớp Font trong gói java.awt cho phép sử dụng các loại font khác nhau. Lớp này bao gồm một số phương thức. Để sử dụng font, chúng ta nên kiểm tra xem hệ thống có hổ trợ hay không. Phương thức’getAllFont()’ trả về tất cả các font mà hệ thống hổ trợ. Trước tiên, khai báo một đối tượng của lớp GraphicsEnvironment như sau: Graphicenvironment ge; ge = GraphicsEnvironment.getLocalGraphicsEnvironment ( ); Đối tượng này sử dụng cú pháp sau để lấy tất cả các font có trong mảng Font: Font f[ ] = ge.getAllFonts( ); Phương thức getAllFont( ) được sử dụng ở đây. Phương thức getAllFont() thuộc lớp GraphicsEnvironment. Đây là lớp trừu tượng, do đó ta không thể khởi tạo lớp này. để truy cập phương thức getAllFont(), chúng ta sử dụng phương thức ‘getLoacalGraphicsEnvironment()’ của lớp GraphicsEnvironment. ge = GraphicsEnvironment.getLocalGraphicsEnvironment ( ); Tham chiếu đến lớp này được gán cho biến ge. Biến này gọi phương thức getAllFont(). Chúng ta sử dụng các font khác nhau để hiển thị các chuổi khác nhau. Phương thức getFont() trả về font mặc định dùng để hiển thị chuỗi, khi không có chọn font nào cả. 49
- Font defaultFont = g.getFont (); //g là đối tượng Graphics g.drawString (“Default Font is ”, 30, 50); Dialog là font mặc định của hệ thống. Để thay đổi font mặc định của hệ thống thành font khác, chúng ta tạo đối tượng của lớp Font. Hàm dựng của Font lấy 3 tham số sau: Ø Tên của font. Ta có thể lấy tên thông qua phương thức getFontList(). Ø Kiểu của font. Ví dụ: Font.BOLD, Font.PLAIN, Font.ITALIC. Ø Kích thước font. Cú pháp sau minh hoạ những thông số trên: Font f1 = new Font (“SansSerif”, Font.ITALIC, 16); g.setFont (f1); Ba tham số được truyền ở đây là: ‘SanSerif’ – tên của font, Font.BOLD – kiểu font, 14 là kích thước của font. Những thông số này tạo ra đối tượng f1. Chúng ta có thể kết hợp 2 kiểu font lại với nhau. Hãy xét ví dụ sau: Font f3 = new Font (“Monospaced”, Font.ITALIC+Font.BOLD, 20); Ở đây kiểu font của f3 vừa đậm, vừa nghiêng. 6.3 Lớp FontMetrics Lớp này xác định kích thước của các ký tự khác nhau thuộc các loại font khác nhau. Xác định kích thước bao gồm chiều cao (height), baseline, descent, và leading. Điều này rất cần thiết vì các ký tự khi in đều chiếm một kích thước riêng. Bạn cần tính kích thước cần thiết khi in các ký tự để tránh các ký tự ghi đè lên nhau. - Height: chiều cao của font. - Baseline (Dòng cơ sở): xác định cơ sở của các ký tự (không kể phần thấp nhất của ký tự) - Ascent: khoảng cách từ đường baseline đến đỉnh của ký tự. - Descent: khoảng các từ baseline đề đáy của ký tự. - Leading: khoảng cách giữa các dòng chữ in. Chương trình 6.7 minh hoạ việc sử dụng các phương thức khác nhau mà lớp FontMetrics có. Trong chương trình này, chúng ta sử dụng các phương thức khác nhau để xem xét chi tiết các loại font khác nhau. Lớp FontMetric là lớp trừu tượng. Phương thức getFontMetrics() có tham số là đối tượng của lớp Font, vì FontMetrics đi đôi với một font nào đó. FontMetrics fm = g.getFontMetrics (f1); Lệnh này tạo đối tượng fm của lớp FontMetrics, cùng với đối tượng f1. Bây giờ, chúng ta sử dụng fm để lấy chi tiết của font. 50
- Các phương thức getHeight, getAscent(), getDescent(), và getLeading() trả về chi tiết của font. Phương thức getFont() của lớp FontMetrics trả về Font mà kết hợp với đối tượng của lớp FontMetrics. Phương thức getName() của lớp Font trả về tên Font. Chương trình import java.awt.*; class FontMetricsUse extends Frame { public FontMetricsUse() { super ("Detail oc Fonts"); setSize (400, 300); setVisible(true); } public void paint (Graphics g) { Font f1 = new Font ("Times Roman", Font.PLAIN, 22); FontMetrics fm = g.getFontMetrics (f1); String name = fm.getFont().getName(); g.drawString ("Details of Font " + name, 30, 50); g.drawString ("Leading: " + String.valueOf (fm.getHeight()), 50, 75); g.drawString ("Leading: " + String.valueOf (fm.getAscent()), 50, 100); g.drawString ("Leading: " + String.valueOf (fm.getDescent()), 50, 125); g.drawString ("Leading: " + String.valueOf (fm.getLeading()), 50, 150); Font f2 = new Font ("DialogInput", Font.PLAIN, 22); fm = g.getFontMetrics (f2); name = fm.getFont().getName(); g.drawString ("Details of Font " + name, 30, 175); g.drawString ("Leading: " + String.valueOf (fm.getHeight()), 50, 200); g.drawString ("Leading: " + String.valueOf (fm.getAscent()), 50, 225); g.drawString ("Leading: " + String.valueOf (fm.getDescent()), 50, 250); g.drawString ("Leading: " + String.valueOf (fm.getLeading()), 50, 275); } public static void main (String args[]) 51
- { new FontMetricsUse (); } } Kết quả của chương trình trên: Lớp FontMetrics Chương trình 6.8 minh hoạ cách lớp FontMetrics được sử dụng để in đoạn văn bản nhiều font, nhiều dòng. Trong chương trình này, chúng ta cần in văn bản nhiều font trên nhiều dòng. Lớp FontMetrics giúp ta xác định khoảng cách cần thiết để in một dòng văn bản cho một font nào đó. Điều này thật cần thiết, bởi vì dòng thứ 2 được in ngay sau dòng thứ nhất. Trước tiên chúng ta in msg1 sử dụng font Monospaced. Sau đó, chúng ta xuất msg2 sử dụng font iaglogInput. Để làm được điều này, chúng ta cần tính khỏng cách cần thiết để xuất msg1. Phương thức stringWidth() của lớp FontMetrics được dùng để tính ra tổng khoảng cách cần thiết để xuất msg1. khi chúng cộng thêm khoảng cách này vào biến x, chúng ta sẽ lấy được vị trí mà chúng ta bắt đầu in đoạn văn bản kế tiếp, msg2. Phương thức setFont() được dùng để thiết lập font để in văn bản. Kế đó, chúng ta xuất msg1 và msg2 trên các dòng khác nhau sử dụng chung 1 font Monospaced. Ở đây, chúng ta cần biết khoảng cách chiều cao của font, để in dòng kế tiếp. Phương thức getHeight() được dùng để làm điều này. Chương trình import java.awt.*; class MultiFontMultiLine extends Frame { 52
- public MultiFontMultiLine() { super ("Multiline Text"); setSize (450, 200); setVisible (true); } public void paint (Graphics g) { Font f1 = new Font ("MonoSpaced", Font.BOLD, 18); Font f2 = new Font ("DialogInput", Font.PLAIN, 14); int x = 20; int y = 50; String msg1 = "Java Language"; String msg2 = "A new approach to programming"; FontMetrics fm = g.getFontMetrics(f1); g.setFont(f1); g.drawString (msg1, x, y); x = x + fm.stringWidth(msg1); g.setFont(f2); g.drawString (msg2, x, y); g.setFont(f1); y = 100; x = 20; int height = fm.getHeight(); g.drawString (msg1, x, y); y += height; g.drawString (msg2, x, y); } public static void main (String args[]) { new MultiFontMultiLine (); } } 53
- Kết quả của chương trình trên: Văn bản được xuất nhiều font, nhiều dòng 6.4. Chọn mode để vẽ Các đối tượng được vẽ bằng cách sử dụng mode vẽ. Khi một đối tượng mới được vẽ, nó sẽ đè lên các hình đã vẽ trước đây. Tương tự, khi các đối tượng được vẽ đi vẽ lại nhiều lần thì chúng sẽ xoá các đối tượng đã vẽ trước đó. Chỉ hiển thị nội dung của đối tượng mới. Để làm cho nội dung củ và nội dung mới đều hiển thị trên màn hình, lớp Graphics cung cấp phương thức setXORMode (Color c); Chương trình 6.9 minh hoạ tiện lợi của của việc sử dụng phương thức setXORMode(). Ở đây, chúng ta sử d ụng phương thức setXORMode() để tô các hình đồ ho ạ khác nhau, mà không đè lên các hình khác. Kết quả là, khi sử dụng mode XOR thì hiển nhiên là tất cả các hình đều hiển thị đầy đủ. Điều này có nghĩa là các hình mới không đè lên các hình củ. Thay vào đó, phần chung giữa các hình sẽ được hiển thị thành một màu khác. Nhưng khi không sử dụng mode XOR, hình mới hoàn toàn che khuất những hình trước đó. Chương trình import java.awt.*; class PaintMode extends Frame { public PaintMode() { super ("Paint Mode"); setSize (300, 300); setVisible (true); } public void paint (Graphics g) { g.setPaintMode (); 54
- g.setColor (Color.blue); g.fillRect (50,50,40, 30); g.setColor (Color.pink); g.fillOval (70, 65, 30, 60); g.setColor (Color.cyan); g.fillRoundRect (90, 80, 70, 50, 20, 30); g.setColor (Color.blue); g.fillRect (50, 150, 40, 30); g.setXORMode (Color.yellow); g.fillOval (70, 165, 30, 60); g.setXORMode (Color.magenta); g.fillRoundRect (90, 180, 60, 40, 50, 20); } public static void main (String args[]) { new PaintMode(); } } Kết quả của chương trình trên: Hình Paint mode 55
- Bài 4: LẬP TRÌNH GIAO DIỆN Mã bài: MĐCNTT 20.4 Mục tiêu: - Nêu được các gói lập trình giao diện trong java. - Trình bày được khái niệm Container và Component. - Trình bày được các đối tượng cơ bản và nâng cao. - Khai báo được đối tượng component. - Khởi tạo đối tượng với các phương thức khởi tạo phù hợp. - Xây dựng được một chương trình đơn giản với giao diện. - Vận dụng các đối tượng để thiết kế và xây dựng được chương trình trong thực tế. 1. Cơ chế lập trình đồ hoạ giao diện Khái niệm : Swing là thư viện các đối tượng để lập trình giao diện đồ hoạ trong Java. Trước đây thư viện AWT là thư viện tiêu chuẩn cho lập trình giao diện, sau này Swing được phát triển kế thừa một số lớp của AWT, hoạt động nhẹ hơn và độc lập với nền tảng thiết bị, và bổ sung thêm nhiều lớp hiển thị mạnh mẽ hơn. Mỗi thành phần trong Swing được gọi là component. Component được chia làm 2 loại: 〈 Loại khung chứa: là những component định nghĩa khung chứa các component khác bên trong. Các component loại này ko thực hiện chức năng hiển thị nội dung, mà chỉ định nghĩa kích thước, nền, cách sắp xếp và hiển thị các component bên trong. Các component khung chứa thường dùng như JFrame, JPanel, JDialog, 〈 Loại hiển thị: là những component đơn vị thực hiện chức năng hiển thị nội dung. Các component hiển thị thường dùng như JLabel, JButton, JList, JTextField, Cách tổ chức code khi lập trình giao diện : Các bạn xem các ví dụ mẫu trên mạng thấy rằng ngta đều tống hết code vào trong 1 file. Điều này giúp bạn dễ nhìn, dễ tiếp cận ở những ví dụ đầu, nhưng cách làm này ko tốt cho sự phát triển về sau, khi mà số lượng component tăng. Sau đây là cách tổ chức code mà mình thường làm: | src |– gui | — | — panel | — | — | — MainPanel.java | — | — Gui.java | — | — ICommon.java | — logic | — | — Logic.java 56
- | — main | — | — Main.java trong đó “ICommon” là interface định nghĩa 3 phương thức initComponent(), addComponent() và addEvent(). Sau này các Panel và Frame sẽ implement interface này để chúng ta thuận tiện cài đặt và thêm các component bên trong, tránh viết lộn xộn. ICommon.java 1 public interface ICommon { 2 void initComp(); 3 void addComp(); 4 void addEvent(); 5 } “Gui” là lớp định nghĩa Frame và thêm Panel vào trong Frame đó. Gui.java 1 public class Gui extends JFrame implements ICommon { 2 private MainPanel mainPanel; 3 4 public Gui { 5 initComp(); 6 addComp(); 7 addEvent(); 8 } 9 10 @Override 11 public void initComp() { 12 // cài đặt ban đầu cho Frame 13 setSize(500, 400); 14 setLayout(new CardLayout()); 15 setLocationRelativeTo(null); 16 setDefaultCloseOperation(EXIT_ON_CLOSE); 17 } 18 19 @Override 20 public void addComp() { 21 // thêm Panel vào Frame 57
- 22 mainPanel = new MainPanel(); 23 add(mainPanel); 24 } 25 26 @Override 27 public void addEvent() { 28 // thêm sự kiện 29 } 30 } “MainPanel” là lớp định nghĩa Panel trong Frame và thêm các component hiển thị trong nó. MainPanel.java 1 public class MainPanel extends JPanel implements ICommon { 2 private JButton btnCount; 3 private JLabel lbCount; 4 private int count; 5 6 public MainPanel { 7 count = 0; 8 initComp(); 9 addComp(); 10 addEvent(); 11 } 12 13 @Override 14 public void initComp() { 15 // cài đặt ban đầu cho Panel 16 setLayout(null); 17 } 18 19 @Override 20 public void addComp() { 21 // cài đặt và thêm Button btnCount vào Panel 58
- 22 btnCount = new JButton(); 23 btnCount.setText("Click"); 24 btnCount.setSize(100, 50); 25 btnCount.setLocation(10, 10); 26 add(btnCount); 27 28 // cài đặt và thêm Label lbCount vào Panel 29 lbCount = new JLabel(); 30 lbCount.setText(count + ""); 31 lbCount.setSize(100, 50); 32 lbCount.setLocation(120, 10); 33 add(lbCount); 34 } 35 36 @Override 37 public void addEvent() { 38 btnCount.addActionListener(new ActionListener() { 39 @Override 40 public void actionPerformed(ActionEvent e) { 41 count++; 42 lbCount.setText(count); 43 } 44 }); 45 } 46 } Còn “Main” chỉ đơn giản là chứa phương thức main() để tạo đối tượng Frame. Main.java 1 public class Main { 2 public static void main(String[] args) { 3 Gui gui = new Gui(); 4 gui.setVisible(true); 5 } 6 } 59
- Cách sử dụng một số component : Các component đều có các phương thức cơ bản sau: setSize(width, height) : cài đặt kích thước. setLocation(x, y) : cài đặt vị trí (lấy vị trí góc trên bên trái làm gốc). setBound(x, y, width, height) : là phương thức ghép chung cả setLocation và setSize. setBackground(color) : cài đặt màu nền. Có 2 cách truyền tham số màu: hoặc là dùng màu được quy ước sẵn trong lớp Color, ví dụ như “Color.white”, hoặc tạo một đối tượng Color, ví dụ “new Color(255, 0, 0)”. Có nhiều cách truyền tham số để khởi tạo đối tượng Color, các bạn tham khảo thêm. setForeground(color) : cài đặt màu chữ. setVisible(boolean) : cài đặt ẩn hay hiện. Thường thì chỉ Frame hay Window bắt buộc phải thiết lập “setVisible(true)”, còn các component khác thì mặc định thiết lập này true rồi. JFrame : setTitle("Title") : cài đặt tên tiêu đề. setLocationRelativeTo(null) : đặt cho cửa sổ xuất hiện ở giữa màn hình. setResizable(false) : cài đặt ko cho phép kéo thả thay đổi kích thước cửa sổ. setDefaultCloseOperation(DO_NOTHING_ON_CLOSE) : lựa chọn ko làm gì khi bạn nhấn nút đóng cửa sổ (nút chéo đỏ). Bạn có thể đặt giá trị “EXIT_ON_CLOSE” để thoát chương trình khi nhấn nút đóng, tuy nhiên cách này ko nên dùng vì ko phải lúc nào nó cũng thoát hoàn toàn. Cách tốt nhất là chúng ta viết xử lý sự kiện riêng (mình sẽ trình bày sau). setLayout(layout) : cài đặt cách bố trí các component trong container. Về các loại Layout mình sẽ trình bày sau. add(component) : sau khi khởi tạo component thì chúng ta thêm component đó vào container, ví dụ “add(mainPanel)”. Lưu ý phải thêm vào khung chứa thì component đó mới được hiển thị. JPanel : setLayout(layout) : tương tự JFrame. add(component) : tương tự JFrame. JLabel : setText("Số lần bấm: " + count) : đặt nội dung text cần hiển thị. setFont(new Font("VNI", Font.PLAIN, 24)) : cài đặt font. setOpaque(true) : mặc định màu nền của Label là trong suốt, đó là bạn phải cài đặt tính đục bằng true thì phương thức cài đặt màu nền setBackground mới có hiệu lực. 60
- setHorizontalAlignment(JLabel.CENTER) : căn text vào giữa Label theo hàng ngang. setVerticalAlignment(JLabel.CENTER) : căn text vào giữa Label theo hàng dọc. Bạn có thể truyền giá trị JLabel.RIGHT để căn sang lề phải. JButton : setText("Bấm vào đây") : đặt nội dung text cần hiển thị. setFont(font) : tương tự. JTextField : setText() : tương tự. setFont() : tương tự. setEnabled(false) : ngăn ko cho chỉnh sửa nội dung text từ bên ngoài. JTextArea : setText() : tương tự. setFont() : tương tự. setEnabled() : tương tự. setLineWrap(true) : cài đặt xuống dòng khi tràn chiều dài khung text, tuy nhiên nó ko cắt nguyên vẹn từ xuống dòng mới đâu. setWrapStyleWord(true) : cho phép cắt nguyên vẹn từ xuống dòng mới. JList : JList là một component hiển thị danh sách các đối tượng, cho phép người dùng chọn được item. Bản thân JList chỉ là thành phần hiển thị. Để nạp dữ liệu cho JList hiển thị, cần có đối tượng model để chứa dữ liệu đó là DefaultListModel. Thông thường để truyền dữ liệu vào model cần có mảng dữ liệu, mảng đó là kết quả của các quá trình tìm kiếm, sắp xếp. Con đường dữ liệu được hiển thị ra JList như sau: ArrayList –> DefaultListModel –> JList Ngoài ra JList thường phải đặt trong một loại component khung chứa là JScrollPane, vì JList ko hỗ trợ thanh cuộn, thanh cuộn là do JScrollPane cung cấp. 1 private DefaultListModel lstModelStudent; 2 private JList lstStudent; 3 private JScrollPane scroll; 4 5 lstStudent = new JList(); 6 scroll = new JScrollPane(lstStudent); 7 add(scroll); 8 updateDataListModelStudent(); 61
- 9 10 private void updateDataListModelStudent() { 11 ArrayList listStudent = manager.getListStudent(); 12 lstModelStudent = new DefaultListModel(); 13 for (Student item : listStudent) { 14 lstModelStudent.addElement(item); 15 } 16 lstStudent.setModel(lstModelStudent); 17 } JList ko có khả năng hiển thị nhiều trường (thuộc tính) của đối tượng trên cùng một hàng. Muốn hiển thị được nhiều trường, bạn chuyển qua dùng component JTable. JTable : Tương tự JList, con đường hiển thị dữ liệu ra màn hình như sau: ArrayList –> DefaultTableModel –> JTable 1 private static final String COLUMN_NAME = {"Mã HS", "Tên", "Tuổi"}; 2 private DefaultTableModel tbModelStudent; 3 private JTable tbStudent; 4 private JScrollPane scroll; 5 6 tbStudent = new JTable(); 7 scroll = new JScrollPane(tbStudent); 8 add(scroll); 9 updateDataTableModelStudent(); 10 11 private void updateDataTableModelStudent() { 12 ArrayList listStudent = manager.getListStudent(); 13 tbModelStudent = new DefaultTableModel(COLUMN_NAME, 0); 14 for (Student item : listStudent) { 15 String[] arr = new String[3]; 16 arr[0] = item.getId(); 17 arr[1] = item.getName(); 18 arr[2] = item.getAge(); 19 tbModelStudent.addRow(arr); 62
- 20 } 21 tbStudent.setModel(tbModelStudent); 22 } JTable chỉ có khả năng hiển thị dữ liệu dạng String, nên với dữ liệu kiểu số hay boolean thì các bạn nhớ chuyển đổi thành chuỗi nhé. JComboBox : Tương tự JList, chỉ khác là nó hiển thị danh sách dạng sổ xuống và có thuộc tính lựa chọn. ArrayList –> DefaultComboBoxModel –> JComboBox 1 private DefaultComboBoxModel cbbModelStudent; 2 private JComboBox cbbStudent; 3 4 cbbStudent = new JComboBox(); 5 add(cbbStudent); 6 updateDataComboBoxModelStudent(); 7 8 private void updateDataComboBoxModelStudent() { 9 ArrayList listStudent = manager.getListStudent(); 10 cbbModelStudent = new DefaultComboBoxModel(); 11 for (Student item : listStudent) { 12 cbbModelStudent.addElement(item); 13 } 14 cbbStudent.setModel(cbbModelStudent); 15 } JComboBox ko cần JScrollPane làm khung. getSelectedIndex() : trả về chỉ số của lựa chọn. JCheckBox : Một số phương thức tương tự như Label. JRadioButton : JProgressBar : setMaximum() : đặt giá trị cực đại của thanh tiến trình. Lưu ý giá trị cực đại cực tiểu này ko liên quan gì đến kích thước width, height của đối tượng JProgressBar. setMinimum() : đặt giá trị cực tiểu. 63
- setValue() : đặt giá trị hiện tại. setStringPainted(true) : khi đặt tham số true, chữ thông báo tiến trình sẽ hiển thị ở giữa thanh tiến trình. Mặc định chữ là phần trăm tiến độ. Xử lý sự kiện: Đóng cửa sổ (đóng Frame) : WindowListener wd = new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { int kq = JOptionPane.showConfirmDialog(Gui.this, "Bạn có muốn thoát không?", "Thông báo", JOptionPane.YES_NO_OPTION); if (kq == JOptionPane.YES_OPTION) { dispose(); } } }; addWindowListener(wd); Click chuột vào Label : 1 label.addMouseListener(new MouseAdapter() { 2 @Override 3 public void mouseReleased(MouseEvent e) { 4 if (e.getButton() == MouseEvent.BUTTON1) { 5 label.setText("Chuột trái click"); 6 } else if (e.getButton() == MouseEvent.BUTTON3) { 7 label.setText("Chuột phải click"); 8 } 9 } 10 }); Nhấn Button : 1 button.addActionListener(new ActionListener() { 2 @Override 3 public void actionPerformed(ActionEvent e) { 4 // blabla 5 } 64
- 6 }); Chọn, bỏ chọn CheckBox : 1 checkBox.addItemListener(new ItemListener() { 2 @Override 3 public void itemStateChanged(ItemEvent e) { 4 if (checkBox.isSelected()) { 5 lbCheck.setText("This CheckBox has checked"); 6 } else { 7 lbCheck.setText("This CheckBox has unchecked"); 8 } 9 } 10 }); 2.Thư viện AWT và Swing AWT là gì AWT là viết tắt của Bộ công cụ cửa sổ trừu tượng. Đây là một API để phát triển GUI hoặc các ứng dụng dựa trên Windows trong Java. Nó đòi hỏi một đối tượng hệ điều hành riêng để thực hiện các chức năng. Ngoài ra, các thành phần AWT rất nặng và cần nhiều không gian bộ nhớ hơn. Hơn nữa, họ mất một thời gian để thực hiện. Hơn nữa, lập trình viên phải nhập gói javax.awt để phát triển GUI dựa trên AWT. Nút, thanh cuộn, trường văn bản, danh sách, hộp thoại và bảng là một số thành phần AWT. Sau khi tạo đối tượng, chúng được đặt trong một thùng chứa. Ngoài ra, nó cung cấp không gian cần thiết cho các thành phần để tải. Thông thường, ứng dụng AWT trong một HĐH có thể trông khác ở một HĐH khác. Xích đu là gì Swing là một bộ công cụ tiện ích GUI cho Java. Nó được xây dựng dựa trên API AWT. Ngoài ra, nó là một phần của Lớp học Java Java Java (JFC). Hơn nữa, Swing cung cấp các thành phần cơ bản như nhãn, hộp văn bản, nút, v.v. cũng như các thành phần nâng cao như bảng được gắn thẻ, bảng và cây. Do đó, Swing cung cấp các thành phần phức tạp hơn AWT. Tại đây, lập trình viên phải nhập gói javax.swing để viết ứng dụng Swing. Gói này cung cấp một số lớp như JButton, JTable, JList, JTextArea và, JCheckBox. Swing là độc lập với nền tảng và các thành phần của nó là nhẹ. Hơn nữa, các thành phần yêu cầu không gian bộ nhớ tối thiểu. Do đó, các ứng dụng Swing thực thi nhanh hơn nhiều. Một mẫu thiết kế phổ biến trong phát triển là mẫu Model, View, Controller (MVC). Xoay theo mô hình này. Nó giúp duy trì mã dễ dàng. Sự khác biệt giữa AWT và Swing Định nghĩa 65
- AWT là tập hợp các thành phần GUI (widget) và các dịch vụ liên quan khác cần thiết cho lập trình GUI trong Java. Swing là một phần của Lớp nền tảng Java (JFC) được sử dụng để tạo các ứng dụng GUI Front end dựa trên Java. Do đó, điều này giải thích sự khác biệt chính giữa AWT và Swing trong Java. Kiểu Các thành phần AWT là nặng trong khi các thành phần Swing là nhẹ. Phụ thuộc nền tảng Một điểm khác biệt lớn giữa AWT và Swing trong Java là AWT phụ thuộc vào nền tảng trong khi Swing độc lập với nền tảng. Trưng bày Hơn nữa, AWT không hỗ trợ giao diện có thể cắm được. Swing hỗ trợ một cái nhìn và cảm giác cắm. Đây cũng là một sự khác biệt quan trọng giữa AWT và Swing trong Java. Các thành phần Ngoài ra, Swing có các thành phần cao cấp hơn AWT. Tốc độ Hơn nữa, việc thực thi AWT chậm hơn. Tuy nhiên, Swing thực hiện nhanh hơn. MVC AWT không hỗ trợ mẫu MVC trong khi Swing hỗ trợ mẫu MVC. Đây là một sự khác biệt khác giữa AWT và Swing. Không gian bộ nhớ Hơn nữa, các thành phần AWT đòi hỏi nhiều không gian bộ nhớ hơn trong khi các thành phần Swing không cần nhiều không gian bộ nhớ. Gói Lập trình viên phải nhập gói javax.awt để phát triển GUI dựa trên AWT. Tuy nhiên, lập trình viên phải nhập gói javax.swing để viết ứng dụng Swing. Phần kết luận Tóm lại, AWT và Swing là hai bộ công cụ để xây dựng Giao diện người dùng đồ họa (GUI) phong phú. Sự khác biệt chính giữa AWT và Swing trong Java là AWT là bộ công cụ phụ trợ giao diện nền tảng, đồ họa và giao diện người dùng gốc Java Java trong khi Swing là bộ công cụ tiện ích GUI cho Java là phần mở rộng của AWT. 3.Container và Component a. Container trong Java Swing - Lập trình Java cơ bản Container là thành phần chủ chốt trong các thành phần của SWING GUI. Một Container cung cấp một không gian, là nơi đặt một thành phần. Một Container trong AWT chính là một Component và nó có thêm khả năng để thêm các thành phần khác vào chính nó. 66
- Khi xem xét về Container, bạn cần chú ý các điểm sau: 1. Các lớp con của Container được gọi là Container. Một số ví dụ về các lớp con của Container là JPanel, JFrame và JWindow. 2. Container chỉ có thể thêm Component vào chính nó 3. Một layout mặc định có mặt trong mỗi container. Layout này có thể bị ghi đè bởi sử dụng phương thức setLayout(). 1. JPanel Lớp này bao gồm các Constructor sau: 1. JPanel(): Tạo một JPanel mới với một double buffer và một Flow Layout. 2. JPanel(boolean isDoubleBuffered): Tạo một JPanel mới với Flow Layout và trình đệm đã xác định. 3. JPanel(LayoutManager layout): Tạo một JPanel mới với Layout Manager đã cho 4. JPanel(LayoutManager layout, boolean is DoubleBuffered): Tạo một JPanel mới với Layout Manager đã cho và trình đệm đã xác định. Ví dụ: mport java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingContainerDemo { private JFrame mainFrame; private JLabel headerLabel; private JLabel statusLabel; private JPanel controlPanel; private JLabel msglabel; public SwingContainerDemo(){ prepareGUI(); } public static void main (String[] args){ SwingContainerDemo swingContainerDemo = new SwingContainerDemo(); swingContainerDemo.showJPanelDemo(); } private void prepareGUI(){ mainFrame = new JFrame("Vi du Java Swing"); 67
- mainFrame.setSize(400,400); mainFrame.setLayout(new GridLayout(3, 1)); mainFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent windowEvent){ System.exit(0); } }); headerLabel = new JLabel("", JLabel.CENTER); statusLabel = new JLabel("",JLabel.CENTER); statusLabel.setSize(350,100); msglabel = new JLabel("Chao mung ban den voi bai huong dan Java Swing.", JLabel.CENTER); controlPanel = new JPanel(); controlPanel.setLayout(new FlowLayout()); mainFrame.add(headerLabel); mainFrame.add(controlPanel); mainFrame.add(statusLabel); mainFrame.setVisible(true); } private void showJPanelDemo(){ headerLabel.setText("Container in action: JPanel"); JPanel panel = new JPanel(); panel.setBackground(Color.magenta); panel.setLayout(new FlowLayout()); panel.add(msglabel); controlPanel.add(panel); mainFrame.setVisible(true); } } 2. JFrame Lớp này bao gồm các Constructor sau: 1. JFrame(): Xây dựng một Frame mới, ban đầu là không nhìn thấy (invisible). 68
- 2. JFrame(GraphicsConfiguration gc): Tạo một Frame trong GraphicsConfiguration đã cho của một thiết bị màn hình và một title trống. 3. JFrame(String title): Tạo một Frame mới, ban đầu là không nhìn thấy (invisible) với title đã cho. 4. JFrame(String title, GraphicsConfiguration gc): Tạo một Frame với title đã cho và GraphicsConfiguration đã cho của một thiết bị màn hình. Ví dụ: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingContainerDemo { private JFrame mainFrame; private JLabel headerLabel; private JLabel statusLabel; private JPanel controlPanel; private JLabel msglabel; public SwingContainerDemo(){ prepareGUI(); } public static void main(String[] args){ SwingContainerDemo swingContainerDemo = new SwingContainerDemo(); swingContainerDemo.showJFrameDemo(); } private void prepareGUI(){ mainFrame = new JFrame("Vi du Java Swing"); mainFrame.setSize(400,400); mainFrame.setLayout(new GridLayout(3, 1)); mainFrame.addWindowListener(new WindowAdapter() { public void windowClosing (WindowEvent windowEvent){ System.exit(0); } }); headerLabel = new JLabel("", JLabel.CENTER); statusLabel = new JLabel("",JLabel.CENTER); 69
- statusLabel.setSize(350,100); msglabel = new JLabel("Chao mung ban den voi bai huong dan Java Swing.", JLabel.CENTER); controlPanel = new JPanel(); controlPanel.setLayout(new FlowLayout()); mainFrame.add(headerLabel); mainFrame.add(controlPanel); mainFrame.add(statusLabel); mainFrame.setVisible(true); } private void showJFrameDemo(){ headerLabel.setText("Container in action: JFrame"); final JFrame frame = new JFrame(); frame.setSize(300, 300); frame.setLayout(new FlowLayout()); frame.add(msglabel); frame.addWindowListener(new WindowAdapter() { public void windowClosing (WindowEvent windowEvent){ frame.dispose(); } }); JButton okButton = new JButton("Open a Frame"); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { statusLabel.setText("Mot Frame duoc hien thi toi nguoi dung."); frame.setVisible(true); } }); controlPanel.add(okButton); mainFrame.setVisible(true); } } Theo dõi chúng tôi miễn phí trên mạng xã 70
- 3. JWindow Lớp này bao gồm các Constructor sau: 1. JWindow(): Tạo một window mà không xác định khung sở hữu nó (owner frame). 2. JWindow(Frame owner): Tạo một window với owner frame đã cho. 3. JWindow(GraphicsConfiguration gc): Tạo một window với GraphicsConfiguration đã cho của một thiết bị màn hình. 4. JWindow(Window owner): Tạo một window với cửa sổ sở hữu nó đã cho (owner window). 5. JWindow(Window owner, GraphicsConfiguration gc): Tạo một window với cửa sổ sở hữu nó đã cho (owner window) và GraphicsConfiguration đã cho của một thiết bị màn hình. Ví dụ: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingContainerDemo { private JFrame mainFrame; private JLabel headerLabel; private JLabel statusLabel; private JPanel controlPanel; private JLabel msglabel; public SwingContainerDemo(){ prepareGUI(); } public static void main (String[] args){ SwingContainerDemo swingContainerDemo = new SwingContainerDemo(); swingContainerDemo.showJWindowDemo(); } private void prepareGUI(){ mainFrame = new JFrame("Vi du Java Swing"); mainFrame.setSize(400,400); mainFrame.setLayout(new GridLayout(3, 1)); mainFrame.addWindowListener(new WindowAdapter() { 71
- public void windowClosing (WindowEvent windowEvent){ System.exit(0); } }); headerLabel = new JLabel("", JLabel.CENTER); statusLabel = new JLabel("",JLabel.CENTER); statusLabel.setSize(350,100); msglabel = new JLabel("Chao mung ban den voi bai huong dan Java Swing." , JLabel.CENTER); controlPanel = new JPanel(); controlPanel.setLayout(new FlowLayout()); mainFrame.add(headerLabel); mainFrame.add(controlPanel); mainFrame.add(statusLabel); mainFrame.setVisible(true); } private void showJWindowDemo(){ headerLabel.setText("Container in action: JWindow"); final MessageWindow window = new MessageWindow(mainFrame, "Chao mung ban den voi bai huong dan Java Swing."); JButton okButton = new JButton("Open a Window"); okButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { window.setVisible(true); statusLabel.setText("Mot Window duoc hien thi toi nguoi dung."); } }); controlPanel.add(okButton); mainFrame.setVisible(true); } class MessageWindow extends JWindow{ private String message; public MessageWindow (JFrame parent, String 72
- message) { super(parent); this.message = message; setSize(300, 300); setLocationRelativeTo(parent); } public void paint (Graphics g) { super.paint(g); g.drawRect(0,0,getSize().width - 1,getSize().height - 1); g.drawString(message,50,150); } } } 3.Container và Component 3.1. Container Container là vùng mà bạn có thể đặt các thành phần của bạn vào đó. Bất cứ vật gì mà kế thừa từ lớp Container sẽ là một container. Applet là một container, applet được dẫn xuất từ panel, lớp panel lại được dẫn xuất từ lớp Container. Một container có thể chứa nhiều phần tử, các phần tử này có thể được vẽ hay được tô màu tuỳ thích. Bạn hãy xem container như một cửa sổ. Đã là cửa sổ thì phải có khung (frame), pane, latch, hook, và các thành phần có kích thước nhỏ hơn. Gói java.awt chứa một lớp gọi là Container. Lớp này trực tiếp hay gián tiếp phát sinh ra hai container được sử dụng phổ biến nhất là Frame và Panel. Frame và Panel là các container thường được sử dụng. Frame là các cửa sổ được tách riêng nhau nhưng ngược lại panel là các vùng được chứa trong một cửa sổ. Panel không có các đường viền, chúng được trình bày trong một cửa sổ do trình duyệt hay appletviewer cung cấp. Appletviewer là một công cụ được JDK hỗ trợ để xem các applet. Frame là lớp con của Window. Chúng được trình bày trong một cửa sổ độc lập, cửa sổ này có chứa các đường viền xung quanh. a. Frame Frame không phụ thuộc vào applet và trình duyệt. Frame có thể hoạt động như một container hay như một thành phần (component). Bạn có thể sử dụng một trong những constructor sau để tạo một frame: 1. Frame(): Tạo một frame vô hình (không nhìn thấy được) 2. Frame(String, title): Tạo một frame với nhan đề trống. 73
- Ví dụ import java.awt.*; class FrameDemo extends Frame { public FrameDemo(String title){ super(title); } public static void main(String args[]){ FrameDemo f=new FrameDemo(“I have been Frameed!!!”); f.setSize(300,200); f.setVisible(true); } } Kết quả thu được b. Panel: Panel được sử dụng để nhóm một số các thành phần lại với nhau. Cách đơn giản nhất để tạo một panel là sử dụng hàm constructor của nó, hàm Panel(). import java.awt.*; class Paneltest extends Panel { 74
- public static void main(String args[]){ Paneltest p=new Paneltest(); Frame f=new Frame(“Testing a Panel”); f.add(p); f.setSize(300,200); f.setVisible(true); } public Paneltest(){ } } Panel không thể được nhìn thấy trực tiếp. Do đó, chúng ta cần thêm panel đến một frame. Vì vậy ta cần tạo một frame mới và thêm Panel mới được tạo này vào nó. Tuy nhiên, frame sẽ không nhìn thấy được, và không có kích thước. Chúng ta sử dụng hai phương thức trong phương thức main – setSize() và setVisible() để thiết lập kích thước và hiển thị frame. Kết quả thu được: c. Dialog Lớp ‘Dialog’ tương tự như lớp Frame, nghĩa là Dialog là lớp con của lớp Window. Đối tượng dialog được tạo như sau: Frame myframe=new Frame(“My frame”); // calling frame String title = “Title”; 75
- boolean modal = true; // whether modal or not Dialog dlg=new Dialog(myframe, title, modal); Số hạng ‘modal’ chỉ ra rằng dialog sẽ ngăn chặn bất kỳ tương tác nào xảy đến với các cửa sổ được mở khác, trong khi dialog đang được hiển thị trên màn hình. Kiểu hộp thoại này ngăn chặn người dùng tương tác với các cửa sổ khác trên màn hình, cho tới khi dialog được đóng lại. Một component có thể được đặt trên giao diện người dùng, có thể được thay đổi kích thước hay làm cho nhìn thấy được. Ví dụ được dùng phổ biến nhất là Textfield, Label, Checkbox, Textarea v.v Các thành phần cao cấp khác như Scrollbar, Scrollpane và Dialog cũng tồn tại. Tuy nhiên chúng không được sử dụng thường xuyên. 3.2. Component a. Label Đối tượng của lớp Label là một thành phần để đặt văn bản trong một vùng chứa. Nó được sử dụng để hiển thị một dòng văn bản chỉ đọc. Văn bản có thể được thay đổi bởi một ứng dụng nhưng người dùng không thể chỉnh sửa trực tiếp. Ví dụ: import java.awt.Frame; import java.awt.Label; public class LabelExample { public static void main(String args[]) { Frame f = new Frame("Label Example"); Label l1, l2; l1 = new Label("First Label."); l1.setBounds(50, 100, 100, 30); l2 = new Label("Second Label."); l2.setBounds(50, 150, 100, 30); f.add(l1); f.add(l2); f.setSize(400, 200); f.setLayout(null); f.setVisible(true); } } Kết quả thu được: 76
- b. Button Lớp Button trong Java AWT được sử dụng để tạo button được gắn nhãn có triển khai độc lập nền tảng. Ví dụ: import java.awt.Button; import java.awt.Frame; public class ButtonExample { public static void main(String[] args) { Frame f = new Frame("Button Example"); Button b = new Button("Click Here"); b.setBounds(50, 100, 80, 30); f.add(b); f.setSize(400, 200); f.setLayout(null); f.setVisible(true); } } Kết quả thu được: 77
- 3. Textfield Đối tượng của một lớp TextField là một thành phần văn bản cho phép chỉnh sửa văn bản một dòng. Nó kế thừa lớp TextComponent. Ví dụ: import java.awt.*; class TextFieldExample{ public static void main(String args[]){ Frame f= new Frame("TextField Example"); TextField t1,t2; t1=new TextField("Welcome to Javatpoint."); t1.setBounds(50,100, 200,30); t2=new TextField("AWT Tutorial"); t2.setBounds(50,150, 200,30); f.add(t1); f.add(t2); f.setSize(400,400); f.setLayout(null); f.setVisible(true); } } Kết quả thu được: 78
- 4. TextArea Đối tượng của một lớp TextArea là một vùng nhiều dòng để hiển thị văn bản. Nó cho phép chỉnh sửa văn bản nhiều dòng. Nó kế thừa lớp TextComponent. Ví dụ: import java.awt.*; public class TextAreaExample { TextAreaExample(){ Frame f= new Frame(); TextArea area=new TextArea("Welcome to javatpoint"); area.setBounds(10,30, 300,300); f.add(area); f.setSize(400,400); f.setLayout(null); f.setVisible(true); } public static void main(String args[]) { new TextAreaExample(); } } Kết quả thu được: 79
- 5. CheckBox Lớp Checkbox được sử dụng để tạo một hộp kiểm. Nó được sử dụng để biến một tùy chọn on (true) hoặc off (false). Click vào một hộp kiểm thay đổi trạng thái của nó từ "on" thành "off" hoặc từ "off" thành "on". import java.awt.*; import java.awt.event.*; public class CheckboxExample { CheckboxExample(){ Frame f= new Frame("CheckBox Example"); final Label label = new Label(); label.setAlignment(Label.CENTER); label.setSize(400,100); Checkbox checkbox1 = new Checkbox("C++"); checkbox1.setBounds(100,100, 50,50); Checkbox checkbox2 = new Checkbox("Java"); checkbox2.setBounds(100,150, 50,50); f.add(checkbox1); f.add(checkbox2); f.add(label); checkbox1.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { label.setText("C++ Checkbox: " 80
- + (e.getStateChange()==1?"checked":"unchecked")); } }); checkbox2.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { label.setText("Java Checkbox: " + (e.getStateChange()==1?"checked":"unchecked")); } }); f.setSize(400,400); f.setLayout(null); f.setVisible(true); } public static void main(String args[]) { new CheckboxExample(); } } Kết quả thu được: 6. CheckBoxGroup Đối tượng của lớp CheckboxGroup được sử dụng để nhóm một tập hợp các CheckBox lại với nhau. Tại một thời điểm chỉ có một nút hộp kiểm được phép ở trạng thái "on" và các nút hộp kiểm còn lại ở trạng thái "off". Nó kế thừa lớp Object. 81
- Ví dụ: import java.awt.Checkbox; import java.awt.CheckboxGroup; import java.awt.Frame; import java.awt.Label; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; public class CheckBoxExample2 { public CheckBoxExample2() { Frame f = new Frame("Ví dụ AWT CheckboxGroup"); final Label label1 = new Label(); label1.setBounds(50, 50, 200, 20); CheckboxGroup cbg = new CheckboxGroup(); Checkbox checkbox1 = new Checkbox("C++", cbg, false); checkbox1.setBounds(100, 80, 50, 20); Checkbox checkbox2 = new Checkbox("Java", cbg, true); checkbox2.setBounds(100, 100, 50, 20); f.add(checkbox1); f.add(checkbox2); f.add(label1); checkbox1.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { label1.setText("C++ Checkbox: " + (e.getStateChange() == 1 ? "checked" : "unchecked")); } }); checkbox2.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { label1.setText("Java Checkbox: " + (e.getStateChange() == 1 ? "checked" : "unchecked")); } }); f.setSize(400, 200); 82
- f.setLayout(null); f.setVisible(true); } public static void main(String args[]) { new CheckBoxExample2(); } } Kết quả thu được: 7. Choice Đối tượng của lớp Choice được sử dụng để hiển thị menu popup của các lựa chọn. Lựa chọn do người dùng lựa chọn được hiển thị ở đầu trình đơn. Nó kế thừa lớp Component. Ví dụ: import java.awt.*; import java.awt.event.*; public class ChoiceExample { ChoiceExample(){ Frame f= new Frame(); final Label label = new Label(); label.setAlignment(Label.CENTER); label.setSize(400,100); Button b=new Button("Show"); b.setBounds(200,100,50,20); final Choice c=new Choice(); 83
- c.setBounds(100,100, 75,75); c.add("C"); c.add("C++"); c.add("Java"); c.add("PHP"); c.add("Android"); f.add(c);f.add(label); f.add(b); f.setSize(400,400); f.setLayout(null); f.setVisible(true); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String data = "Programming language Selected: "+ c.getItem(c.getSelectedIndex()); label.setText(data); } }); } public static void main(String args[]) { new ChoiceExample(); } } Kết quả thu được: 84
- 8. List Đối tượng của lớp List thể hiện một danh sách các mục văn bản. Với sự giúp đỡ của đối tượng List, người dùng có thể chọn một trong hai mục hoặc nhiều mục. Nó kế thừa lớp Component. Ví dụ: import java.awt.*; import java.awt.event.*; public class ListExample { ListExample(){ Frame f= new Frame(); final Label label = new Label(); label.setAlignment(Label.CENTER); label.setSize(500,100); Button b=new Button("Show"); b.setBounds(200,150,80,30); final List l1=new List(4, false); l1.setBounds(100,100, 70,70); l1.add("C"); l1.add("C++"); l1.add("Java"); l1.add("PHP"); final List l2=new List(4, true); l2.setBounds(100,200, 70,70); l2.add("Turbo C++"); l2.add("Spring"); l2.add("Hibernate"); l2.add("CodeIgniter"); f.add(l1); f.add(l2); f.add(label); f.add(b); f.setSize(450,450); f.setLayout(null); f.setVisible(true); b.addActionListener(new ActionListener() { 85
- public void actionPerformed(ActionEvent e) { String data = "Programming language Selected: "+l1.getItem(l1.getSelectedIndex()); data += ", Framework Selected:"; for(String frame:l2.getSelectedItems()){ data += frame + " "; } label.setText(data); } }); } public static void main(String args[]) { new ListExample(); } } Kết quả thu được: 4.Quản lý Layout Layout (bố cục) nghĩa là sự bố trí sắp xếp các thành phần bên trong Container theo một phương thức nhất định. Nói cách khác, chúng ta đặt các thành phần tại một vị trí cụ thể bên trong Container. Tác vụ bố trí này được thực hiện tự động bởi LayoutManager. Nếu chúng ta không sử d ụng LayoutManager thì các thành phần cũng sẽ được tự động bố trí bởi LayoutManager mặc định. Tuy nhiên, để xử lý 86
- một số lượng thành phần lớn với kích cỡ, hình dạng khác nhau và muốn chúng được bố trí theo cách bạn muốn thì việc sử dụng các LayoutManager là cần thiết. LayoutManager được liên kết với mỗi đối tượng Container. Mỗi LayoutManager là một đối tượng của lớp mà triển khai LayoutManager Interface. Dưới đây là các Interface mà định nghĩa các tính năng của LayoutManager: - LayoutManager Interface - LayoutManager2 Interface 4.1. Giới thiệu về LayoutManager Interface LayoutManager Interface được sử dụng để định nghĩa giao diện cho các lớp mà biết cách để bố trí các Container. Cú pháp khai báo cho java.awt.LayoutManager là: ? 1 public interface LayoutManager 4.1. LayoutManager Interface này có các phương thức sau: void addLayoutComponent(String name, Component comp): Nếu layout manager sử dụng một chuỗi mỗi thành phần, thêm thành phần comp tới layout, liên kết nó với chuỗi được xác định bởi tên. void layoutContainer(Container parent): Bố trí Container đã cho. Dimension minimumLayoutSize(Container parent): Tính toán các chiều kích cỡ tối thiểu cho Container đã xác định, mà đã cung cấp các thành phần được chứa trong đó. Dimension preferredLayoutSize(Container parent): Tính toán các chiều kích cỡ được ưu tiên cho Container đã xác định, mà đã cung cấp các thành phần được chứa trong đó. void removeLayoutComponent(Component comp): Xóa thành phần đã cho từ layout. 4.2. Giới thiệu về LayoutManager2 Interface LayoutManager2 Interface được sử dụng để định nghĩa giao diện cho các lớp mà biết cách bố trí các Container dựa trên một đối tượng ràng buộc Constraint. Cú pháp khai báo cho java.awt.LayoutManager2 là: ? 1 public interface LayoutManger2 2 extends LayoutManager LayoutManager2 Interface bao gồm các phương thức sau: void addLayoutComponent(Component comp, Object constraints): Thêm thành phần comp đã cho tới layout, bởi sử dụng đối tượng ràng buộc Constraint. float getLayoutAlignmentX(Container target): Trả về căn chỉnh theo trục x. float getLayoutAlignmentY(Container target): Trả về căn chỉnh theo trục y. void invalidateLayout(Container target): Vô hiệu hóa layout, chỉ rằng nếu Layout Manager đã lưu thông tin thì nó nên được loại bỏ. 87
- Dimension maximumLayoutSize(Container target): Tính toán các chiều kích cỡ tối đa cho Container đã xác định, mà đã cung cấp các thành phần chứa trong đó. Các lớp Layout Manager trong Java Swing Bảng sau liệt kê danh sách các lớp được sử dụng phổ biến, bạn truy cập link để tìm hiểu chi tiết: STT LayoutManager & Mô tả 1 Lớp BoxLayout Lớp BoxLayout, trong java.swing package, được sử dụng để sắp xếp các thành phần hoặc theo chiều dọc hoặc theo chiều ngang 2 Lớp BorderLayout BorderLayout sắp xếp các thành phần để phù hợp với 5 miền: đông, tây, nam, bắc và trung tâm 3 Lớp CardLayout CardLayout xem xét mỗi thành phần trong Container như là một card. Chỉ có một card là nhìn thấy tại một thời điểm 4 Lớp FlowLayout FlowLayout là Layout mặc định. Nó bố trí các thành phần trong luồng định hướng (trong một line, line sau nối tiếp line trước) 5 Lớp GridLayout GridLayout quản lý các thành phần trong lưới hình chữ nhật. Một thành phần được hiển thị trong mỗi hình chữ nhật con. 6 Lớp GridBagLayout GridBagLayout là một lớp quản lý layout linh động. Đối tượng của GridBagLayout căn chỉnh các thành phần theo chiều dọc, ngang hoặc theo baseline của chúng mà không yêu cầu các thành phần phải có cùng kích cỡ. 7 Lớp GroupLayout GroupLayout nhóm các thành phần theo cấu trúc thứ bậc để đặt chúng trong một Container 8 Lớp SpringLayout SpringLayout đặt vị trí các con của Container liên kết với nó tuân theo một tập hợp các ràng buộc. 88
- 5.Lập trình GUI cơ bản 5.1. GUI=Graphic User Interface – mô hình giao tiếp kiểu tương tác giữa ứng dụng và user dạng đồ họa Mỗi ngôn ngữ hỗ trợ cách tạo GUI khác nhau: C#, VB, VC++ lập trình viên phải phụ thuộc vào công cụ trong java, Python, Flex thì việc code lại cực kỳ đơn giản rất ít khi cần sử dụng công cụ kéo thả GUI = Container + Compnents. 6.Lập trình GUI nâng cao 6.1. Các thành phần được giới thiệu 6.2. Vùng văn bản (TextArea). Cho phép người dùng nhập vào nhiều dòng văn bản. Tạo đối tượng TextArea 89
- TextArea(); TextArea(int rows, int columns); TextArea(String s); TextArea(String s, int rows, int columns); Các phương thức khác giống như TextField // Cac import can thiet public class DemoTextArea extends Applet implements ActionListener { private TextArea textArea1, textArea2; private Button copy; public void init() { textArea1 = new TextArea("Sample Text", 5, 20); textArea2 = new TextArea(5, 20); copy = new Button("Copy >>>"); setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); copy.addActionListener(this); add(textArea1); add(copy); add(textArea2); } public void actionPerformed(ActionEvent event) { textArea2.setText(textArea1.getText()); } } 90
- 6.3. Khung vẽ (Canvas) - Khung vẽ là một vùng chuyên để vẽ đồ hoạ, nó không bị che bởi các thành phần giao diện khác. - Khung vẽ có thể xử lý các sự kiện giống như Applet. - Để sử dụng khung vẽ, cần tạo một lớp khác dẫn xuất từ Canvas và cài đặt nạp chồng phương thức paint(). - Nên gọi setSize cho khung vẽ. Toạ độ vẽ là (0,0) tính trong khung vẽ. // Cac import can thiet public class DemoCanvas extends Applet implements ActionListener { private Button rectButton; private Button circleButton; private MyCanvas canvas; public void init() { setLayout(new BorderLayout()); rectButton = new Button("Draw Rectangle"); circleButton = new Button("Draw Circle"); rectButton.addActionListener(this); circleButton.addActionListener(this); Panel panel = new Panel(); panel.add(rectButton); panel.add(circleButton); canvas = new MyCanvas(); canvas.setBackground(Color.lightGra) ; add(panel, BorderLayout.NORTH); add(canvas, BorderLayout.CENTER); } public void actionPerformed(ActionEvent event) { if (event.getSource() == rectButton) canvas.draw(1); else if (event.getSource() == circleButton) canvas.draw(2); } 91
- } class MyCanvas extends Canvas { private int shape; public void paint(Graphics g) { Dimension size = getSize(); g.setColor(Color.BLUE); if (shape == 1) g.fillRect(40, 40, size.width-80, size.height-80); else if (shape == 2) g.fillOval(40, 40, size.width-80, size.height-80); } public void draw(int shape) { this.shape = shape; repaint(); } } 6.4. Thanh trượt (Scroll bar) Thanh trượt cho phép điều chỉnh giá trị trong một khoảng nhất định 92
- Để nghe sự kiện trên thanh trượt cần cài đặt giao tiếp AdjusmentListener. Nạp chồng adjustmentValueChanged() 6.5. Thanh trượt (Scroll bar) Bài tập: Viết chương trình cho phép điều khiển font chữ thông qua thanh trượt. Khi thanh trượt thay đổi thì cỡ chữ hiển thị (drawString) thay đổi theo. 6.6. Khung cuộn (ScrollPane) Khung cuộn là một container cho phép chứa thành phần GUI có kích thước lớn hơn chính nó. Bài tập: Viết chương trình cho phép vẽ trong m ột canvas có độ rộng lớ n hơn kích thước của applet. Đặt canvas vào trong một scroll pane. 93
- 6.7. Bố cục nâng cao CardLayout Sắp xếp các thành phần giống như các lá bài. Tại mỗi thời điểm chỉ lá bài đầu tiên được hiển thị. Mỗi lá bài thường là một Panel và trên đó có thể dùng bất kỳ một bố cục nào. GridBagLayout Sắp xếp các thành phần trong một lưới giống như GridLayout. Các thành phần có thể có kích thước khác nhau. Null Layout Dùng lệnh setLayout(null); Phải đặt vị trí và kích thước cho các thành phần thông qua các hàm: setLocation, setSize, setBounds. 6.8. Khung chứa Frame Frame được dùng để xây dựng các ứng dụng GUI chạy độc lập. Frame là một cửa sổ có thanh tiêu đề và các đường biên. Bố cục mặc định của Frame là BorderLayout. Frame kế thừa từ Window, nó có thể nghe các sự kiện xảy ra trên cửa sổ khi cài đặt giao tiếp WindowListener. Các ứng dụng độc lập thường tạo ra cửa sổ kế thừa từ lớp Frame. Ví dụ về Frame import java.awt.*; import java.awt.event.*; public class DemoFrame { public static void main(String[] args) { Frame frame = new Frame(“Example on Frame”); Label label = new Label("This is a label in Frame", 94
- Label.CENTER); frame.add(label, BorderLayout.CENTER); frame.setSize(500,500); frame.setVisible(true); frame.addWindowListener(new MyWindowListener()); } } // Lop nghe doc lap (external listener) class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } import java.awt.*; import java.awt.event.*; public class DemoFrame2 { public static void main(String[] args) { MyFrame myFrame = new MyFrame("Example on my frame"); myFrame.setSize(250, 300); myFrame.setVisible(true); 95
- myFrame.addWindowListener(new WindowAdapter() {// Lop nghe noi khong ten (anonymous inner class listener) public void windowClosing(WindowEvent e) { System.exit(0); } }); } } Ví dụ về Frame class MyFrame extends Frame { public MyFrame(String title) { super(title); } public void paint(Graphics g) { g.setColor(Co lor.BLUE); g.fillOval(40, 40, 80, 80); } } 6.9. Cài đặt listener. Lớp nghe độc lập: Lớp nghe sự kiện là một lớp khác với lớp chứa giao diện. Lớp nghe nội không tên: Lớp nghe không có tên, chỉ định nghĩa phương thức xử lý sự kiện (actionPerformed) Lớp nghe nội có tên: Lớp nghe được khai báo nằm trong một lớp khác. Lớp nội có thể truy xuất các phương thức, dữ liệu của lớp chứa nó (outer class) Dùng lớp nghe nội có tên là một kĩ thuật phổ biến. 9.10. Khung chứa Frame Tạo các thành phần GUI và xử lý sự kiện trong Frame cũng giống như trong Applet. Chú ý: 96
- Frame không có các phương thức init, start như trong Applet. Các ứng dụng độc lập dùng Frame phải có hàm main và được chạy trực tiếp bằng lệnh java Cần có lệnh setSize, setVisible(true) để có thể hiển thị Frame. Ở cuối chương trình nên có lệnh: System.exit(0); Bài tập Bài 1: Viết lại chương trình Tính Tổng 2 số sử dụng Frame. Bài 2: Mở rộng bài 1 để khi người dùng đóng cửa sổ thì sẽ xuất hiện một thông báo xác nhận việc đóng. Dùng JOptionPane.showConfirmDialog Thực đơn (Menu) Object MenuComponent Menultem MenuBar Menu CheckboxMenultem Menu MenuBar Separator Menultem Tạo thực đơn Tạo và gắn MenuBar vào cửa sổ MenuBar menuBar = new MenuBar(); 97
- myFrame.setMenuBar(menuBar); Tạo Menu và gắn vào MenuBar Menu fileMenu = new Menu(“File”); menuBar.add(fileMenu); Tạo MenuItem và gắn vào Menu MenuItem openItem = new MenuItem(“Open”); fileMenu.add(openItem); Tạo đường phân cách fileMenu.addSeparator(); Xử lý sự kiện trên các MenuItem Đối tượng nghe các MenuItem phải cài đặt giao tiếp ActionListener Tham khảo thêm về CheckboxMenuItem PopupMenu Dialog cũng là một cửa sổ, thường dùng để nhập hoặc hiển thị thông tin với người dùng. Hai loại hộp thoại Modal: Phải đóng hộp thoại trước khi chuyển sang cửa sổ khác. Modaless: Có thể giữ nguyên hộp thoại và chuyển sang cửa sổ khác. Dialog kế thừa từ lớp Window, nó có bố cục mặc định là BorderLayout. Hộp thoại có thể chứa các thành phần GUI và xử lý các sự kiện như một cửa sổ bình thường. Ví dụ về Frame, Menu và Dialog import java.awt.*; 98
- import java.awt.event.*; public class DemoFrame3 { public static void main(String[] args { MyFrame myFrame = new MyFrame("Example on my frame"); myFrame.setSize(500, 400); myFrame.setVisible(true); myFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; } } Ví dụ về Frame, Menu và Dialog. class MyFrame extends Frame implements ActionListener { private MenuBar menuBar; private Menu menu; private MenuItem circleItem, rectItem; public MyFrame(String title) { super(title); menuBar = new MenuBar();setMenuBar(menuBar); menu = new Menu("Draw"); menuBar.add(menu); circleItem = new MenuItem("Circle"); rectItem = new MenuItem("Rectangle"); menu.add(circleItem); menu.add(rectItem); circleItem.addActionListener(this); rectItem.addActionListener(this); 99
- } } Ví dụ về Frame, Menu và Dialog. public void actionPerformed(ActionEvent e) { if (e.getSource() == circleItem) { MyDialog dialog = new MyDialog(this, "Modeless Dialog: Circle", false); } } } class MyDialog extends Dialog { MyDialog(Frame parent, String title, boolean isModel) { super(parent, title, isModel); add(new Label("Hi, I am a dialog"), BorderLayout.CENTER); setSize(300, 200); setVisible(true); addWindowListener(new MyDialogListener(this)); } }; // Co the dat lop nay lam lop noi (inner class) cua lop MyDialog class MyDialogListener extends WindowAdapter { Dialog dialog; MyDialogListener(Dialog dia) { dialog = dia; } public void windowClosing(WindowEvent e) { dialog.setVisible(false); 100
- dialog.dispose(); } } Giới thiệu JFC JFC (Java Foundation Class) Là thư viện lập trình giao diện đồ hoạ phát triển dựa trên thư viện AWT JFC cung cấp khả năng tạo giao diện linh động, uyển chuyển hơn so với AWT JFC có sẵn trong các phiên bản từ Jdk 1.2 trở đi. Các lớp của JFC nằm trong gói javax.swing Các thành phần Swing Các thành phần GUI của Swing thường bắt đầu bởi chữ J: JButton, JLabel, JTextArea, JFrame, JPanel, JCheckBox, JRadioButton, JList, JComboBox, JScrollPane Các thành phần mở rộng như: JTabbedPane, JProgressBar, JTable, JTree Việc xử lý sự kiện trên các thành phần Swing giống như trên các thành phần AWT. Ví dụ về Swing import java.awt.*; import javax.swing.*; public class HelloJFC { public static void main(String[] args) { JFrame frame = new JFrame("JFC"); Icon icon = new ImageIcon("rose.gif"); JButton button = new JButton("Rose", icon); button.setMnemonic('R'); button.setToolTipText("Button Rose"); frame.getContentPane().setLayout(new FlowLayout()); frame.getContentPane().add(button); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setSize(400, 300); frame.setVisible(true); } } 101
- Thiết kế chương trình Các thành phần của chương trình Dữ liệu của bài toán cần xử lý (Model) Hiển thị dữ liệu của bài toán thông qua giao diện (View) Điều khiển tương tác với người dùng (Controller) Ví dụ: Chương trình điều khiển quả bóng Model: Dữ liệu về quả bóng View: Giao diện hiển thị dữ liệu quả bóng Controller: Điều khiển di chuyển quả bóng Model: Dữ liệu về bóng gồm toạ độ tâm (x,y) và bán kính bóng. View: Giao diện hiển thị gồm có hình quả bóng và 2 nút điều khiển. Controller: Khi ấn nút điều khiển thì quả bóng di chuyển. Một số phương pháp thiết kế Big Blob Tất cả Model, View, Controller đặt trong một một lớp duy nhất. 102
- Ví dụ với Big Blob // file TestBall.java tao ra mot big blob public class TestBall { public static void main(String[] args) { MyBallFrame myFrame = new MyBallFrame(“Ball Frame”); myFrame.setSize(400, 300); myFrame.setVisible(true); } } // MyBallFrame la mot big blob // No chua ca model, view va controller class MyBallFrame extends Frame implements ActionListener { private int x, y, radius; // du lieu ve qua bong (model) private Button moveLeft, moveRight; // thanh phan GUI (view) moveLeft.addActionListener(this); moveRight.addActionListener(this); // xu ly su kien (controller) public void actionPerformed(ActionEvent event) } Một số phương pháp thiết kế 103
- Presentation-Model Tách riêng Model và Presentation (gồm View + Controller) Ví dụ với Presentation-Model // file TestBall.java tao model va presentation public class TestBall { public static void main(String[] args) { // tao model BallModel myBall = new BallModel(50, 50, 20); // tao presentation BallPresentation myFrame = new BallPresentation(myBall); } } // file BallPresentation.java chua view va controller // No co mot thanh phan du lieu la model can xu ly // Cach 1: Dung top-level listener public class BallPresentation extends Frame implements ActionListener { private BallModel ball; // model can xu ly private Button moveLeft, moveRight; // thanh phan GUI (view) moveLeft.addActionList ener(this); moveRight.addActionLi stener(this); // xu ly su kien (controller) public void actionPerformed(ActionEvent event) 104
- } // file BallPresentation.java, cach 2: dung lop nghe la inner class public class BallPresentation extends Frame { private BallModel ball; // model can xu ly private Button moveLeft, moveRight; // thanh phan GUI (view) moveLeft.addActionListener(new ToLeftListener()); moveRight.addActionListener(new ToRightListener()); // xu ly su kien (controller) class ToLeftListener implements ActionListener { public void actionPerformed(ActionEvent event) { ball.moveLeft(); repaint(); // goi phuong thuc cua lop outer } } } // file BallModel.java chua du lieu va phuong thuc cua qua bong // Model khong phu thuoc vao Presentation public class BallModel { private int x, y, radius; BallModel(int x, int y, int radius) void moveLeft() void moveRight() int getXCenter() int getYCenter() int getRadius() 105
- } Một số phương pháp thiết kế Model-View-Controller Tách riêng Model, View và Controller view Controller Model Model-View-Controller Ưu điểm Các modul độc lập, dễ quản lý Có thể dễ dàng tạo nhiều giao diện khác nhau cho cùng một chương trình Dễ mở rộng chương trình Ví dụ với MVC //file TestBall.java tao model, view va controller public class TestBall { public static void main(String[] args) { // tao model BallModel myBall = new BallModel(50, 50, 20); // tao view BallView ballView = new BallView(myBall); tao controller BallController ballController = new BallController(myBall, ballView); ballView.setVisible(true); } } // file BallView.java public class BallView extends Frame 106
- { private BallModel ball; // model can xu ly private Button moveLeft, moveRight; BallView(BallModel ballModel) { ball = ballModel; } public void paint(Graphics g) { g.fillOval( ); } // phuong thuc nay duoc goi boi controller public void addToLeftListener(ActionListener al) { buttLeft.addActionListener(al); } } // file BallController.java public class BallController { private BallModel ball; // model can xu ly private BallView view; // view can xu ly BallController(BallModel ballModel, BallView ballView) { // nhan model va view can xu ly ball = ballModel; view = ballView; // dat lang nghe tren view view.addToLeftListener(new ToLeftListener()); view.addToRightListener(new ToRightListener()); } // file BallController.java (tiep theo) 107
- // xu ly su kien thong qua inner class class ToLeftListener implements ActionListener { public void actionPerformed(ActionEvent event) { ball.moveLeft(); view.repaint(); } } } // file BallModel.java chua du lieu va phuong thuc cua qua bong // Model khong phu thuoc vao View va Controller public class BallModel { private int x, y, radius; BallModel(int x, int y, int radius) void moveLeft() void moveRight() int getXCenter() int getYCenter() int getRadius() } Case study: Chương trình đổi tiền Viết chương trình cho phép tính số lượng tiền VNĐ tương ứng với một số lượng USD cho trước. Biết rằng 1 đôla = 16,798 đ. Mô tả giao diện như sau: 108
- ExchangeModel ? ExchangeView ? ExchangeController ? Cài đặt và thử nghiệm BÀI TẬP 1. Viết chương trình cho phép người dùng chọn một trong hai chế độ là Line và Point (dùng Checkbox), sau đó người dùng có thể dùng chuột để vẽ trong một Canvas nằm giữa màn hình (giống MS Paint). 2. Viết lại các chương trình liên quan tới Graphics sử dụng Frame. 3. Viết lại các chương trình liên quan tới thành phần giao diện GUI sử dụng Frame. 4. Viết chương trình tạo 3 menu trong một Frame như sau: Colors Shapes Help Red Circle About Green Rect Blue Line Menu Colors cho phép chọn màu, menu Shapes cho phép chọn hình. Khi người dùng chọn menu và ấn nút draw trên Frame thì chương trình vẽ ra hình và màu được chọn. Menu Help – About hiển thị hộp thoại giới thiệu về chương trình. 5.Viết chương trình tính diện tích các hình: Tạo một Frame trong đó ở bên trái có 3 lựa chọn là Circle, Rectangle và Triangular (dùng Checkbox). Khi người dùng chọn một trong các hình thì ở bên phải sẽ hiển thị các ô nhập liệu tương ứng: Circle có một ô nhập là Radius, Rectangle có 2 ô nhập là Width và Height, Triangular có 3 ô nhập là 3 cạnh a, b, c. Sau đó người dùng chọn nút Compute thì chương trình tính và hiển thị kết quả lên màn hình. (Dùng CardLayout) 6. Viết chương trình tạo 2 menu item là Nhập hàng và Bán hàng. Khi người dùng chọn nhập hàng thì hiển thị Frame cho phép nhập vào tên hàng, số lượng, đơn giá (lưu thông tin này vào mảng). Khi người dùng chọn Bán hàng thì hiển thị Frame (hoặc Dialog) cho phép nhập vào tên người mua và cho phép chọn mua một trong số các mặt hàng có sẵn; sau đó hiển thị số tiền mà người đó phải trả. (Thiết kế theo MVC) 109
- TÀI LIỆU THAM KHẢO g/GUI/Swing2/shortcourse.htm 110