Jtable_Swing part 5


Trong phần này, chúng ta tập trung vào một số thiết lập để làm việc với các thao tác chọn trên một bảng.

JTable là một thành phần hai chiều (hàng và cột): mỗi ô được chọn sẽ có chỉ số hàng và chỉ số cột. Trong khi đó, JList là một thành phần một chiều mà ở đó mỗi một ô chỉ có duy nhất một chỉ số đó là chỉ số hàng. Bởi vì bản chất của JTable là một thành phần hai chiều cho nên thông tin được chọn của bảng không thể được quản lý bởi mộtListSelectionModel. Interface ListSelectionModel chỉ hỗ trợ cho việc quản lý các thông tin được chọn ở hình thức một chiều. Để khắc phục vấn đề này, Jtable sử dụng hai đối tượng của lớp DefaultListSelectionModel.

  • Một đối tượng được quản lý bởi chính bản thân Jtable. Đối tượng này quản lý thông tin được chọn theo dòng
  • Một đối tượng được quản lý bởi TableColumnModel. Đối tượng này quản lý thông tin được chọn theo cột

Như chúng ta đã nói lúc trước, khi một ô được chọn, các ô khác cũng có thể được chọn theo. Điều này tùy thuộc vào việc chúng ta thiết lập cách chọn cho bảng. Trong thực tế, có rất nhiều thiết lập chọn cho một bảng. Interface ListSelectionModel và lớp cài đặt của nó là DefaultListSelectionModel được sử dụng để quản lý việc chọn trên một JTable.

  • Chọn theo hàng: Khi một ô được chọn thì tất cả các ô khác cùng hàng với nó cũng được chọn. Đây là thiết lập chọn mặc định của JTable. JTable cung cấp cho chúng ta hai phương thức là getRowSelectionAllowed vàsetRowSelectionAllowed để cho phép chúng ta truy vấn, thiết lập, hoặc hủy bỏ cơ chế chọn theo hàng cho bảng.
  • Chọn theo cột: Khi một ô được chọn, tất cả các ô khác cùng cột với nó cũng được chọn. Việc truy vấn, thiết lập, hủy bỏ cơ chế chọn theo cột cho bảng được thực hiện bởi hai phương thức getColumnSelectionAllowedvà setColumnSelectionAllowed của JTable
  • Chọn theo ô: Trong chế độ này, việc chọn một ô sẽ không ảnh hưởng gì đến các ô khác. Việc truy vấn, thiết lập, hủy bỏ cơ chế chọn theo ô cho bảng được thực hiện bởi hai phương thức getCellSelectionEnabled vàsetCellSelectionEnabled của JTable. Việc kích hoạt chế độ chọn theo ô sẽ làm vô hiệu hóa hai chế độ là chọn theo hàng và chọn theo cột
Kết hợp các chế độ chọn theo hàng, chọn theo cột và chọn theo ô

Chúng ta có thể sử dụng chế độ chọn theo hàng và chọn theo cột cùng nhau sao cho khi chúng ta nhấp chuột để chọn một ô, tất cả các ô khác trong cùng hàng hoặc cột với nó cũng được chọn. Tuy nhiên việc kích hoạt chế độ chọn theo ô sẽ dẫn đến việc các chế độ chọn theo hàng và chọn theo cột bị mất hiệu lực. Cho ví dụ, giả sử chúng ta có đoạn mã sau:

  1. JTable table;
  2. table.setRowSelectionAllowed(true);
  3. table.setColumnSelectionAllowed(true);
  4. table.setCellSelectionEnabled(true);

Trong đoạn mã trên, mặc dù tất cả các chế độ chọn của bảng đều được kích hoạt tuy nhiên việc kích hoạt chế độ chọn theo ô sẽ vô hiệu hóa hai chế độ kia. Vì thế, mặc dù chúng ta có ba loại thiết lập chế độ chọn cho bảng, nhưng chỉ có bốn tổ hợp của chúng là có ý nghĩa:

  • Chỉ có chế độ chọn theo hàng được kích hoạt
  • Chỉ có chế độ chọn theo cột được kích hoạt
  • Chế độ chọn theo ô được kích hoạt. Khi đó chúng ta không cần quan tâm đến việc hai chế độ còn lại có được kích hoạt hay không
  • Khi mà tất cả các chế độ chọn bị vô hiệu hóa.

Trong trường hợp cuối cùng, khi mà tất cả các chế độ bị vô hiệu hóa, chúng ta không thể chọn bất kì một ô nào trong bảng.

Các chế độ chọn theo danh sách

Khi một ô được chọn, lúc đó một hoặc cả hai đối tượng của ListSelectionModel sẽ được cập nhật theo việc chọn này. Theo mặc định, mỗi model có thể duy trì nhiều khoảng giá trị. Cho ví dụ, như hình dưới đây, trong model sẽ duy trì hai khoảng giá trị được chọn. Khoảng giá trị thứ nhất là các dòng trong bảng có chỉ số từ 0 đến 1 và khoảng giá trị thứ hai là các dòng trong bảng có chỉ số từ 3 đến 4.

