Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Biểu diễn quan hệ mối quan hệ master-details bằng JTree – JTable

Cho CSDL như hình sau:

masterdetailjtree_011.png

Trong MySQL, bạn có thể tạo 2 bảng như sau:
masterdetailjtree_04.png
masterdetailjtree_03.png

Mong muốn của chúng ta là sau khi làm xong, chúng ta sẽ có kết quả như hình sau:
masterdetailjtree_02.png

Khi chương trình thực thi sẽ nạp danh sách lớp vào JTree, khi người dùng chọn 1 lớp học tên JTree, danh sách sinh viên của lớp đó sẽ hiển thị lên 1 JTable.

Đầu tiên ta xây dựng 2 lớp Sinh vien và Lophoc đặc tả cho 2 bảng như sau:

File Lophoc.java

/**
* Đặc tả thông tin về 1 Lớp học
*/
package vovanhai.wordpress.com.masterdetails;

public class Lophoc {
private String msLop;
private String tenLop;
private String giavienCN;
public Lophoc() {
super();
}
public Lophoc(String msLop, String tenLop, String giavienCN) {
super();
this.msLop = msLop;
this.tenLop = tenLop;
this.giavienCN = giavienCN;
}
public String getMsLop() {
return msLop;
}
public void setMsLop(String msLop) {
this.msLop = msLop;
}
public String getTenLop() {
return tenLop;
}
public void setTenLop(String tenLop) {
this.tenLop = tenLop;
}
public String getGiavienCN() {
return giavienCN;
}
public void setGiavienCN(String giavienCN) {
this.giavienCN = giavienCN;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((msLop == null) ? 0 : msLop.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;
Lophoc other = (Lophoc) obj;
if (msLop == null) {
if (other.msLop != null)
return false;
} else if (!msLop.equals(other.msLop))
return false;
return true;
}
@Override
public String toString() {
return tenLop;
}

}

và file Sinhvien.java

package vovanhai.wordpress.com.masterdetails;

public class Sinhvien {
private String msSV;
private String hoTen;
private String email;
private String diaChi;
private String msLop;
public Sinhvien() {
super();
}
public Sinhvien(String msSV, String hoTen, String email, String diaChi,
String msLop) {
super();
this.msSV = msSV;
this.hoTen = hoTen;
this.email = email;
this.diaChi = diaChi;
this.msLop = msLop;
}
public String getMsSV() {
return msSV;
}
public void setMsSV(String msSV) {
this.msSV = msSV;
}
public String getHoTen() {
return hoTen;
}
public void setHoTen(String hoTen) {
this.hoTen = hoTen;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDiaChi() {
return diaChi;
}
public void setDiaChi(String diaChi) {
this.diaChi = diaChi;
}
public String getMsLop() {
return msLop;
}
public void setMsLop(String msLop) {
this.msLop = msLop;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((msSV == null) ? 0 : msSV.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;
Sinhvien other = (Sinhvien) obj;
if (msSV == null) {
if (other.msSV != null)
return false;
} else if (!msSV.equals(other.msSV))
return false;
return true;
}
@Override
public String toString() {
return hoTen;
}
}

Ta xây dụng lớp để kết nối đến CSDL. Ở đây tôi dùng MySQL làm RDBMS. Code như sau:

package vovanhai.wordpress.com.masterdetails;

import java.sql.Connection;
import java.sql.DriverManager;

public class ConnectionFactory {
private static Connection con;

public static Connection CreateMySQLConnection(String database)throws Exception{
String url=”com.mysql.jdbc.Driver”;
Class.forName(url);

String dburl=”jdbc:mysql://localhost:3306/”+database+
“?user=root&password=”;
con=DriverManager.getConnection(dburl);
return con;
}
}

Bây giờ ta xây dựng giao diện cũng như các xử lý. Code như sa:

package vovanhai.wordpress.com.masterdetails;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.sql.Connection;
import java.sql.ResultSet;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

public class DisplayMasterDetailsGUI extends JFrame
implements TreeSelectionListener{
//Khai báo dành cho Tree
private DefaultTreeModel treeModel;
private DefaultMutableTreeNode root;
private JTree tree;
//Khai báo dành cho table
private DefaultTableModel tableModel;
private JTable table;

private Connection con;//connection đến DB
private JLabel lblStatus;// hiển thị thông tin thao tác

public DisplayMasterDetailsGUI() {
setTitle(“Master – Details Application. http://www.vovanhai.wordpress.com”);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(700,500);
tieude();
createBody();
buildTree();
bottom();
}
/**
* Tạo giao diện chính
*/
void createBody(){
//tạo cây
root=new DefaultMutableTreeNode(“Lớp học”);
treeModel=new DefaultTreeModel(root);
tree=new JTree(treeModel);
tree.addTreeSelectionListener(this);

//tạo bảng
String []header={“Mã số sv”,”họ tên”,”email”,”địa chỉ”};
tableModel=new DefaultTableModel(header,0);
table=new JTable(tableModel);
table.setPreferredScrollableViewportSize(new Dimension(300,400));
table.getTableHeader().setFont(new Font(“Arial”,Font.BOLD,12));
table.getTableHeader().setForeground(Color.blue);

JPanel pTree=new JPanel(new BorderLayout());
JPanel pTable=new JPanel(new BorderLayout());

JSplitPane spMain=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,pTree,pTable);
spMain.setOneTouchExpandable(true);
this.add(spMain,BorderLayout.CENTER);

pTree.add(new JScrollPane(tree));
tree.setPreferredSize(new Dimension(250,200));
pTable.add(new JScrollPane(table));
}

/**
* Xây dựng cây dựa trên bản lớp
*/
void buildTree(){
try {
con=ConnectionFactory.CreateMySQLConnection(“masterdetailsdemo”);
String sql=”select * from Lophoc”;
ResultSet rs=con.createStatement().executeQuery(sql);

while(rs.next()){
Lophoc lh=new Lophoc(rs.getString(“msLop”),
rs.getString(“tenLop”),
rs.getString(“giaovienCN”));
DefaultMutableTreeNode node=new DefaultMutableTreeNode(lh);
root.add(node);
}
tree.expandRow(0);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Hiển thị danh sách sinh viên trong 1 lớp
* @param classID là mã số lớp chỉ định hiển thị
*/
void displayStudentInclass(String classID){
try {
String sql=”select * from Sinhvien where msLop='”+classID+”‘”;
ResultSet rs=con.createStatement().executeQuery(sql);
//clear table
tableModel.setRowCount(0);
while(rs.next()){
String []row={
rs.getString(“msSv”),
rs.getString(“hoTen”),
rs.getString(“email”),
rs.getString(“diaChi”),
};
tableModel.addRow(row);
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Hiển thị tiêu đề
*/
void tieude(){
JLabel lbl=new JLabel(“MASTER-DETAILS EXAMPLE”,JLabel.CENTER);
lbl.setFont(new Font(“Arial”,Font.BOLD,24));
lbl.setForeground(Color.red);
add(lbl,BorderLayout.NORTH);
}

/**
* Hiển thị thanh status bar
*/
void bottom(){
JPanel p=new JPanel(new BorderLayout());
lblStatus=new JLabel(“information”);
lblStatus.setFont(new Font(“Arial”,Font.PLAIN,13));
lblStatus.setForeground(Color.red);
p.add(lblStatus);
this.add(p,BorderLayout.SOUTH);
}

/**
* Sự kiện cho việc chọn 1 nút trên JTree
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode selNode=(DefaultMutableTreeNode)e.getPath().getLastPathComponent();
if(selNode.isLeaf()){
Lophoc lh=(Lophoc)selNode.getUserObject();
lblStatus.setText(“Đang chọn: “+lh.getMsLop()
+” – Tên lớp: “+lh.getTenLop()
+” – Giáo viên CN: “+lh.getGiavienCN());
displayStudentInclass(lh.getMsLop());
}
else
lblStatus.setText(“Vui lòng chọn lớp để xem danh sách”);
}
}

Tạo lớp Starting.java đảm nhận việc thực thi. Code như sau:

package vovanhai.wordpress.com.masterdetails;

public class Starting {
public static void main(String[] args) {
new DisplayMasterDetailsGUI().setVisible(true);
}
}

Chúc thành công!

15 Responses to “Biểu diễn quan hệ mối quan hệ master-details bằng JTree – JTable”

  1. Guest said

    Chào thầy
    Hiện giờ em muốn tạo thêm 1 button, khi bấm vào button thì nó sẽ xóa tất cả dữ liệu của row đang đc select và xóa luôn trong CSDL. Thầy có thể hướng dẫn em được không

  2. Tim hieu ejb3 said

    Thưa thầy, em đang tìm hiểu về EJB3. Mong thầy hướng dẩn em tìm kiếm theo giá trong ví dụ sau:
    Trong database ta có bảng Book có các trường sau(BookName varchar, Author varchar, Price int)
    Yêu cầu tìm tất cả các book có giá từ …. đến ……

  3. MuaHong said

    Thầy Hải cho em hỏi, ở hai hình 2 và 3, chương trình MySQL Table Editor là ở đâu vậy? Nó là tool có sẵn của MySql (làm sao mở lên) hay là phải cài thêm vậy ạh (source ở đâu)?
    Em xin cảm ơn thầy!

  4. Võ Văn Hải said

    Đây nè bạn:http://dev.mysql.com/downloads/gui-tools/5.0.html

  5. Dung said

    em muốn thay tree bang combobox thì nên làm như thế nào ạ? xin thầy chỉ dẫn thêm. em mới học java nen chưa có nhieuf kinh nghiệm.

  6. toan said

    thầy cho em hỏi lam cách nào để xuất dữ liệu trong java ra dang report vay? em mới học java nên không rành lắm

  7. Võ Văn Hải said

    Dùng BIRT hoặc Jasper report. Em google 1 trong 2 từ khóa này sẽ có giải pháp.

  8. assembly said

    Thầy ơi em mới học java em thử dùng netbean để làm như trên nhưng gặp rất nhiều khó khăn em đã làm đi làm lại rất nhiều nhưng đều thất bại,mong thầy giúp em,em cảm ơn thầy rất nhiều.

  9. Võ Văn Hải said

    Em có thể download code đã pub ở đây

  10. Chào thầy!
    Thầy ơi cho e hỏi về công cụ “ant”. Em đang tìm hiểu về công cụ này nhưng e chưa biết tí về nó, thầy giới thiệu chút về nó giùm e.

  11. Võ Văn Hải said

    Đến URL http://ant.apache.org/ để đọc đi bạn.

  12. Bình Đen said

    em đang sử dụng netbean em muốn thêm mới 1 Nodes vào trong treeview thì làm cách nào, Thầy có biết phần mềm nào hỗ trợ kéo thả mạnh không giống như DEV hỗ trợ cho VS C# ý

  13. Thầy ơi ! thầy có thể giúp em về code java nay được không a ! em đang vướng không biết nó bị lỗi gì cả

    eclipse 3.7
    https://linuxdpswing.googlecode.com/svn/trunk/
    http://code.google.com/p/linuxdpswing/downloads/list

  14. mr said

    Em xây dựng một úng dụng biểu diễn mối quan hệ master_detail bằng jtree và jtable, sử dụng MS SQL Server làm RDBMS.
    Chương trình chạy OK nhưng em có cảm giác nó chạy hơi chậm. CHo em hỏi, nguyên nhân do truy xuát CSDL chậm hay code co vấn đề?

  15. thanhtuan said

    chào thầy!
    em đang sử dụng netbean vậy làm sao khi mình rightclick vào 1 node trong JTree thì nó co thể hiện lên 1 popup menu để lựa chọn
    mong thầy và các bạn giúp đỡ
    xin cảm ơn!

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.