Em chào các anh chị,Mấy anh chị cho em hỏi là em có 2 table là A và B trong 1 panel…Làm thế nào để mình biết được người dùng click vào bảng A hay bảng B ạ…Anh chị nào biết chỉ em với.em cảm ơn nhiều ạ
Cách nhận biết table nào được chọn trong 2 table trong Java Swing
Em thêm sự kiện cho hai bảng là biết người ta click vào bảng nào thôi, ví dụ em thêm sự kiện actionListener và bảng A và một cái khác vào bảng B chẳng hạn. Thì khi người dùng nhấn vào A thì nó làm sự kiện actionListener của bảng A , và ngược lại.
Anh ơi,Em thêm sự kiện actionListener nhưng bảng thì không add được cái actionListener anh à,Button mới add được…Em bị kẹt chổ đó
// Trường Hợp 1 : Dùng sự kiện kích chuột
table.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = table.rowAtPoint(evt.getPoint());
int col = table.columnAtPoint(evt.getPoint());
// Em lam gi do tiep theo o day
}
});
// Trường Hợp 2 : Em chọn từng ô của bản, ví dụ như khi em nhấn phím Ctrl chẳng hạn
// Em phải cho phép chọn từng ô bằng cách sau
table.setCellSelectionEnabled(true);
// Thiết lập cơ chế chọn cho Table , ListSelectionModel.SINGLE_SELECTION là chỉ chọn 1 ô duy nhất
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// Cuối cùng em thêm lắng nghe sự kiện cho ô trong bảng như sau
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
String selectedData = null;
int[] selectedRow = table.getSelectedRows();
int[] selectedColumns = table.getSelectedColumns();
for (int i = 0; i < selectedRow.length; i++) {
for (int j = 0; j < selectedColumns.length; j++) {
selectedData = (String) table.getValueAt(selectedRow[i], selectedColumns[j]);
}
}
System.out.println("Selected: " + selectedData);
}
});
// Trường Hợp 3 : Em muốn chọn theo hàng
//1- Cũng như trên em phải thiết lập cơ chế chọn
table.setRowSelectionAllowed(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
// Em để ý valueChanged là khi mà em đang chọn 'A' em chọn sang 'B' là thay đổi đó
@Override
public void valueChanged(ListSelectionEvent event) {
if (table.getSelectedRow() > -1) {
// In giá trị hàng đó ra
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
selectedRow = lsm.getMinSelectionIndex();
// Lấy số lượng cột của bảng
int numCols = table.getColumnCount();
// lấy dữ liệu của dòng
model = (DefaultTableModel) table.getModel();
System.out.print(" \n row " + selectedRow + ":");
// In dữ liệu ra theo cột
for (int j = 0; j < numCols; j++)
{
System.out.print(" " + model.getValueAt(selectedRow, j));
}
}
}
});
//Trường Hợp 4 : Em muốn lắng nghe các sự kiện khi dữ liệu của bảng bị thay đổi
table.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if(e.getType() == e.UPDATE){
// In dữ liệu mới ra
System.out.println(e.getColumn());
System.out.println(e.getFirstRow());
System.out.println(e.getLastRow());
}
}
});
// Trường Hợp 5 : Em muốn vẽ thêm màu cho dòng , hay thêm mấy cái Button chẳng hạn thì làm như sau
public class ColorRenderer extends JLabel
implements TableCellRenderer {
//TableCellRenderer tức là kết xuất đồ họa cho ô (Cell)
public ColorRenderer(boolean isBordered) {
// Tức là em có muốn cho hiển thị Border hay không.
this.isBordered = isBordered;
// Cần cho thiết lập này để màu mới hiển thị lên
setOpaque(true);
}
public Component getTableCellRendererComponent(
JTable table, Object color,
boolean isSelected, boolean hasFocus,
int row, int column) {
Color newColor = (Color)color;
setBackground(newColor);
if (isBordered) {
if (isSelected) {
// Nếu được chọn thì đổi sang màu viền mới
setBorder(selectedBorder);
} else {
// Ngược lại thì trả về màu viền ban đầu
setBorder(unselectedBorder);
}
}
setToolTipText("Hướng dẫn gì đó ở đây chẳng hạn");
return this;
}
}
// Sau đó em thêm ColorRenderer trên vào Bảng như sau
table.setDefaultRenderer(Color.class, new ColorRenderer(true));
// Trong trường hợp em muốn xác định chính xác em vẽ màu cho ô nào thì làm như sau
TableCellRenderer colorRenderer = new ColorRenderer(true);
table = new JTable(...) {
public TableCellRenderer getCellRenderer(int row, int column) {
if ((row == 0) && (column == 0)) {
// giả sử anh muốn vẽ màu cho ô đầu tiên tọa độ [0,0] chẳng hạn
return colorRenderer;
}
// ngược lại thì em cho Renderer mặc định của lớp JTable
return super.getCellRenderer(row, column);
}
};
// Trường hợp 6 : Khởi tạo dữ liệu cho bảng
// Cái này là tạo ra Model cho bảng , sau khi tạo xong thì em thêm vào bảng (JTable)
JTable table = new JTable( new AbstractTableModel() {
public String getColumnName(int col) {
return columnNames[col].toString();
}
// Trả về số lượng hàng
public int getRowCount() {
return rowData.length;
}
//Trả về số lượng cột ( như ở trên anh có câu lệnh lấy số cột là từ đây)
public int getColumnCount() {
return columnNames.length;
}
// Đây chính là câu lệnh mà JTable lấy dữ liệu cho vị trí nào
public Object getValueAt(int row, int col) {
return rowData[row][col];
}
// Xác định xem ô đó có được cho phép chỉnh sửa không ( Anh sẽ đề cập bên dưới)
public boolean isCellEditable(int row, int col){
// em thêm các điều kiện tại đây
return true;
}
// trả về kiểu dữ liệu , lập trình cao hơn em sẽ quan tâm cái này nữa
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
// Đây là phương thức em cập nhật dữ liệu cho JTable
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = value;
// Bắn ra sự kiện cho bạn cập nhật lại dữ liệu mới , không
// có cái này thì bảng không thay đổi gì hết , có tầm 5 câu lệnh
// bắn sự kiện khác nhau.
fireTableCellUpdated(row, col);
}
});
//Trường hợp 7 : Em muốn thêm các button hay textField vào bảng chẳng hạn, em để ý
// là ở trên có Renderer là chỉ mới vẽ ra thôi , chưa dùng được , muốn vừa dùng được
// vừa thấy được thì phải có cả 2 , Renderer và Editer nôn na là vậy ( sau này có ví dụ em mới hiểu được)
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
// Ở đây anh Extends AbstractCellEditor nên nó làm sẳn một số phương thức quan trọng rồi
// mình chỉ cần chỉ ra cho nó mình muốn dùng Component gì , và lưu vào table giá trị gì
JComponent component = new JTextField();
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
int rowIndex, int vColIndex) {
// Ví dụ anh muốn trả về một TextField chẳng hạn
((JTextField) component).setText((String) value);
return component;
}
// JTable nó sẽ lấy giả trị khi em thao tác Trên Component bất kỳ tại đây
// ví dụ nếu Component là button thì trả về true hay false chẳng hạn.
public Object getCellEditorValue() {
return ((JTextField) component).getText();
}
}
// cuối cùng sau khi tạo riêng ra đối tượng như trên, vì tạo ra như vậy dễ quản lí mã nguồn hơn
// Em thêm vào bảng như sau
// ở ví dụ này anh thêm cho cột thứ 6 chỉ số là 5.
TableColumn col = table.getColumnModel().getColumn(5);
// em new mới đối tượng rồi set vào
col.setCellEditor(new MyTableCellEditor());
// Trường hợp 8 : Anh đã nói ở trên thông thường thì Renderer nó hay đi kèm với Editer thì
// Một cách xử lí code tốt hơn là cho hai đứa nó vào chung luôn , như bên dưới , anh hay làm.
private class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
// Em thấy anh implements luôn cả 2 cái Interface.
private static final long serialVersionUID = 1L;
private JFormattedTextField renderer;
private JFormattedTextField editor;
private NumberFormat format = DecimalFormat.getInstance();
public MyCellEditor() {
format.setMinimumFractionDigits(2);
format.setMaximumFractionDigits(4);
format.setRoundingMode(RoundingMode.HALF_UP);
renderer = new JFormattedTextField(format);
renderer.setBorder(null);
editor = new JFormattedTextField(format);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
renderer.setValue(value);
return renderer;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
editor.setValue(value);
return editor;
}
// Khi nào em cho Stop Editing tức là dừng chỉnh sửa
// Thì dữ liệu nó sẽ được đẩy vào table qua phương thức getValueAt(...)
// mà anh đã đề cập ở tren
@Override
public boolean stopCellEditing() {
try {
editor.commitEdit();
} catch (ParseException e) {
return false;
}
return super.stopCellEditing();
}
@Override
public Object getCellEditorValue() {
return editor.getValue();
}
}
// Và còn rất nhiều tính năng khác nữa , cơ mà anh đi ăn cơm đã , anh viết ra cho em tham khảo đầy đủ
// Có gì thắc mắc em thử tra Google hoặc hỏi lại anh nhé.
Chúc em thành công nhé ^^~ , Anh đã giới thiệu sơ qua cho em các tính năng hay gặp của JTable rồi đó
Dạ,Em làm được rồi anh ạ,Em cảm ơn anh nhiều
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?