Thứ Năm, 21 tháng 3, 2013

Thêm-xóa-sửa với jtable trong java


Qua một thời gian mình thấy có nhiều bạn mới làm việc với jtable có nhiều lúng túng ở các tương tác với dữ liệu của table, mình nhận thấy có 2 điều sau.


  1. Sử dụng mảng 2 chiều để khởi tạo dữ liệu cho bảng, về sau khó xử lý khi dữ liệu thay đổi.

  2. Thường muốn tương tác trực tiếp với table để thay đổi dữ liệu của nó

hai việc trên làm cho dòng tư duy logic khi xử lý gặp một số vấn đề.

Topic này mình sẽ hướng dẫn các bạn mới một cách sử lý dữ liệu bảng, sử dụng dữ liệu theo kiểu tham chiếu.

Nếu các bạn xem javaapi của JTable thì các bạn sẽ thấy nó có nhiều constructor khác nhau, nhận vào nhiều định dạng và kiểu dữ liệu, ở đây mình sẽ không quan trọng về việc sử dụng constructor nào mà chỉ quan tâm đến việc dữ liệu được tạo vào sử dụng cho nó như thế nào.

Để set dữ liệu cho table, mình sử dụng phương thức

PHP:

setModel(TableModel dataModel) 


TableModel là new DefaultTableModel(Vector data, Vector columnnames)

PHP:

tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));//Set dữ liệu cho bảng


tableRecords và tableTitle là 2 vector

PHP:

    Vector tableRecords = new Vector();//Vector chứa các dòng dữ liệu của bảng.
Vector tableTitle = new Vector();//Vector chứa các tiêu đề của bảng.


Vậy sau khi khởi tạo

PHP:

tableList = new javax.swing.JTable();


thì chúng ta sẽ khởi tạo dữ liệu cho vector tableTitle và thực hiện setModel

PHP:

        tableTitle.add("ID");
tableTitle.add("Name");
tableTitle.add("Phone");
tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));//Set dữ liệu cho bảng



ok rồi, đến đây ta đã có một bảng có 3 cột là "ID, Name, Phone"

Tiếp theo ta thực hiện việc thay đổi dữ liệu và update cho table, lấy mẫu là việc add thêm một dòng vào bảng.

PHP:

        if (e.getSource() == butAdd) {
Vector record = new Vector();
record.add(txtId.getText());
record.add(txtName.getText());
record.add(txtPhone.getText());
tableRecords.add(record);
tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));
//        JOptionPane.showMessageDialog(rootPane, "Thêm thành công");
}


như kết cấu vừa nêu, chúng ta sử dụng tableRecords là một vector để chứa tất cả các dòng dữ liệu của table. Ở phần code bên trên chúng ta tạo ra một dòng dữ liệu mới là một vector record sau đó add các giá trị tương ứng từ các text field txt.. vào và thêm vector đó vào vector tableRecords 

PHP:

tableRecords.add(record);


đến đây tableRecords chứa một vector con có các giá trị lấy từ các textfield, việc còn lại là set dữ liệu

PHP:


tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));


Đối với chương trình cần lưu trữ dữ liệu thì trước thao tác set dữ liệu chúng ta thực hiện lấy cữ liệu để lưu trữ, dữ liệu đó nằm trong vector tableRecords.

JTableDataManageExample.java

PHP:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* JTableDataManageExample2.java
*
* Created on Sep 29, 2011, 7:32:47 PM
*/
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
*
* @author Thanh Nhan <JackV at congdongjava.com>
*/
public class JTableDataManageExample extends JFrame implements ActionListener, MouseListener {

/** Creates new form JTableDataManageExample2 */
public JTableDataManageExample() {
initComponents();

butAdd.addActionListener(this);
butDelete.addActionListener(this);
butUpdate.addActionListener(this);

tableList.addMouseListener(this);

tableTitle.add("ID");
tableTitle.add("Name");
tableTitle.add("Phone");

tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));//Set dữ liệu cho bảng

