Tải bản đầy đủ (.doc) (12 trang)

Kinh nghiệm áp dụng Object Oriented trong lập trình Java docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (171.37 KB, 12 trang )

Kinh nghiệm áp dụng Object Oriented trong lập trình Java
Tác giả muốn phổ biến kinh nghiệm bản thân trong việc áp dụng Object Oriented (OO) với lập trình sử dụng Java.
Vấn đề được đặt ra là:“làm thế nào dựa trên phân tích những yêu cầu của một ứng dụng, để tạo ra các lớp (class) hay object cần
thiết ?” Hai danh từ class và object sẽ được dùng để chỉ chung một khái niệm trong bài viết này.
“Sử dụng những nguyên tắc của OO trong việc phân tích, sẽ giúp cho bạn tìm ra những class hoặc object cần thiết một cách có hệ
thống. Giúp bạn làm quen và hiểu OO là mục đích chính của bài viết này.”
“ Đầu tiên nên tìm hiểu OO được hình thành trong hoàn cảnh nào của việc lập trình“
Trở về thời gian trước khi OO được hình thành, những ngôn ngữ như C, Pascal dựa trên function hoặc procedure. Toàn bộ ứng dụng
là một chuỗi các function và procedure, cái này gọi cái kia cho đến khi program chấm dứt.
Ví dụ :
Yêu cầu của một ứng dụng là tìm kiếm dữ kiện của thí sinh đưa vào số báo danh, thì cách phân tích có thể sẽ là:
1. Tạo ra một function để nhập số báo danh.
2. Tạo ra một function để truy tìm dữ kiện dựa trên dữ kiện nhập.
3. Tao ra một function để display kết quả tìm được.
Cách suy nghĩ hay phân tích như vậy gọi là procedural, gồm nhiều sự kiện xảy ra nối tiếp nhau. Cái ưu điểm của cách phân tích này
là intuitive (trực quan). Nó dễ hiểu và gần gũi với suy luận tự nhiên của con người. Chỉ cần khéo léo chia vấn đề thành những
operation nhỏ hơn để giải quyết. Mọi chuyện có vẻ như có thể giải quyết khá dễ dàng với cách phân tích này.
Lấy một ví dụ khác phức tạp hơn. “Bạn được yêu cầu viết ứng dụng simulate hoat động của một chiếc xe đạp. Làm thế nào để chia
nhỏ thành các function hay procedure đây ?” Tất nhiên là được nhưng sẽ khó hơn. Vấn đề sẽ trở nên khó hơn nếu nói đến các hệ thống
phức tạp như xe gắn máy, máy bay… v.v
Nếu bạn nhìn hoạt động của chiếc xe đạp theo khía cạnh cơ khí máy móc thì nó hòan toàn đơn giản và dễ hiểu. Nó gồm có pedal gắn
liền với đĩa, rồi dây xích, rồi líp, rồi bánh xe. Nó như một cỗ máy cơ khí được tạo thành bởi nhiều bộ phận cơ khí nhỏ và đơn giản.
Nếu bạn có hể lập trình giống như vậy, bằng cách lắp ráp nhiều bộ phận nhỏ đơn giản lại với nhau, bài toán sẽ trở nên đơn giản hơn,
và OO bắt đầu từ suy nghĩ như vậy.
• Đọc tới đây bạn sẽ đặt câu hỏi: “chẳng phải phương pháp procedural ở trên cùng là chia bài toán thành những function
nhỏ hơn hay sao ? Như vậy OO có gì khác biệt hơn ?”
Tất nhiên là có. Function hay procedure là một khái niệm trừu tượng dùng để mô tả hoạt động của một vật cụ thể trong thực tế, trong
khi OO cho phép tạo ra những object dựa trên hay bắt chước theo những vật cụ thể. Do đó những object trong OO được “cụ thể hoá
hơn” và “dễ hiểu hơn”.
Bạn có vẻ chưa tin vào khái niệm OO ! Không sao hết, hãy nhìn vào hoạt động của chiếc xe đạp kỹ lưỡng hơn. Đĩa quay kéo dây xích,
dây xích lại kéo lip. Khái niệm OO sẽ đưa đến 3 object như sau: đĩa, dây xích, lip.


