Hướng dẫn lập trình GUI & Object trong Java qua 1 ví dụ

Trong bài này tôi sẽ hướng dẫn các bạn các bước làm việc với nền tảng hướng đối tượng bên dưới và thao tác với các đối tượng dựa trên cơ chế giao diện người dùng (GUI). Đồng thời đây cũng là 1 dạng database đơn giản để thao tác với các bài toán lưu trữ không phức tạp.

Giả sử chúng ta có mối quan hệ giữa các đối tượng trong việc quản lý thư viện như sau: Ta có 1 phòng chứa sách của thư viện (LibRoom), trong đó có nhiều kệ sách (Shelf), mỗi kệ sách có chứa nhiều cuốn sách(Book).

Giao diện thao tác ứng dụng sau khi hoàn tất như sau
http://vovanhai.files.wordpress.com/2008/11/oopgui_01.png
Trước hết ta thiết kế các đối tượng và mối quan hệ giữa chúng.

Code cho lớp Book.java






package qlsv;
import java.io.Serializable;public class Book implements Serializable{
private static final long serialVersionUID = 1L;
private String BookID;
private String BookTitle;
private String AuthorName;
private int noPages; public Book(String bookID, String bookTitle, String authorName,  int noPages) {
AuthorName = authorName;
BookID = bookID;
BookTitle = bookTitle;
this.noPages = noPages;
}
public Book(){
this(“”,”",”",0);
}public String getBookID() {
return BookID;
}
public void setBookID(String bookID) {
BookID = bookID;
}
public String getBookTitle() {
return BookTitle;
}
public void setBookTitle(String bookTitle) {
BookTitle = bookTitle;
}
public String getAuthorName() {
return AuthorName;
}
public void setAuthorName(String authorName) {
AuthorName = authorName;
}
public int getNoPages() {
return noPages;
}
public void setNoPages(int noPages) {
this.noPages = noPages;
}@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((BookID == null) ? 0 : BookID.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Book other = (Book) obj;
if (BookID == null) {
if (other.BookID != null)
return false;
} else if (!BookID.equals(other.BookID))
return false;
return true;
}

@Override
public String toString() {
return BookTitle;
}
}

Code cho lớp Shelf.java






package qlsv; import java.io.Serializable;
import java.util.ArrayList;

public class Shelf implements Serializable{
private static final long serialVersionUID = 3225680073019589887L;
private String ShelfID;
private String ShelfName;
private ArrayList<Book>booklist;

public Shelf(String shelfID, String shelfName) {
ShelfID = shelfID;
ShelfName = shelfName;
booklist=new ArrayList<Book>();
}
public String getShelfID() {
return ShelfID;
}
public void setShelfID(String shelfID) {
ShelfID = shelfID;
}
public String getShelfName() {
return ShelfName;
}
public void setShelfName(String shelfName) {
ShelfName = shelfName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ShelfID == null) ? 0 : ShelfID.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Shelf other = (Shelf) obj;
if (ShelfID == null) {
if (other.ShelfID != null)
return false;
} else if (!ShelfID.equals(other.ShelfID))
return false;
return true;
}
@Override
public String toString() {
return ShelfName;
}
/**
* Thêm 1 cuốn sách vào kệ
* @param b
* @return
*/
public boolean AddBook(Book b){
if(booklist.contains(b))
return false;
return booklist.add(b);
}
/**
* Bỏ 1 cuốn sách khỏi kệ
* @param bookID
* @return
*/
public boolean RemoveBook(String bookID) {
Book b=new Book(bookID,”",”",0);
if(!booklist.contains(b))
return false;
return booklist.remove(b);
}

/**
* Update thông tin sách
* @param bookID
* @param newBook
* @return
*/
public boolean UpdateBookInfos(String bookID,Book newBook) {
Book b=new Book(bookID,”",”",0);
if(!booklist.contains(b))
return false;
Book old=booklist.get(booklist.indexOf(b));
old.setBookTitle(newBook.getBookTitle());
old.setAuthorName(newBook.getAuthorName());
old.setNoPages(newBook.getNoPages());
return true;
}

public Book GetBook(String id){
Book b=new Book(id,”",”",0);
if(!booklist.contains(b))
return null;
return booklist.get(booklist.indexOf(b));
}
/**
* Lấy book khi biết stt
* @param index
* @return
*/
public Book GetBook(int index){
if(index<0||index>booklist.size())
return null;
return booklist.get(index);
}
/**
* Số mẫu tin có trong tập hợp
* @return
*/
public int Count(){
return booklist.size();
}
}

Code cho lớp LibRoom.java






package qlsv; import java.io.Serializable;
import java.util.ArrayList;

