Sắp xếp các hàng trong bảng

Bảng dữ liệu thường được yêu cầu tổ chức dưới nhiều dạng khác nhau. Để tiện theo dõi và tìm kiếm, bảng kết quả cần được sắp xếp theo thứ tự tăng hoặc giảm theo các giá trị của một cột nào đó.

Ví dụ 4.8. Ta hãy tổ chức lại bảng các hành tinh ở ví dụ 4.5 sao cho khi nhấn đúp vào tên của một cột nào đó thì bảng sẽ được sắp xếp lại theo thứ tự các giá trị của cột đó. Vi dụ, nhấn đúp vào cột Moons thì bảng được sắp xếp theo thứ tự tăng dần của sổ lượng vệ tinh của các hành tinh như hình 4.11.

Để sắp xếp được các hàng ta sử dụng mô hình bộ lọc, nó lưu trữ các tham chiếu tới mô hình bảng hiện thời. Khi JTable cần tìm một giá trị, mô hình bộ lọc sẽ tính chỉ số cùa cột hiện thời (cột được nhấn đúp) và nhận lại giá trị từ mô hình bảng.

public Object getValueAt(int r, int c){

return model.getValueAt (rows[r].index, c);

Mô hình bộ lọc làm nhiệm vụ sắp xếp giữa JTable và TableModel như sau.

Ta thực hiện sắp xếp các đối tượng của Row. Mỗi đối tượng cúa Row có chứa chì sổ index của cột trong mô hình bảng. So sánh hai đối tượng đó như sau: tìm các phần tù trong mô hình và so sảnh chúng.

model.getValueAt (rl, c).compareTo(model.getValueAt (r2, c))

Trong đó, rl, r2 là hai chỉ số của cột trong Row và c là cột mà các phần từ của nó cần sắp xếp.

Lớp Row được xây dựng riêng ờ trong lớp SortFilterMbdel vi phương thức compareTo () chi cần truy cập đến mô hình và cột hiện thời trong mô hình sắp xếp.

class SortFilterModel extends AbstractTableModel{

//…

public SortFilterModel(TableModel m){ model = m;

rows = new Row [model. getRowCount ()] ; for(int i = 0; i < rows.length; i++){ rows[i] = new Row(); rows[i].index = i;

}

}

public void sort(int c){ sortColumn = c;

Arrays.sort(rows); fireTableDataChanged();

}

//…

private class Row implements Comparable{ public int index;

public int compareTo(Object other){ Row otherRow = (Row)other;

Object a = model.getValueAt(index,sortColưmn);

Cfoject b = model.getValueftf (otberRow.index, sortColirrn) ;

if(a instanceof Comparable)

return ( (Corrparable) a) . compareTo (b) ;

else

return index – otherRow.index;

}

}

}

Cuối cùng, chương trình hiển thị bàng các hành tinh, trong đó cho phép sắp xếp theo các cột khi được nhấn đúp, được viết như sau.

// TableSort.java

import java.awt.*; import java.awt.event.*; import java.util.*; import j avax. swing.*; import javax.swing,event. *; import j avax.swing.table.*;

public class TableSort{

public static void main(String args[]){

JFrame fr = new TableSortFrame(); fr.show();

}

}

class SortFilterModel extends AbstractTableModel{

private TableModel model; private int sortColumn; private Row[] rows;

public SortFilterModel(TableModel m){ model = m;

rows = new Row[model.getRowCount()];

for(int i = 0; i < rows.length; i++) ( rows[i] = new Row(); rows[i].index = i;

}

}

public void sort(int c){
sortColumn = c;

Arrays.sort(rows); fireTableDataChanged();

}

public void addMouseListener(final JTable table){

table.getTableHeader().addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent evt){

// Kiểm ừa xem có kích chuột đúp hay không if(evt.getClìckCount() < 2) return;

// Nếu có cột được kích đúp

int tableColumn = table.columnAtPoint(evt.getPoint()) ;

// Chuyền vào chi số cùa mô hình và sắp xểp

int irodelGolưm = table. convert ColumnlndexTcModel (tableColumn); sort(modelColumn);

}

});

}

//