Nhưng làm thế nào bắt chước được hoạt động của chúng ?
Sự tiếp xúc hoặc truyền động trong thực tế, được mô phỏng trong phần mềm bằng cách: object này gọi các method của object khác.
Nhìn vào ví dụ dưới đây
class DayXich {
// method mô tả sự kéo của dây xích
public void keo(){
}
}
class Dia {
// method mô tả sự quay của đĩa
public void xoay(DayXich dx) {
// đĩa truyền động cho dây xích bằng cách
// gọi method keo()
dx.keo(); }
}
Method xoay() của Đĩa gọi method keo() của DayXich. Bản thân method xoay() sẽ bị gọi bởi method nào đó, và cứ như vậy tạo thành
hoạt động của cả cổ máy.
Trong OO, khi object A gọi method của object B, thì được gọi một cách văn vẻ là “A send a message to B”, trong thực tế nó chỉ đơn
giản là mô phỏng cách thức các bộ phận tiếp xúc hay truyền động để làm việc với nhau. Như vậy khái niệm OO đưa phần mềm phản
ánh gần gủi và trung thực hơn hoạt động trong thực tế. Người lập trình cũng giống như một kỹ sư cơ khí, thiết kế, chế tạo và lắp ráp
từng bộ phận cho một cỗ máy lớn.
Cách suy nghĩ theo OO đòi hỏi người lập trình phải nhìn cả ứng dụng giống như một cỗ máy đang vận hành, tìm hiểu sự hoạt động
của từng bộ phận, và làm cho chúng cùng làm việc với nhau. Điều này rất quan trọng cần phải nhấn mạnh một lần nữa: Trước khi có
thể tìm ra các class hay object cần thiết cho một ứng dụng, bạn hãy cố gắng hình dung toàn bộ ứng dụng hoạt động giống như một hệ
thống gồm nhiều chi tiết, bộ phận nhỏ hoạt động ăn khớp với nhau.
Đến đây bạn đã biết được tại sao OO ra đời. Cũng giống như Newton đã phát hiện ra sức hút của trái đất, OO ra đời do sự quan sát và
mô phỏng theo sự làm việc của những hệ thống có sẵn. Mục đích chính của chúng ta vẫn là làm sao tìm ra được những object cần thiết
cho một ứng dụng.
Trong thế giới phần mềm một object trong bất kỳ ứng dụng nào đều có thể là một trong 3 loại: Control, Boundary, Entity. Nếu bạn
chưa hiểu rõ ý nghĩa chúng là gì ? Cũng không sao. Thông thường không phải lúc nào cũng dễ dàng xác định loại của một object. Xác