setSize(500, 600);
setLocationRelativeTo(null);

setTitle("JTable - add,delete,update - JackV congdongjava.com");
}
Vector tableRecords = new Vector();//Vector chứa các dòng dữ liệu của bảng.
Vector tableTitle = new Vector();//Vector chứa các tiêu đề của bảng.

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == butAdd) {
Vector record = new Vector();
record.add(txtId.getText());
record.add(txtName.getText());
record.add(txtPhone.getText());
tableRecords.add(record);
tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));
//        JOptionPane.showMessageDialog(rootPane, "Thêm thành công");
txtId.setText("");
txtName.setText("");
txtPhone.setText("");
txtId.requestFocus();
}

if (e.getSource() == butDelete) {
int iDongDaChon = tableList.getSelectedRow();
if (iDongDaChon == -1) {
JOptionPane.showMessageDialog(rootPane, "Bạn chưa chọn record cần xóa");
} else {
Vector vDongDaChon = (Vector) tableRecords.get(iDongDaChon);
String idCuaDongDaChon = vDongDaChon.get(0).toString();
if (JOptionPane.showConfirmDialog(rootPane, "Bạn có chắc chắn muốn xóa dòng đã chọn có id: " + idCuaDongDaChon, "Lua chon", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
tableRecords.remove(iDongDaChon);
tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));
}
}
}

if (e.getSource() == butUpdate) {
int iDongDaChon = tableList.getSelectedRow();
if (iDongDaChon == -1) {
JOptionPane.showMessageDialog(rootPane, "Xin vui lòng chọn dòng cần sửa");
} else {
Vector record = new Vector();
record.add(txtViewId.getText());
record.add(txtViewName.getText());
record.add(txtViewPhone.getText());
tableRecords.set(iDongDaChon, record);
tableList.setModel(new DefaultTableModel(tableRecords, tableTitle));
//            JOptionPane.showMessageDialog(rootPane, "Cập nhật xong");
}
}
}

@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() == tableList) {
int iDongDaChon = tableList.getSelectedRow();
if (iDongDaChon != -1) {
Vector vDongDaChon = (Vector) tableRecords.get(iDongDaChon);
String id = vDongDaChon.get(0).toString();
String name = vDongDaChon.get(1).toString();
String phone = vDongDaChon.get(2).toString();
txtViewId.setText(id);
txtViewName.setText(name);
txtViewPhone.setText(phone);
}
}
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

private void initComponents() {

jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jPanel2 = new javax.swing.JPanel();
jPanel4 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
txtId = new javax.swing.JTextField();
jPanel5 = new javax.swing.JPanel();
jLabel3 = new javax.swing.JLabel();
txtName = new javax.swing.JTextField();
jPanel6 = new javax.swing.JPanel();
jLabel4 = new javax.swing.JLabel();
txtPhone = new javax.swing.JTextField();
jPanel3 = new javax.swing.JPanel();
butAdd = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
tableList = new javax.swing.JTable();
jPanel7 = new javax.swing.JPanel();
jPanel13 = new javax.swing.JPanel();
butDelete = new javax.swing.JButton();
jPanel8 = new javax.swing.JPanel();
jPanel9 = new javax.swing.JPanel();
jLabel6 = new javax.swing.JLabel();
txtViewId = new javax.swing.JTextField();
jPanel10 = new javax.swing.JPanel();
jLabel7 = new javax.swing.JLabel();
txtViewName = new javax.swing.JTextField();
jPanel11 = new javax.swing.JPanel();
jLabel8 = new javax.swing.JLabel();
txtViewPhone = new javax.swing.JTextField();
jPanel12 = new javax.swing.JPanel();
butUpdate = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jPanel1.setLayout(new java.awt.GridLayout(3, 0));

jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Quản Lý Danh Sách");
jPanel1.add(jLabel1);

jPanel2.setLayout(new java.awt.GridLayout(1, 0));

jPanel4.setLayout(new java.awt.BorderLayout());

jLabel2.setText(" ID: ");
jPanel4.add(jLabel2, java.awt.BorderLayout.WEST);
jPanel4.add(txtId, java.awt.BorderLayout.CENTER);

jPanel2.add(jPanel4);

jPanel5.setLayout(new java.awt.BorderLayout());

jLabel3.setText(" Name: ");
jPanel5.add(jLabel3, java.awt.BorderLayout.WEST);
jPanel5.add(txtName, java.awt.BorderLayout.CENTER);

jPanel2.add(jPanel5);

jPanel6.setLayout(new java.awt.BorderLayout());

jLabel4.setText(" Phone: ");
jPanel6.add(jLabel4, java.awt.BorderLayout.WEST);
jPanel6.add(txtPhone, java.awt.BorderLayout.CENTER);

jPanel2.add(jPanel6);

jPanel1.add(jPanel2);

butAdd.setText("Thêm");

jPanel3.add(butAdd);

jPanel1.add(jPanel3);

getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_START);

