En Netbeans, he utilizado el GUI Builder para insertar un JTable en mi aplicación.

Sólo tengo una clase (CustomerDB) hasta el momento que es:

package CustomerDB;
import [...];
public class CustomerDB extends javax.swing.JFrame {
CellEditorListener ChangeNotification = new CellEditorListener() {
public void editingCanceled(ChangeEvent e) {
System.out.println("The user canceled editing.");
}
public void editingStopped(ChangeEvent e) {
System.out.println("The user stopped editing successfully.");
}
};
public CustomerDB() {
customerTable = new javax.swing.JTable();
customerTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null}
},
new String [] {
"ID", "Name", "Address", "Phone"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
customerTable.getDefaultEditor(String.class).addCellEditorListener(ChangeNotification);
} 
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new CustomerDB().setVisible(true);
}
});
}
//Variables declaration - do not modify
[...]
private javax.swing.JTable customerTable;
[...]
//End of variables declaration
}

Cada vez que un usuario cambia los datos en la tabla, quiero obtener el valor antiguo (opcional) y el nuevo valor de la celda.

Con el fin de obtener estos datos, me trató de implementar un detector de eventos:

    CellEditorListener ChangeNotification = new CellEditorListener() {
public void editingCanceled(ChangeEvent e) {
System.out.println("The user canceled editing.");
}
public void editingStopped(ChangeEvent e) {
System.out.println("The user stopped editing successfully.");
}
};

, A continuación, asigne esta CellEditorListener a la mesa (su editor de celdas):

    customerTable.getDefaultEditor(String.class).addCellEditorListener(ChangeNotification);

Esto funciona hasta ahora. Pero aún no me permiten detectar el antiguo y el nuevo valor de esta celda. ¿Qué más tengo que hacer?

Muchas gracias de antemano!

  • lo de la línea de tiros de la NPE?
  • La línea que he mencionado en este contexto: la tabla customer.getCellEditor().addCellEditorListener(ChangeNotification); lo Siento, probablemente, esto no fue lo suficientemente clara.
  • He encontrado el error 🙂 El método getCellEditor() es el equivocado. Se le da el editor de celdas sólo si el usuario está editando una celda en el momento. De lo contrario, el resultado es NULL, que es la causa de esta excepción. Así que tengo que usar getDefaultEditor(String.class) aquí. Pero la cuestión no se resuelve completamente, pero aún así … 🙂
  • Excelente! He estado jugando con este mismo y no veo que. Gracias! Lo que todavía está pendiente en la pregunta?
  • y creo que CellEditorListener podría devuelve algo dentro de TableCellEditor
  • La parte que falta, es todavía el valor antiguo 😉
  • no necesariamente. Por favor vea mi respuesta.

InformationsquelleAutor caw | 2011-07-31