định object thuộc loại nào, không phải là yếu tố quan trọng trong việc tìm kiếm object cần thiết cho một ứng dụng.
Thu hẹp hơn cho những ứng dụng về web hay Swing người ta đưa ra khái niệm MVC = Model-View-Controller. Như vậy ta có thể so
sánh như sau:
• Control = Controller
• Boundary = View
• Entity = Model
Thông thường một ứng dụng luôn làm những công việc như sau:
1. Nhập và xuất dữ kiện (input/output).
2. Thay đổi hay kết hợp dữ kiện (manipulate data).
3. Lưu trữ hay truy cập dữ kiện (save or retrieve data from database).
Công việc thứ nhất thường đưa đến những object thuộc loại View, công việc 2 và 3 thường đưa đến object thuộc loại Model. Bạn có
thể nôn nóng đặt câu hỏi:Như vậy Controller cần khi nào ? Câu trả lời sẽ là mọi ứng dụng đều phải có Controller object. Không có
chúng thì ứng dụng sẽ nằm i` ra đó mà không chạy. Điều này được làm rõ khi bạn đọc tiếp theo dưới đây.
View hay Boundary object trong ứng dụng tìm kiếm dữ kiện của thí sinh là những object mà người sử dụng có thể nhìn thấy. Có thể là
JTextField để nhập dữ kiện, có thể là JTable để hiện kết quả truy tìm. Giả sử có 2 ứng dụng A và B chạy độc lập trong đó ứng dụng A
cần dữ kiện được tạo ra từ B, thì View object của A là những object dùng để liên hệ với B để nhận dữ kiện, còn View object của B là
những object xuất dữ kiện cho A hoặc cho bất kỳ ứng dụng nào khác.
Model hay Entity object thường là những object chứa dữ kiện. Object loại này cũng chứa logic hay những thuật toán thay đổi hay kết
hợp dữ kiện mà nó chứa, và cả việc đưa vào hay lấy ra từ database. Nói một cách đại khái, đây là những object 'knows how to do'.
Trong ứng dụng truy tìm thí sinh, thì nó chính là TableModel dùng để chứa data cho JTable.
Control hay Controller object là những object 'knows what to do next'.
Bạn cũng biết là trong Java mọi method đều phải nằm trong một class. Class chứa method main() là một ví dụ của Control hay
Controller. Chúng cũng thường là những class có những method chứa logic như sau:
if(){
//call some method
}else {
//call some other method
}
Không có những method này thì ứng dụng không chạy được. Bản thân những method này (hay class chứa nó) chứa đựng algorithm
hay logic của ứng dụng.

Đến đây bạn đã quen thuộc hơn với khái niệm của những object trong phần mềm của một ứng dụng. Bạn có thể liên hệ được sự hiện
diện của chúng với những vật cụ thể ở ngoài thực tế. Bạn cũng có thể phân loại và biết được mục đích tại sao cần có object này hay
object khác cho một ứng dụng.
Chúng ta sẵn sàng cho bước kế tiếp: “tìm kiếm những object cần thiết cho một ứng dụng”
Trở lại ví dụ mô hình xe đạp, thì những class như: Dia, DayXich, Lip thuộc loại nào? Bạn biết chắc rằng cần phải có những class này
để mô phỏng theo những bộ phận thực của xe đạp, nhưng khó biết chắc nó thuộc loại nào. Phần mềm ngày càng phức tạp và sự phân
loại object cũng ngày càng khó hơn. Tuy nhiên, việc xác định loại của một class hay object không phải là “kim chỉ nam” trong việc
tìm kiếm đầy đủ những object cho một ứng dụng. Chúng ta không nên đi tìm kiếm object dựa trên mục đích như: Phải bắt đầu bằng
tìm kiếm tất cả những object thuộc loại View, Model, hay Controller cho ứng dụng này
Sau khi nắm vững yêu cầu của một ứng dụng, nếu bạn có thể liên hệ được hoạt động của ứng dụng với một cỗ máy hay một hệ thống
gồm nhiều bộ phận rời rạc hoạt động với nhau, cũng giống như mô hình hoạt động của xe đạp ở trên, thì đó chính là nơi mà bạn có thể
chỉ ra được những object cần thiết. Sự cần thiết cần có của một object không phải dựa trên câu hỏi:“nó thuộc loại object nào ? mà
phải dựa trên “nó làm được gì ?”. Có nghĩa là trong mô hình xe đạp cần phải có class DayXich để mô phỏng dây xích của xe đạp. Xác
định bản thân class DayXich thuộc loại nào không quan trọng lắm, nhưng nó cần thiết để truyền tương tác giữa Dia và Lip.
Việc hình dung ra hoạt động của toàn bộ ứng dụng như một cỗ máy không phải lúc nào cũng dễ dàng. Và trong thực tế không
phải phần mềm nào cũng dựa theo một hệ thống cụ thể có sẵn.
Trong trường hợp này, nguyên tắc “chia để trị” có thể áp dụng.
“Chia để trị” là chia toàn bộ hoạt động của ứng dụng thành nhiều chức năng nhỏ hơn. Mọi chức năng hoạt động theo nguyên tắc hộp
đen (a blackbox), và chúng hoạt động càng độc lập với nhau càng tốt. Mọi blackbox nhận dữ kiện và xuất dữ kiện tùy theo chức năng
của chúng. Dữ kiện xuất của blackbox này sẽ là dữ kiện nhập của blackbox khác. Mỗi một blackbox sẽ có chức năng đơn giản hơn
nhiều so với toàn bộ ứng dụng, và nhờ đó bạn sẽ dễ dàng tìm ra những object cần thiết cho hoạt đông của blackbox hơn. Bạn có biết
đây cũng chính là nguyên tắc trong việc chế tạo các thiết bị điện tử. Lấy ví dụ trong computer, bạn có thể tháo rời từng bộ phận như
CD drive, hard drive và mỗi bộ phận luôn có điểm tiếp xúc hoặc dây nối để nối với các bộ phận khác. Cần nhớ rằng mọi blackbox
trong một ứng dụng phần mềm chứa một hay nhiều object, và blackbox chỉ là những ranh giới trừu tượng dùng để chia nhỏ vấn đề.
Trở lại ví dụ tìm kiếm thí sinh dựa vào số báo danh. Chúng ta có thể chia vấn đề thành 2 blackbox: blackbox 1 (BB1) dùng để nhận dữ
kiện và trình bày kết quả; blackbox 2 (BB2) dùng để truy tìm dữ kiện.
BB1 có thể chứa JTextField để nhập dữ kiện và JTable để trình bày kết quả.
BB2 chứa JButton “Truy Tìm”, và SearchAction liên hệ với JButton thực hiện việc truy tìm.
Điểm tiếp xúc hay dây nối giữa các blackbox được thể hiện trong phần mềm bằng method của class hay object.
* Đối với BB1 , method getText() của JTextField được dùng như điểm để xuất dữ kiện (là số báo danh của thí sinh trong trường hợp

này); và chúng ta cần thêm một điểm để nhận kết quả tìm được. Phân tích đến đây, chúng ta có thể tạo thêm một class
ResultTableModel với method addResult() cho BB1 để làm điểm nhận kết quả. ResultTableModel được tạo ra như là một
TableModel cho JTable. Chúng ta đã tìm được 3 class cho BB1 gồm có: JTextField, JTable, và ResultTableModel.
* Đối với BB2 gồm có 2 class: JButton và SearchAction. BB2 nối với BB1 bằng cách gọi 2 method JTextField.getText() và
ResultTableModel.addResult() thông qua Action.actionPerformed() như sau:
SearchAction(JTextField jtf,ResultTableModel tm) extends {

public void actionPerformd(ActionEvent a)
{
String sbd = jtf.getText(); //nhận số báo danh, truy tìm từ database.
tm.addResult(ketquatimđược); //kết quả tìm được.
}
}
Đến đây bạn nên thấy rằng cách suy nghĩ và phân tích vấn đề sử dụng OO cũng quen thuộc và gần gủi với suy nghĩ và thế giới xung
quanh của con người. Sản phẩm của OO là những object với những method phản ánh sự làm việc và tương tác với các object khác. Nó
dễ hiểu và dễ truyền đạt hơn là những function và procedure của cách suy nghĩ procedural. Đi xa hơn nữa, những tính chất chỉ có
trong OO như inheritance, encapsulation, polymorphism làm cho những ứng dụng trở nên linh hoạt và dễ bảo trì hơn. Trình bày chi
tiết của 3 tính chất trên sẽ nằm trong một bài viết khác.
Sau đây là những điểm cần lưu ý cho những người mới lập trình theo phương pháp OO nhất là những người đã quen thuộc với cách
suy nghĩ procedural:
1. Sai lầm khi cho rằng vì Java là một OO ngôn ngữ, cho nên chỉ cần sử dụng Java thành thạo là bạn sẽ tự nhiên sẽ biết OO.
Không hiểu được tại sao OO và những tính chất của nó được hình thành sẽ không biết cách áp dụng đúng đắn.
2. Mỗi một class tìm được trong khi phân tích được xem chính nó là một blackbox nhỏ nhất. Khi viết mã nguồn cho một class
bạn nên tự đặt chính bản thân vào địa vị của class đó. Nghĩa là bạn chỉ quan tâm tới việc làm sao biến đổi dữ kiện nhập
thành dữ kiện xuất trong phạm vi của class. Không quan tâm đến việc dữ kiện nhập từ đâu tới và ai sẽ là người sử dụng dữ
kiện xuất. Nó cũng giống như những bộ phận của xe đạp được tạo ra bởi nhiều người khác nhau, và vẫn có thể lắp ráp được
với nhau dễ dàng. Đây là đặc điểm rất quan trọng để phân biệt một người lập trình theo phương pháp OO với một người
theo phương pháp procedural.
3. Đến đây nếu bạn nắm vững được thêm 3 tính chất của OO: inheritance, encapsulation, polymorphism thì bạn có thể tự tin
vào kỹ năng OO của mình rồi đó.

2. Action
Một ngày đẹp trời nọ, sếp của bạn tự nhiên giao cho bạn viết một chương trình thay thế cho cái Notepad của Windows. Lý do đơn
giản là ổng ko thích dùng cái của Windows và thứ hai là ổng muốn thử thách trình độ của bạn. Việc đầu tiên bạn nghĩ tới khi tạo GUI
cho chương trình là hệ thống menu, và muốn chơi trội hơn Windows bạn quyết định thêm vào một cái toolbar. Bạn bắt tay vào tạo một
menu bar.
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu(“File”);
JMenuItem item = new JMenuItem(“New”);
item.addActionListener(aMenuListener);
file.add(item);
item = new JMenuItem(“Open”);
item.addActionListener(aMenuListener);
file.add(item);
item = new JMenuItem(“Save”);
item.addActionListener(aMenuListener);
file.add(item);
item = new JMenuItem(“Exit”);
item.addActionListener(aMenuListener);
file.addSeparator();
file.add(item);
//
Bạn thêm vào menu bar vài cái menu nữa Edit, Format, View, Help và cuối cùng bạn gọi phương thức setJMenuBar(menuBar). Vậy
là bạn đã có hệ thống menu cho mình. Bước tiếp theo là tạo toolbar:
JToolBar toolBar = new JToolBar();
JButton b = new JButton(“New”);
b.addActionListener(aButtonListener);
toolbar.add(b);
b = new JButton(“Open”);
b.addActionListener(aButtonListener);
toolbar.add(b);

//
getContentPane().add(toolbar, BorderLayout.NORTH);
Sau khi có hệ thống menu hoàn chỉnh và một thanh toolbar vừa ý, bạn chợt phát hiện ra rằng chẳng có gì khác nhau giữa action New
trên menu file và button New trên toolbar, nhưng bạn lại tạo ra hai lớp khác nhau để lắng nghe sự kiện New. Bạn quyết định chỉ tạo
một lớp implements ActionListener interface cho cả menu item và button trên toolbar, hãy xem bạn làm gì trong phương thức
actionPerformed():
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if(obj instanceof JMenuItem) {
JMenuItem item = (JMenuItem)obj;
String name = item.getText();
if(“New”.equals(name)) {
//
}
//
} else if(obj instanceof JButton) {
JButton b = (JButton)obj;
String bName = b.getText();
if(“New”.equals(bName)) {
//
}
//
}
}
Từ hệ thống menu bạn cảm thấy choáng vì khối lượng các câu lệnh if else Liệu có giải pháp nào tốt hơn không? Tôi nói với bạn là
tại sao bạn không sử dụng interface Action có sẵn trong Java nhỉ?
Action Interface
Action interface kế thừa từ ActionListener interface, điều này có nghĩa là khi bạn implements interface này bạn phải định nghĩa
phương thức actionPerformed() và một số phương thức khác. Phương thức add() của JToolBar, JMenu, JPopupMenu nhận vào một
tham số là đối tượng implements Action interface, khi action được add vào các container này thì container tự động tạo một component

tương ứng, ví dụ: khi bạn add một action và JMenu thì một JMenuItem sẽ được tạo ra, add vào JToolBar thì một JButton sẽ được tạo
ra. Và lúc này action sẽ trở thành một ActionListener cho component đó. Khi bạn click chọn menu item, hay click chọn button thì
phương thức actionPerformed() sẽ được gọi. Trong Action định nghĩa sẵn một số hằng số:
- NAME : tên của Action
- SHORT_DESCRIPTION, LONG_DESCRIPTION: tooltip
- SMALL_ICON: icon
- MNEMONIC_KEY: phím đại diện
- ACCELERATOR_KEY: phím tăng tốc
- ACTION_COMMAND_KEY: chuỗi đại diện cho Action
- DEFAULT
Ngoài ra, Action còn có một thuộc tính kiểu boolean để bạn có thể enable hay disable một action
Khi bạn muốn set thuộc tính cho Action bạn dùng phương thức
putValue(String key, Object obj);
key ở đây là một trong các hằng số ở trên, một Hashtable sẽ được dùng để lưu giữ các giá trị trên. Ví dụ khi bạn muốn add một icon:
putValue(Action.SMALL_ICON, new ImageIcon( ));
hoặc bạn muốn add một tooltip:
putValue(Action.SHORT_DESCRIPTION, “Tooltip”);
Ngược lại, bạn dùng phương thức:
getValue(String key);
để lấy về giá trị tương ứng với hằng số ở trên. Phương thức này trả về một Object, vì vậy bạn phải ép kiểu để có được giá trị mong
muốn.
• AbstractAction
AbstractAction là lớp implements Action interface và đã định nghĩa sẵn cho bạn hầu hết các phương trong Action interface. Bạn chỉ
cần kế thừa lớp này và định nghĩa lại phương thức actionPerformed().
Vậy là đủ rồi, chúng ta cùng áp dụng Actibạn có thể đặt tên gì cũng được.
Trong lớp này, tôi tạo thêm 3 inner claon để xây dựng GUI cho chương trình. Tôi gọi chương trình là NotepadForBoss, ss
- FileAction
- EditAction
- HelpAction
package org.mountain.abstractaction;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
public class NotepadForBoss extends JFrame {
private JMenuBar menuBar;
private JToolBar toolBar;
private JTextArea display;
private JMenu fileMenu, editMenu, helpMenu;
private FileAction newAction, openAction, saveAction, exitAction;
private EditAction copyAction, cutAction, pasteAction;
private HelpAction contentsAction, aboutAction;

//

// This action for File menu
class FileAction extends AbstractAction {
private String name;
private Icon icon;


public FileAction(String name) {
super(name);
// this.name = name;
// this.putValue(AbstractAction.NAME, name);
// this.putValue(AbstractAction.SHORT_DESCRIPTION, name);
}

public FileAction(String name, Icon icon) {
super(name, icon);
// this(name);
// this.icon = icon;
// if(icon != null) {
// putValue(AbstractAction.SMALL_ICON, icon);
// }
}

public FileAction(String name, Icon icon, KeyStroke key) {
this(name, icon);
putValue(AbstractAction.ACCELERATOR_KEY, key);
}

public void actionPerformed(ActionEvent e) {
display.setText("FileAction You just pressed: " + (String)getValue(AbstractAction.NAME));
}
}

// This action for Edit menu
class EditAction extends AbstractAction {
private String name;
private Icon icon;


public EditAction(String name) {
this.name = name;
this.putValue(AbstractAction.NAME, name);
}

public EditAction(String name, Icon icon) {
this(name);
this.icon = icon;
if(icon != null) {
putValue(AbstractAction.SMALL_ICON, icon);
}
}

public EditAction(String name, Icon icon, KeyStroke key) {
this(name, icon);
putValue(AbstractAction.ACCELERATOR_KEY, key);
}
public void actionPerformed(ActionEvent e) {
display.setText("EditAction You just pressed: " + (String)getValue(AbstractAction.NAME));
}
}

// This action for Help menu
class HelpAction extends AbstractAction {
private String name;
private Icon icon;

public HelpAction(String name) {
this.name = name;

this.putValue(AbstractAction.NAME, name);
}

public HelpAction(String name, Icon icon) {
this(name);
this.icon = icon;
if(icon != null) {
putValue(AbstractAction.SMALL_ICON, icon);
}
}

public HelpAction(String name, Icon icon, KeyStroke key) {
this(name, icon);
putValue(AbstractAction.ACCELERATOR_KEY, key);
}
public void actionPerformed(ActionEvent e) {
String name = (String)getValue(AbstractAction.NAME);
if("About".equalsIgnoreCase(name)) {
JOptionPane.showMessageDialog(null, "Hello!");
} else {
display.setText("HelpAction You just pressed: " + (String)getValue(AbstractAction.NAME));
}
}
}
}
Giờ đến lúc ta tạo menu bar và toolbar từ những lớp này.
package org.mountain.abstractaction;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
public class NotepadForBoss extends JFrame {
private JMenuBar menuBar;
private JToolBar toolBar;
private JTextArea display;
private JMenu fileMenu, editMenu, helpMenu;
private FileAction newAction, openAction, saveAction, exitAction;
private EditAction copyAction, cutAction, pasteAction;
private HelpAction contentsAction, aboutAction;

public NotepadForBoss() {
super("Abstract Action Example v1.0");
setDefaultCloseOperation(EXIT_ON_CLOSE);

menuBar = new JMenuBar();
toolBar = new JToolBar();

fileMenu = new JMenu("File");

newAction = new FileAction("New", new ImageIcon("new.gif"), KeyStroke.getKeyStroke(KeyEvent.VK_N,

KeyEvent.CTRL_MASK));
fileMenu.add(newAction);
openAction = new FileAction("Open", new ImageIcon("open.gif"), KeyStroke.getKeyStroke(KeyEvent.VK_O,
KeyEvent.CTRL_MASK));
fileMenu.add(openAction);
saveAction = new FileAction("Save", new ImageIcon("save.gif"), KeyStroke.getKeyStroke(KeyEvent.VK_S,
KeyEvent.CTRL_MASK));
fileMenu.add(saveAction);
exitAction = new FileAction("Exit");
fileMenu.addSeparator();
fileMenu.add(exitAction);

editMenu = new JMenu("Edit");
copyAction = new EditAction("Copy", new ImageIcon("copy.gif"));
editMenu.add(copyAction);
cutAction = new EditAction("Cut", new ImageIcon("cut.gif"));
editMenu.add(cutAction);
pasteAction = new EditAction("Paste", new ImageIcon("paste.gif"));
editMenu.add(pasteAction);

helpMenu = new JMenu("Help");
contentsAction = new HelpAction("Contents");
helpMenu.add(contentsAction);
aboutAction = new HelpAction("About", new ImageIcon("palette_select.gif"));
helpMenu.addSeparator();
helpMenu.add(aboutAction);

menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);


toolBar.add(newAction);
toolBar.add(openAction);
toolBar.add(saveAction);
toolBar.addSeparator();
toolBar.add(copyAction);
toolBar.add(cutAction);
toolBar.add(pasteAction);
// toolBar.addSeparator();
// toolBar.addSeparator();
// toolBar.add(aboutAction);

setJMenuBar(menuBar);
add(toolBar, BorderLayout.NORTH);

display = new JTextArea();
JScrollPane pane = new JScrollPane(display);
getContentPane().add(pane, BorderLayout.CENTER);

setSize(400, 300);
}
// This action for File menu
class FileAction extends AbstractAction {
//
}

// This action for Edit menu
class EditAction extends AbstractAction {
//
}


// This action for Help menu
class HelpAction extends AbstractAction {
//
}

public static void main(String[] args) {
JFrame f = new NotepadForBoss();
f.setVisible(true);
}
}
Trong mỗi lớp Action ở trên chúng ta đã tạo ra 3 constructor. Thứ nhất là tạo action với tên:
FileAction(String name);
Thứ 2: tên cộng với một icon
FileAction(String name, Icon icon);
Thứ 3: ta thêm vào một tham số là phím (tổ hợp phím) tăng tốc
FileAction(String name, Icon icon, KeyStroke keyStroke);
Khi bạn chọn menu item hay click vào button, chương trình chỉ đơn giản in ra tên của action.
Đây là GUI mà chúng ta đã tạo được:
Action thực sự hữu dụng khi bạn làm việc với JMenu, JToolBar, hoặc là JPopupMenu. Rõ ràng là bạn không cần phải làm công việc
nhàm chán, tạo menu item, add cho nó một ActionListener, rồi add nó vào một menu. Bạn chỉ cần add một action vào menu.
Có điều ứng dụng của chúng ta chưa hoàn chỉnh cho lắm, hình như thiếu vài cái menu. Tôi để công việc này lại cho bạn

×