public class LibRoom implements Serializable{
private static final long serialVersionUID = -8865071229701963561L;
private String RoomID;
private String Location;
private ArrayList<Shelf> shelfList;

public void setRoomID(String RoomID)
{
this.RoomID=RoomID;
}
public String getRoomID()
{
return RoomID;
}
public void setLocation(String Location)
{
this.Location=Location;
}
public String getLocation()
{
return Location;
}
public LibRoom(String location, String roomID) {
Location = location;
RoomID = roomID;
shelfList=new ArrayList<Shelf>();
}
/**
* Them 1 ke moi vao phong
* @param s: ke can them
* @return true nếu thêm được
*/
public boolean AddShelf(Shelf s){
if(shelfList.contains(s))
return false;
return shelfList.add(s);
}
/**
* Lấy 1ke65 trong phòng khi biết mã số
* @param sID: mả số kệ cần lấy
* @return null nếu không có kệ
*/
public Shelf GetShelf(String sID){
Shelf s=new Shelf(sID,”");
if(!shelfList.contains(s))
return null;
return shelfList.get(shelfList.indexOf(s));
}

public Shelf getShelf(int index){
if(index<0||index>shelfList.size())
return null;
return shelfList.get(index);
}

/**
* Xóa bỏ 1 shelf trong room
* @param sID
* @return
*/
public boolean RemoveShelf(String sID){
Shelf s=new Shelf(sID,”");
if(!shelfList.contains(s))
return false;
return shelfList.remove(s);
}
/**
* Số shelf có trong phòng
* @return
*/
public int Count(){
return shelfList.size();
}
}

Code cho Giao diện, lớp BookMS.java






package gui; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import qlsv.Book;
import qlsv.Shelf;
import qlsv.LibRoom;
import db.Database;

@SuppressWarnings(“all”)
public class BookMS extends JFrame implements ActionListener, TreeSelectionListener, ListSelectionListener{
private final String DB_NAME=”lib.db”;
private DefaultMutableTreeNode root;
private DefaultTreeModel treeModel;
private JTree tree;

private DefaultListModel dlmBook;
private JList lstBook;

private JTextField tfID,tfTitle,tfAuthor,tfPages;
private JButton btThem,btLuu,btSua,btXoa;
private JButton btAddShelf,btRemShelf;

private LibRoom db=null;//dùng nạp toàn bộ csdl
private Shelf selShelf=null;

public BookMS() {
super(“Quản lý thư viện”);
addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent arg0) {
//lưu csdl
SaveDB();
//thoat
System.exit(1);
}
});
setSize(600,400);
TaoHeader();
TaoGUI();
LoadDB();
/*db.AddShelf(new Shelf(“s01″,”Tiểu thuyết 3 xu”));
db.AddShelf(new Shelf(“s02″,”Sách Tin học”));
db.AddShelf(new Shelf(“s03″,”Sách Ngoại ngữ”));*/
LockText(true);//không cho sửa
}
/**
* Hàm này thực thi khi bắt đầu chạy chương trình
*/
void LoadDB(){
try {
if(!new File(DB_NAME).exists()){//chưa tồn tại csdl
db=new LibRoom(“bien hoa”,”room001″);
}
else{
Database b=new Database();
db=(LibRoom)b.DeserialObject(DB_NAME);
//xây dựng tree
BuildTree();
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, “Lỗi nạp CSDL”);
}
}
/**
* Xây dựng tree dựa trên DB
*/
void BuildTree() {
root.removeAllChildren();
for (int i = 0; i < db.Count(); i++) {
Shelf sf=db.getShelf(i);
root.add(new DefaultMutableTreeNode(sf));
}
tree.updateUI();//cập nhật lên jtree
}
/**
* Chạy khi kết chương trình
* dùng để update dữ liệu xuống file
*/
void SaveDB(){
try {
new Database().SerialObject(db, DB_NAME);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, “Lỗi lưu CSDL”);
}
}

void TaoHeader(){
JLabel lbl=new JLabel(“LIBRARY MANAGMENT SYSTEM”,JLabel.CENTER);
lbl.setFont(new Font(“Arial”,Font.BOLD,30));
lbl.setForeground(Color.blue);
this.add(lbl,BorderLayout.NORTH);
}
void TaoGUI(){

//tạo tree
root=new DefaultMutableTreeNode(“Lib room”);
treeModel=new DefaultTreeModel(root);
tree=new JTree(treeModel);
tree.addTreeSelectionListener(this);
JScrollPane treePane=new JScrollPane(tree);

JPanel pLeft=new JPanel(new BorderLayout());
pLeft.add(treePane,BorderLayout.CENTER);
JPanel pFunc=new JPanel();
pFunc.add(btAddShelf=new JButton(“Add Shelf”));
pFunc.add(btRemShelf=new JButton(“Remove Shelf”));
btAddShelf.addActionListener(this);
btRemShelf.addActionListener(this);
pLeft.add(pFunc,BorderLayout.SOUTH);

JPanel pCen=new JPanel(new BorderLayout());
JSplitPane spPane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,pLeft,pCen);
this.add(spPane,BorderLayout.CENTER);