jScrollPane1.setViewportView(tableList);

getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

jPanel7.setLayout(new java.awt.GridLayout(3, 0));

butDelete.setText("Xóa");
jPanel13.add(butDelete);

jPanel7.add(jPanel13);

jPanel8.setLayout(new java.awt.GridLayout(1, 0));

jPanel9.setLayout(new java.awt.BorderLayout());

jLabel6.setText(" ID: ");
jPanel9.add(jLabel6, java.awt.BorderLayout.WEST);
jPanel9.add(txtViewId, java.awt.BorderLayout.CENTER);

jPanel8.add(jPanel9);

jPanel10.setLayout(new java.awt.BorderLayout());

jLabel7.setText(" Name: ");
jPanel10.add(jLabel7, java.awt.BorderLayout.WEST);
jPanel10.add(txtViewName, java.awt.BorderLayout.CENTER);

jPanel8.add(jPanel10);

jPanel11.setLayout(new java.awt.BorderLayout());

jLabel8.setText(" Phone: ");
jPanel11.add(jLabel8, java.awt.BorderLayout.WEST);
jPanel11.add(txtViewPhone, java.awt.BorderLayout.CENTER);

jPanel8.add(jPanel11);

jPanel7.add(jPanel8);

butUpdate.setText("Sửa");
jPanel12.add(butUpdate);

jPanel7.add(jPanel12);

getContentPane().add(jPanel7, java.awt.BorderLayout.PAGE_END);

pack();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(JTableDataManageExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(JTableDataManageExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(JTableDataManageExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(JTableDataManageExample2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {
new JTableDataManageExample().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton butAdd;
private javax.swing.JButton butDelete;
private javax.swing.JButton butUpdate;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel10;
private javax.swing.JPanel jPanel11;
private javax.swing.JPanel jPanel12;
private javax.swing.JPanel jPanel13;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JPanel jPanel6;
private javax.swing.JPanel jPanel7;
private javax.swing.JPanel jPanel8;
private javax.swing.JPanel jPanel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable tableList;
private javax.swing.JTextField txtId;
private javax.swing.JTextField txtName;
private javax.swing.JTextField txtPhone;
private javax.swing.JTextField txtViewId;
private javax.swing.JTextField txtViewName;
private javax.swing.JTextField txtViewPhone;
// End of variables declaration
}



Khi bạn chạy thử bạn sẽ nhận ra một điều là nếu bạn sửa trực tiếp dữ liệu của một ô trên table thì dữ liệu tại vị trí tương ứng trên vector data sẽ thay đổi theo.

Làm theo cách này bạn nhớ là dữ liệu luôn nằm trong vector tableRecords không cần phải tương tác với jtable, tuy nhiên, một số trường hợp do sort mà không thao tác trực tiếp với tableRecords thì thường là sẽ sai index.

0 nhận xét:

Đăng nhận xét