3 Comentarios

  1. 19

    Pero aún no me permiten detectar el antiguo y el nuevo valor de esta celda. ¿Qué más tengo que hacer?

    Es más fácil utilizar un TableModelListener para escuchar los cambios, pero todavía tiene el problema de no poder acceder a el valor antiguo.

    Retirar el La Celda De La Tabla De Escucha para una solución que le da acceso a la «vieja valor» así como el «nuevo valor».

    • Gracias, funciona bien! Pero solo quiero cambios por el usuario. Pero con un TableModelListener yo también te cambia por el equipo durante la inicialización. Así que un CellEditorListener sería mejor, ¿verdad?
    • Has leído el enlace? Me dio una solución para acessing el viejo «valor». Yo estaba sugiriendo, en general, un TableModelListener es más fácil de usar (en comparación con un CellEditorListener) porque es uno de escucha para todos los tipos de datos (Cadena, Fecha, Integer, etc.). Usted acaba de añadir el detector DESPUÉS de los datos se ha añadido a la modelo.
    • Camickr el sitio web de la guarda el día de nuevo 🙂
  2. 12

    o TableModelLister con ListSelectionListener, puño devuelve si TableCell cambiado, segundo de la llamada seleccionada, a continuación, sólo tienes que comparar Fila & Índice de Columna de TableModelLister con ListSelectionListener

    import java.awt.*;
    import java.util.Random;
    import java.util.Vector;
    import javax.swing.*;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableCellRenderer;
    public class Forum implements ListSelectionListener {
    private JFrame frame = new JFrame("Frame");
    private JPanel fatherCenter = new JPanel();
    private JScrollPane tableScroll = new JScrollPane();
    private myTableModel tableModel;
    private JTable dialogTable;
    private ListSelectionModel lsDialog;
    private void addComponentsToPane(Container pane) {
    tableModel = new myTableModel();
    dialogTable = new JTable(tableModel) {
    private static final long serialVersionUID = 1L;
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);
    JComponent jc = (JComponent) comp;//for Custom JComponent
    if (!isRowSelected(row)) {
    int modelRow = convertRowIndexToModel(row);
    boolean type = (Boolean) getModel().getValueAt(modelRow, 2);
    boolean type1 = (Boolean) getModel().getValueAt(modelRow, 3);
    boolean type2 = (Boolean) getModel().isCellEditable(row, column);
    comp.setForeground(Color.black);
    if ((type) && (!type1)) {
    comp.setBackground(Color.yellow);
    } else if ((!type) && (type1)) {
    comp.setBackground(Color.orange);
    } else if ((!type) || (!type1)) {
    comp.setBackground(Color.red);
    //} else if ((!type2)) {
    //comp.setForeground(Color.red);
    //comp.setBackground(Color.magenta);
    } else {
    comp.setBackground(row % 2 == 0 ? getBackground() : getBackground().darker());
    }
    dialogTable.convertRowIndexToView(0);
    } else {
    comp.setForeground(Color.blue);
    comp.setBackground(Color.lightGray);
    }
    if (!isCellEditable(row, column)) {
    comp.setForeground(Color.red);
    comp.setBackground(Color.magenta);
    }
    return comp;
    }
    };
    tableScroll = new JScrollPane(dialogTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    tableScroll.setBorder(null);
    dialogTable.getTableHeader().setReorderingAllowed(false);
    dialogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    lsDialog = dialogTable.getSelectionModel();
    dialogTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    dialogTable.setRowHeight(20);
    dialogTable.setRowMargin(2);
    ListSelectionModel rowSelMod = dialogTable.getSelectionModel();
    //ListSelectionModel colSelMod = dialogTable.getColumnModel().getSelectionModel();
    rowSelMod.addListSelectionListener(this);
    //colSelMod.addListSelectionListener(this);
    fatherCenter = new JPanel();
    fatherCenter.setLayout(new BorderLayout(10, 10));
    fatherCenter.add(tableScroll, BorderLayout.CENTER);
    pane.add(fatherCenter);
    }
    private void addData() {
    Runnable doRun1 = new Runnable() {
    @Override
    public void run() {
    tableModel.resetTable();
    Vector<String> tbl = new Vector<String>();
    Vector<Object> tbl1 = new Vector<Object>();
    Random rnd = new Random();
    tbl.add("Integer");
    tbl.add("Double");
    tbl.add("Boolean");
    tbl.add("Boolean");
    tbl.add("String");
    tableModel.setColumnNames(tbl);
    for (int row = 0; row < 30; row++) {
    tbl1 = null;
    tbl1 = new Vector<Object>();
    tbl1.addElement(row + 1);
    tbl1.addElement(rnd.nextInt(25) + 3.14);
    tbl1.addElement((row % 3 == 0) ? false : true);
    tbl1.addElement((row % 5 == 0) ? false : true);
    if (row % 7 == 0) {
    tbl1.add(("Canc"));
    } else if (row % 6 == 0) {
    tbl1.add(("Del"));
    } else {
    tbl1.add(("New"));
    }
    tableModel.addRow(tbl1);
    }
    addTableListener();
    }
    };
    SwingUtilities.invokeLater(doRun1);
    }
    private void addTableListener() {
    tableModel.addTableModelListener(new TableModelListener() {
    @Override
    public void tableChanged(TableModelEvent tme) {
    if (tme.getType() == TableModelEvent.UPDATE) {
    System.out.println("");
    System.out.println("Cell " + tme.getFirstRow() + ", "
    + tme.getColumn() + " changed. The new value: "
    + tableModel.getValueAt(tme.getFirstRow(),
    tme.getColumn()));
    }
    }
    });
    }
    public void valueChanged(ListSelectionEvent le) {
    int row = dialogTable.getSelectedRow();
    int col = dialogTable.getSelectedColumn();
    String str = "Selected Row(s): ";
    int[] rows = dialogTable.getSelectedRows();
    for (int i = 0; i < rows.length; i++) {
    str += rows[i] + " ";
    }
    str += "Selected Column(s): ";
    int[] cols = dialogTable.getSelectedColumns();
    for (int i = 0; i < cols.length; i++) {
    str += cols[i] + " ";
    }
    str += "Selected Cell: " + dialogTable.getSelectedRow() + ", " + dialogTable.getSelectedColumn();
    System.out.println(str);
    Object value = dialogTable.getValueAt(row, col);
    System.out.println(String.valueOf(value));
    }
    private void createAndShowGUI() {
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout(10, 10));
    addComponentsToPane(frame.getContentPane());
    addData();
    frame.setLocation(150, 150);
    frame.setPreferredSize(new Dimension(400, 647));
    frame.pack();
    frame.setVisible(true);
    }
    public static void main(String[] args) {
    Forum osFrame = new Forum();
    }
    public Forum() {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
    createAndShowGUI();
    }
    });
    }
    private class myTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 1L;
    private Vector<Vector<Object>> data;
    private Vector<String> colNames;
    private boolean[] _columnsVisible = {true, true, true, true, true};
    myTableModel() {
    this.colNames = new Vector<String>();
    this.data = new Vector<Vector<Object>>();
    }
    myTableModel(Vector<String> colnames) {
    this.colNames = colnames;
    this.data = new Vector<Vector<Object>>();
    }
    public void resetTable() {
    this.colNames.removeAllElements();
    this.data.removeAllElements();
    }
    public void setColumnNames(Vector<String> colNames) {
    this.colNames = colNames;
    this.fireTableStructureChanged();
    }
    public void addRow(Vector<Object> data) {
    this.data.add(data);
    this.fireTableDataChanged();
    this.fireTableStructureChanged();
    }
    public void removeRowAt(int row) {
    this.data.removeElementAt(row);
    this.fireTableDataChanged();
    }
    @Override
    public int getColumnCount() {
    return this.colNames.size();
    }
    @Override
    public Class<?> getColumnClass(int colNum) {
    switch (colNum) {
    case 0:
    return Integer.class;
    case 1:
    return Double.class;
    case 2:
    return Boolean.class;
    case 3:
    return Boolean.class;
    default:
    return String.class;
    }
    }
    @Override
    public boolean isCellEditable(int row, int colNum) {
    switch (colNum) {
    case 2:
    return false;
    default:
    return true;
    }
    }
    @Override
    public String getColumnName(int colNum) {
    return this.colNames.get(colNum);
    }
    @Override
    public int getRowCount() {
    return this.data.size();
    }
    @Override
    public Object getValueAt(int row, int col) {
    Vector<Object> value = this.data.get(row);
    return value.get(col);
    }
    @Override
    public void setValueAt(Object newVal, int row, int col) {
    Vector<Object> aRow = data.elementAt(row);
    aRow.remove(col);
    aRow.insertElementAt(newVal, col);
    fireTableCellUpdated(row, col);
    }
    public void setColumnVisible(int index, boolean visible) {
    this._columnsVisible[index] = visible;
    this.fireTableStructureChanged();
    }
    }
    }
  3. 5

    mKorbel es algo. Lo que si puedes crear tu propio editor de celdas que se extiende DefaultCellEditor:

      customerTable.setDefaultEditor(String.class, new DefaultCellEditor(new JTextField()){
    @Override
    public Component getTableCellEditorComponent(JTable table,
    Object value, boolean isSelected, int row, int column) {
    //code on line below is redundant but would be needed if need to see
    //other property of the value object than toString()
    String valueStr = (value == null) ? "null" : value.toString();
    System.out.printf("[%d, %d]: %s%n", row, column, valueStr);
    return super.getTableCellEditorComponent(table, value, isSelected, row, column);
    }
    @Override
    public Object getCellEditorValue() {
    System.out.printf("cell editor value: %s%n", super.getCellEditorValue());
    return super.getCellEditorValue();
    }
    });

Dejar respuesta

Please enter your comment!
Please enter your name here