//Pane details
JPanel pList=new JPanel(new BorderLayout());
JPanel pDetails=new JPanel(new BorderLayout());

pList.setBorder(BorderFactory.createTitledBorder(“Book listing…”));
pDetails.setBorder(BorderFactory.createTitledBorder(“Selected book informations”));

pCen.add(pList,BorderLayout.CENTER);
pCen.add(pDetails,BorderLayout.SOUTH);
//Them list book
dlmBook=new DefaultListModel();
lstBook=new JList(dlmBook);
pList.add(new JScrollPane(lstBook));
lstBook.setPreferredSize(new Dimension(200,200));
lstBook.addListSelectionListener(this);

//tạo details
Box b=Box.createVerticalBox();
Box b1=Box.createHorizontalBox();
Box b2=Box.createHorizontalBox();
Box b3=Box.createHorizontalBox();
Box b4=Box.createHorizontalBox();
Box b5=Box.createHorizontalBox();

b.add(b1);b.add(Box.createVerticalStrut(7));
b.add(b2);b.add(Box.createVerticalStrut(7));
b.add(b3);b.add(Box.createVerticalStrut(7));
b.add(b4);b.add(Box.createVerticalStrut(7));
b.add(b5);b.add(Box.createVerticalStrut(7));

JLabel l1,l2,l3,l4;
b1.add(l1=new JLabel(“Book ID:”,JLabel.RIGHT));b1.add(tfID=new JTextField(20));
b2.add(l2=new JLabel(“Title:”,JLabel.RIGHT));b2.add(tfTitle=new JTextField(20));
b3.add(l3=new JLabel(“Author:”,JLabel.RIGHT));b3.add(tfAuthor=new JTextField(20));
b4.add(l4=new JLabel(“No. Pages:”,JLabel.RIGHT));b4.add(tfPages=new JTextField(20));

l1.setPreferredSize(l4.getPreferredSize());
l2.setPreferredSize(l4.getPreferredSize());
l3.setPreferredSize(l4.getPreferredSize());

b5.add(btThem=new JButton(“Thêm”));btThem.addActionListener(this);
b5.add(btLuu=new JButton(“Lưu”));btLuu.addActionListener(this);btLuu.setEnabled(false);
b5.add(btSua=new JButton(“Sửa”));btSua.addActionListener(this);
b5.add(btXoa=new JButton(“Xóa”));btXoa.addActionListener(this);
pDetails.add(b,BorderLayout.CENTER);
}

private void LockText(boolean status){
tfID.setEditable(!status);
tfPages.setEditable(!status);
tfTitle.setEditable(!status);
tfAuthor.setEditable(!status);
}

