30/09/2018, 18:58

Cách nhận biết table nào được chọn trong 2 table trong Java Swing

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 ạ

Nguyễn Hữu Quyền viết 21:12 ngày 30/09/2018

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.

viết 21:01 ngày 30/09/2018

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ổ đó

Nguyễn Hữu Quyền viết 21:02 ngày 30/09/2018
// 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 đó

viết 21:14 ngày 30/09/2018

Dạ,Em làm được rồi anh ạ,Em cảm ơn anh nhiều

Bài liên quan
0