public Object getValueAt(int r, ínt c {

return model.getValueAt{ìows[r].iidex, c);

}

public boolean isCellEditalLe(int r, _nt c){

return model.isCellEdit ible(rows.r’.index, c);

} public void setValueAt (Ob; ec t aValU’ỉ, nt r, int c) (

model.setValueAt (aValue, rows[r].index, c);

}

// Định nghĩa các phương thức còn lại cùa mò hình

public int getRowCount0{

return model.getRowCount();

}

public int getColumnCount(){

return model.getColumnCount();

}

public String getColumnName(int c){ return model.getColumnName (c);

}

public Class getColumnClass(int c){ return model.getColumnClass(c);

}

// Lớp bên trong lưu giữ các chì số cùa các hàng.

private class Row implements Comparable{ public int index;

public int compareTo(Object other){

Row otherRow = (Row)other;

Object a = model.getValueAt(index,sortColumn); Object b = model.getValueAt (otherRow.index, sortColum);

if(a instanceof Comparable)

return ((Comparable)a).campareTo(b);

else

return index – otherRow.index;

}

}

}

class TableSortFrame extends JFrame

{

public TableSortFrame(){

setTitie(“Table Sorting”); setsize(300, 200);

addWindowListener(new WindowAdapter(){

public void windowclosing(WindowEvent e){ System.exit(0);

}

});

// Xây dựng mô hình bảng và bộ sếp xếp,

DefaultTableModel model

= new DefaultTableModel(cells, columnNames); SortFilterModel sorter = new SortFilterModel(model); // Hiển thị bảng

JTable table = new JTable(sorter);

Container content = getContentPane(); content.add(new JScrollPane(table), “Center”);

H Đặt bảng vào bộ xử lý kích đúp chuột sorter.addMouseListener(table);

}

// Mảng dừ liệu về các hành tinh

private Objectn [] cells = {

{“Mercury”, new Double(2440), new Integer(0), Boolean.FALSE, Color.yellow},

{“Venus”, new Double(6052), new Integer(0), Boolean.FALSE, Color.yellow},

{“Earth”, new Double(6378), new Integer(l), Boolean. FALSE, Color.blue},

{“Mars”, new Double(3397), new Integer(2), Boolean.FALSE, Color.red},

{“Jupiter”, new Double(71492), new Integer(16), Boolean.TRUE, Color.orange},

{“Saturn”, new Double(60268), new Integer(18), Boolean.TRUE, Color.orange},

{“Uranus”, new Double(25558), new Integer(17),

Boolean.TRUE, Color.blue},

{“Neptune”, new Double(24766), new Integer(8),

Boolean.TRUE, Color.blue),

{“Pluto”, new Double(1137), new Integer(1),

Boolean.FALSE, Color.black )

};

// Tên cùa các cột

private string)] columnNames = {

“Planet”, “Radius”, “Moons”, “Gaseous”, “Color”

};

}

javax. swing, tabic. T ableModel                                   API

  • int getRowCount (): Cho biết số cột trong mô hình bảng
  • int getColumnCount (int row, int column) : Cho biết số hàng
  • Object getValueAt (int row, int column): Cho biết đối tượng ớ ô tưcmg ứng
  • void setgetValueAt (Object newValue, int row, int column): Đặt lại giá trị newValue vào ô tương ứng.
  • boolean isCellEditable(int row, int column): Kết quả là true nếu ô tương ứng là thay đối được.
  • String getColumnName (int column) : Đọc tiêu đề (tên) cùa cột.
  • Class getColumnClas (int columnlndex) : Xác định lóp chứa giá trị ở cột

javax.swing.table.JTable                                                                                           API

  • JTableHeader getTableHeader (): Đọc tiêu đề cùa bảng
  • int columnAtPoint (Point p): Cho số hiệu của cột ờ toạ độ
  • int convertColumnlndexToModel (int tableColumn): Cho lại chì số mô hình cùa cột sau khí được chuyển đổi. Giá trị kết quả khác với tableColumn nếu một số cột bị loại khỏi bảng hoặc bị che giấu.
  • void setRowHeight (int height): Đặt chiều cao cho các hàng là height

* Rectangle getCellTect (int row, int column, boolean includeSpacing) : Xác định khung chữ nhật bao quanh ô tương ứng. Nếu includeSpacing thì kể cả các dấu cách.

  • Color get Select ionBackground (): Xác định màu nền
  • Color getSelectionForeground () : Xác định màu vẽ
  • int convertColumnlnđexToModel(int tableColumn):