@Override
public void actionPerformed(ActionEvent e) {
Object o=e.getSource();
if(o.equals(btAddShelf)) {
String sID=JOptionPane.showInputDialog(“Nhập Mã số kệ:”);
String sName=JOptionPane.showInputDialog(“Nhập tên kệ:”);
if(sID==null||sName==null)
return;
if(sID.trim().equals(“”)||sName.trim().equals(“”)) {
JOptionPane.showMessageDialog(null, “Cần nhập thông tin đầy đủ mới lưu được”);
return;
}
Shelf sf=new Shelf(sID,sName);
if(db.AddShelf(sf)) {
BuildTree();
}
else
JOptionPane.showMessageDialog(null, “Không thêm được kệ sách này”);
}
else if(o.equals(btRemShelf)) {
try {
if(selShelf==null) {
JOptionPane.showMessageDialog(null, “Chọn kệ sách cần xóa trước đã”);
return;
}
if(JOptionPane.showConfirmDialog(null,
“Bạn chắc chắn xóa cuốn sách này chứ?”,
“Xác nhận”,JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION) {
DefaultMutableTreeNode selNode=(DefaultMutableTreeNode)tree.getSelectionPath().getLastPathComponent();
root.remove(selNode);
if(db.RemoveShelf(selShelf.getShelfID()))
BuildTree();
}
}catch (Exception ex) {
JOptionPane.showMessageDialog(null, “Không xóa được”);
System.out.println(ex);
}
}
else if(o.equals(btThem)){
if(btThem.getText().equalsIgnoreCase(“Thêm”)){
btThem.setText(“Hủy bỏ”);
btLuu.setEnabled(true);
btXoa.setEnabled(false);
btSua.setEnabled(false);
LockText(false);
}else{
btThem.setText(“Thêm”);
btLuu.setEnabled(false);
btXoa.setEnabled(true);
btSua.setEnabled(true);
LockText(true);
}
}
else if(o.equals(btLuu)){
if(tfID.getText().trim().equals(“”)||
tfTitle.getText().trim().equals(“”)||
tfAuthor.getText().trim().equals(“”)||
tfPages.getText().trim().equals(“”)){
JOptionPane.showMessageDialog(null, “Không được để trống”);
return;
}
int pages=0;
try {
pages = Integer.parseInt(tfPages.getText());
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, “Phải nhập số nguyên vào số trang”);
tfPages.selectAll();tfPages.requestFocus();
return;
}
if(btThem.isEnabled()){//nút lưu của nút thêm
Book b=new Book(tfID.getText(),tfTitle.getText(),
tfAuthor.getText(),pages);
if(selShelf!=null){
if(selShelf.AddBook(b)) {
dlmBook.addElement(b);
//khôi phục tình trạng
btThem.setText(“Thêm”);
btLuu.setEnabled(false);
btXoa.setEnabled(true);
btSua.setEnabled(true);
LockText(true);
}
else
JOptionPane.showMessageDialog(null, “Không thêm được. Trùng khóa”);
}
else
JOptionPane.showMessageDialog(null, “Phải chọn kệ trước”);
}
else{//nút lưu là của nút sửa
if(selShelf!=null) {
Book b=new Book(tfID.getText(),tfTitle.getText(),
tfAuthor.getText(),Integer.parseInt(tfPages.getText()));
if(!selShelf.UpdateBookInfos(tfID.getText(), b))
JOptionPane.showMessageDialog(null, “Không update được”);
else {
BuildList();
btSua.setText(“Sửa”);
btLuu.setEnabled(false);
btXoa.setEnabled(true);
btThem.setEnabled(true);
LockText(true);
lstBook.setEnabled(true);
tree.setEnabled(true);
}
}
else
JOptionPane.showMessageDialog(null, “Không update được. Chọn kệ trước”);
}
}
else if(o.equals(btSua)) {
if(tfID.getText().trim().equals(“”)) {
JOptionPane.showMessageDialog(null, “Hãy chọn sách cần sửa thông tin trước”);
return;
}
if(btSua.getText().equalsIgnoreCase(“Sửa”)){
btSua.setText(“Hủy bỏ”);
btLuu.setEnabled(true);
btXoa.setEnabled(false);
btThem.setEnabled(false);
LockText(false);tfID.setEditable(false);
lstBook.setEnabled(false);
tree.setEnabled(false);
}else{
btSua.setText(“Sửa”);
btLuu.setEnabled(false);
btXoa.setEnabled(true);
btThem.setEnabled(true);
LockText(true);
lstBook.setEnabled(true);
tree.setEnabled(true);
}
}
else if(o.equals(btXoa)) {
String id=tfID.getText();
if(id.trim().equals(“”)) {
JOptionPane.showMessageDialog(null, “Bạn cần chọn cuốn sách cần gỡ bỏ trước đã”);
return;
}
if(JOptionPane.showConfirmDialog(null,
“Bạn chắc chắn xóa cuốn sách này chứ?”,
“Xác nhận”,JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION) {

if(!selShelf.RemoveBook(id))
JOptionPane.showMessageDialog(null, “Không xóa được”);
else {
BuildList();
}
}
}
}

//khi chọn lên tree sẽ liệt kê các sách của kệ đang chọn
@Override
public void valueChanged(TreeSelectionEvent te) {
try {
DefaultMutableTreeNode selNode=(DefaultMutableTreeNode)tree.getSelectionPath().getLastPathComponent();
if(selNode.getLevel()>0) {
selShelf=(Shelf)selNode.getUserObject();
//đưa danh sách các book vào list
BuildList();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}

private void BuildList() {
dlmBook.clear();
for (int i = 0; i < selShelf.Count(); i++) {
Book b=selShelf.GetBook(i);
dlmBook.addElement(b);
}
}
//Khi chọn lên 1 cuốn sách trong jlist
//sẽ hiển thị thông tin chi tiết trên các textfield
@Override
public void valueChanged(ListSelectionEvent arg0) {
try {
Book selBook=(Book)lstBook.getSelectedValue();
if(selBook!=null) {
tfID.setText(selBook.getBookID());
tfTitle.setText(selBook.getBookTitle());
tfAuthor.setText(selBook.getAuthorName());
tfPages.setText(selBook.getNoPages()+”");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Code cho lớp Starting.java






package gui; public class Stating {
public static void main(String[] args) {
new BookMS().setVisible(true);
}
}





Code cho lop database

package db;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Database {
public void SerialObject(Object obj,String filename)throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(obj);
oos.close();
}

public Object DeserialObject(String filename)throws Exception{
Object obj=null;
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(filename));
obj=ois.readObject();
return obj;
}
}

Đây là phiên bản file JAR tự chạy có bao gồm source code.

Chúc thành công!

Post a Comment

أحدث أقدم