Để chọn ra hai khoảng giá trị giống như trên, chúng ta làm các bước như sau:

  1. Chọn dòng trên cùng của bảng
  2. Bấm và giữ phím Shift sau đó nhấp chuột chọn dòng thứ hai. Như vậy đến đây, khoảng thứ nhất của các dòng đã được chọn
  3. Thả phím Shift sau đó bấm và giữ phím Ctrl, chọn dòng thứ tư
  4. Thả phím Ctrl, bấm và giữ phím Shift sau đó nhấp chuột chọn dòng cuối cùng. Lúc này, khoảng thứ hai của các dòng được chọn

Như chúng ta đã làm phía trên, để chọn một khoảng giá trị giữa hai cặp giá trị, chúng ta chỉ việc chọn điểm đầu khoảng giá trị sau đó bấm và giữ phím Shift rồi chọn điểm cuối khoảng giá trị đó. Trong khi đó việc bấm phím Ctrl sẽ cho phép chúng ta chọn một giá trị khác nhưng không làm mất đi những giá trị hay khoảng giá trị đã được chọn trước đó. Một cách chọn khác thay vì sử dụng phím Shift để chọn một khoảng giá trị đó là nhấp chuột lên rồi kéo thả con trỏ trên khoảng giá trị đó. Cho ví dụ, trong trường hợp này, chúng ta có thể nhấp chuột lên một ô của dòng đầu tiên và sau đó kéo thả chuột đến dòng thứ hai, như vậy khoảng giá trị đầu tiên trong bảng sẽ được chọn.

Ví dụ trên đã minh họa cho chế độ chọn mặc định gọi là multiple-interval selection hay là có thể chọn nhiều khoảng giá trị. Đây là một trong ba chế độ mà ListSelectionModel hỗ trợ. Hai chế độ còn lại là single-interval selection và single selection.

Như cái tên đã chỉ ra, chế độ single-interval selection là chế độ cho phép chọn một khoảng giá trị đơn lẻ. Trong ví dụ của chúng ta, nếu chúng ta chọn chế độ single-interval selection thì sau khi khoảng giá trị thứ hai (từ chỉ số hàng 3 đến 4) được chọn, khoảng giá trị thứ nhất (từ chỉ số hàng 0 đến 1) được chọn trước đó sẽ trở thành không được chọn.

Còn trong chế độ single-selection, một ListSelectionModel chỉ cho phép chọn một giá trị đơn lẻ và không thể chọn một khoảng giá trị trong bảng. Cho ví dụ, khi chúng ta kích hoạt chế độ chọn theo cột và single-selection, chúng ta chỉ có thể chọn một cột duy nhất tại một thời điểm.

Như đã nói trước đó, mỗi JTable sẽ duy trì hai đối tượng của ListSelectionModel và cung cấp phương thứcsetSelectionMode để thiết lập chế độ chọn theo danh sách cho cả hai đối tượng đó. Mỗi một chế độ chọn sẽ được biểu diễn bởi một giá trị hằng số được định nghĩa trong ListSelectionModel:

  • MULTIPLE_INTERVAL_SELECTION
  • SINGLE_INTERVAL_SELECTION
  • SINGLE_SELECTION

Chú ý rằng JTable không có phương thức getSelectionMode để lấy về chế độ hiện tại. Phương thức này thuộc về đối tượng của ListSelectionModel. Chúng ta phải lấy thông tin trên từ đối tượng của ListSelectionModel như cách sau:

  1. JTable table;
  2. int oldSlectionMode = table.getSelectionModel().getSelectionMode();
  3. table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

Trở lại ví dụ của chúng ta, để minh họa cho các chế độ chọn và sự kết hợp giữa chúng, chúng ta sẽ sửa đoạn mã trong lớp SimpleTableTest ở file SimpleTableTest.java như sau:

public class SimpleTableTest extends JFrame{ protected JTable table;
  1. public SimpleTableTest(){
  2.     […]
  3.     pane.add(jsp, BorderLayout.CENTER);
  4.     JPanel outerPanel = new JPanel();
  5.     outerPanel.setLayout(new GridLayout(1, 2, 0, 0));
  6.     JPanel innerPanel = new JPanel();
  7.     innerPanel.setLayout(new FlowLayout());
  8.     JCheckBox modeBox = new JCheckBox(“Row”, true);
  9.     modeBox.addItemListener(new ItemListener() {
  10.         public void itemStateChanged(ItemEvent event) {
  11.             JCheckBox box = (JCheckBox)(event.getSource());
  12.             table.setRowSelectionAllowed(box.isSelected());
  13.         }
  14.     });
  15.     innerPanel.add(modeBox);
  16.     modeBox = new JCheckBox(“Column”);
  17.     modeBox.addItemListener(new ItemListener() {
  18.         public void itemStateChanged(ItemEvent event) {
  19.             JCheckBox box = (JCheckBox)(event.getSource());
  20.             table.setColumnSelectionAllowed(box.isSelected());
  21.         }
  22.     });
  23.     innerPanel.add(modeBox);
  24.     modeBox = new JCheckBox(“Cell”);
  25.     modeBox.addItemListener(new ItemListener() {
  26.         public void itemStateChanged(ItemEvent event) {
  27.             JCheckBox box = (JCheckBox)(event.getSource());
  28.             table.setCellSelectionEnabled(box.isSelected());
  29.         }
  30.     });
  31.     innerPanel.add(modeBox);
  32.     BevelBorder bb = new BevelBorder(BevelBorder.RAISED);
  33.     TitledBorder tb = new TitledBorder(bb, “Table Selection Types”);
  34.     innerPanel.setBorder(tb);
  35.     outerPanel.add(innerPanel);
  36.     innerPanel = new JPanel();
  37.     innerPanel.setLayout(new FlowLayout());
  38.     JComboBox listModes = new JComboBox();
  39.     listModes.addItem(“Single Selection”);
  40.     listModes.addItem(“Single Interval Selection”);
  41.     listModes.addItem(“Multiple Interval Selections”);
  42.     listModes.setSelectedIndex(2);
  43.     listModes.addItemListener(new ItemListener() {
  44.         public void itemStateChanged(ItemEvent event) {
  45.             JComboBox box = (JComboBox)(event.getSource());
  46.             int index = box.getSelectedIndex();
  47.             switch(index){
  48.                 case 0:
  49.                     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  50.                     break;
  51.                 case 1:
  52.                     table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
  53.                     break;
  54.                 case 2:
  55.                     table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  56.                     break;
  57.             }
  58.         }
  59.     });
  60.     innerPanel.add(listModes);
  61.     bb = new BevelBorder(BevelBorder.RAISED);
  62.     tb = new TitledBorder(bb, “List Selection Modes”);
  63.     innerPanel.setBorder(tb);
  64.     outerPanel.add(innerPanel);
  65.     pane.add(outerPanel, BorderLayout.SOUTH);
  66. }
  67. public static void main(String [ args){
  68.     […]
  69. }
 

Bây giờ chạy lại chương trình và chúng ta có thể từ từ kiểm tra các chế độ chọn và tổ hợp của chúng có ảnh hưởng như thế nào đến việc chọn dữ liệu trong bảng.

Thiết lập việc chọn bằng dòng lệnh

Ngoài các sự kiện do người sử dụng có thể sinh ra để thay đổi việc chọn các ô trong một bảng, JTable cũng cung cấp cho chúng ta một số các phương thức để chúng ta có thể lấy thông tin và sinh ra các sự kiện bằng dòng lệnh. Các phương thức sẽ được liệt kê trong bảng dưới đây:

PHƯƠNG THỨC THỰC HIỆN
getSelectedRowCount() Trả về số hàng đang được chọn trong bảng
getSelectedRows() Trả về một mảng các số nguyên, mỗi một số nguyên chính là chỉ số của một hàng đang được chọn trong bảng.
getSelectedRow() Trả về một số nguyên, số nguyên này là chỉ số nhỏ nhất của một hàng trong tập hợp các hàng đang được chọn của bảng.
setRowSelectionInterval(int index0, int index1) Chọn một tập các hàng có chỉ số từ index0 cho đến index1. Các hàng khác có chỉ số không thuộc vào khoảng này sẽ không được chọn kể cả khi chúng đã được chọn trước đó.
addRowSelectionInterval(int index0,int index1) Chọn một tập các hàng có chỉ số từ index0 cho đến index1.
getSelectedColumnCount() Trả về số cột đang được chọn trong một bảng
getSelectedColumns() Trả về một mảng các số nguyên, mỗi số nguyên là một chỉ số của một cột đang được chọn trong bảng
getSelectedColumn Trả về một số nguyên là chỉ số nhỏ nhất của một cột trong số các cột đang được chọn của bảng.
setColumnSelectionInterval(int index0, int index1) Chọn các cột có chỉ số nằm trong khoảng từ index0 đến index1. Các cột khác có chỉ số nằm ngoài khoảng này sẽ không được chọn bất kể trước đó chúng đã được chọn hay chưa.
addColumnSelectionInterval(int index0, int index1) Chọn các cột có chỉ số nằm trong khoảng từ index0 đến index1

Tất cả các phương thức này được định nghĩa trong JTable. Khi một phương thức được gọi nó sẽ chuyển yêu cầu đến một ListSelectionModel để xử lý và lấy thông tin ở đó. Một cách cụ thể, các phương thức có liên quan đến việc chọn theo hàng sẽ chuyển yêu cầu về một model được quản lý bởi JTable, trong khi đó các phương thức liên quan đến việc chọn theo cột sẽ chuyển yêu cầu về một model được quản lý bởi một cài đặt của TableColumnModel trong bảng.

Như vậy kết thúc phần này, chúng ta đã nắm được các chế độ chọn khi thao tác với hàng và cột. Trong phần 6 chúng ta sẽ tìm hiểu về các thao tác với tiêu đề của bảng.

One Response to “Jtable_Swing part 5”

  1. Swing in Java « Thái Hoàng Hải Says:

    […] 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 Part 9 Share this:TwitterFacebookLike this:LikeBe the first to like this […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: