0

while dragging column 3 (selected cell is edited) before column 2 after the operation is complete, value of col 3 is displayed in both new col 2 and former col 3 (should contain value of former col 2)

example, if the content of columns is a b c

Before dragging:
table: a b c
model: a b c

After dragging:
table: a c c
model: a c c

tracking invocation of [model]setValueAt(...) during the drag and drop, I realize the method is called with col 3 as argument, passing "c" as object, so the col 3 of model is re-setted to "c", ok, then it is called with col 2 as argument (which should not), passing "c" as object. My question is why and by what setValueAt is called with 2 as column, when 2 is the column in view, not in model. I do not invoque the method in my code.

Even when commenting putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); the setValueAt is still invocated.

Note : I am doing a few hacks with focus in my jtable, and use a personnal editor. the table :

public PersoTable(final PgTable pgt, PersoTableModel persotablemodel) {

    super(persotablemodel);

    /*
     * parcours des colonnes utiles (action et inforow comptent pas)
     */
    sorter = new TableRowSorter<>(this.getModel());
    this.setRowSorter(sorter);
    for (int i = 0; i < pgt.getNbCols(); i++) {
        sorter.setComparator(i, new PersoTriable());
    }
    DocumentListener dl = new DocumentListener() {
        /*
         * on créé ici car un seul suffit pour la tableFiltre. 
         * Dans l'Editot il serait instancié plusieurs fois
         */
        @Override
        public void insertUpdate(DocumentEvent e) {
            filtre(pgt);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            filtre(pgt);
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            filtre(pgt);
        }
    };
    ge = new PersoEditor(pgt, dl);
    gr = new PersoRender(pgt);
    setDefaultRenderer(String.class, gr);
    setDefaultEditor(String.class, ge);

    removeColumn(getColumnModel().getColumn(INFO_ROW_COL));

    setShowGrid(false);
    setIntercellSpacing(new Dimension(0, 0));

    setFillsViewportHeight(true);
    /**
     * pour mise en édit qd on vient sur la jtable par une tabulation
     */
    addFocusListener(new GfocusAdapter());
    getTableHeader().addMouseListener(PersoTableTriEcouteur.getInstance());

    /*
     * mouseMotion car besoin du move
     */
    addMouseMotionListener(PersoMouseAdapter.getInstance());
    addMouseListener(PersoMouseAdapter.getInstance());
    putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
}

the model

public class PersoTableModel extends AbstractTableModel {

boolean DEBUG = true;
private String[] entetes;
private List<ParDesc> listePardesc;

public PersoTableModel(List<ParDesc> data, PgTable pgtable) {

    // dans pgt on a déclaré x colonnes.
    // mais columnNames contient en plus :
    // - la 1ere colonne contenant les InfoRow.
    // - la colonne action
    entetes = new String[pgtable.getNbCols() + 2];// 2 premieres colonnes sans entetes
    entetes[0] = "InfoRow";
    entetes[1] = "";
    for (int i = 0; i < pgtable.getNbCols(); i++) {
        entetes[i + 2] = pgtable.getColName(i);
    }
    this.listePardesc = data;
}

public PersoTableModel(List<ParDesc> data, PgTable pgtable) {
    this(data, pgtable);
}

public void addParDesc(int row, ParDesc parDesc) {
    listePardesc.add(row, parDesc);
    fireTableRowsInserted(row, listePardesc.size() - 1);
}

public void addParDesc(ParDesc parDesc) {
    listePardesc.add(parDesc);
    fireTableRowsInserted(listePardesc.size() - 1, listePardesc.size() - 1);
}

@Override
public int getColumnCount() {
    return entetes.length;
}

@Override
public int getRowCount() {
    return listePardesc.size();
}

@Override
public String getColumnName(int col) {
    return entetes[col];
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    switch (columnIndex) {
        case 0:
            return listePardesc.get(rowIndex).getInfoRow();
        case 1:
            return listePardesc.get(rowIndex).getAction();
        case 2:
            return listePardesc.get(rowIndex).getRang();
        case 3:
            return listePardesc.get(rowIndex).getFld_key();
        case 4:
            return listePardesc.get(rowIndex).getLib();
        case 5:
            return listePardesc.get(rowIndex).getDebut();
        case 6:
            return listePardesc.get(rowIndex).getLg();
        case 7:
            return listePardesc.get(rowIndex).getDt_cre_maj();
        default:
            return null; //Ne devrait jamais arriver
    }
}

public InfoRow getInfoRow(int row) {
    return listePardesc.get(row).getInfoRow();
}

@Override
public Class getColumnClass(int columnIndex) {
    switch (columnIndex) {
        case 0:
            return InfoRow.class;
        default:
            return String.class;
    }
}

@Override
public boolean isCellEditable(int row, int col) {
    //Note that the data/cell address is constant,
    //no matter where the cell appears onscreen.
    if (col == 7) {
        return false;
    } else {
        return true;
    }
}

@Override
public void setValueAt(Object value, int row, int col) {
    if (value == null) {
        return;
    }
    ParDesc pardesc = listePardesc.get(row);
    if (DEBUG) {
        System.out.println("On sette " + row + "," + col
                + " à " + value
                + " (instance de "
                + value.getClass() + ")");
    }
    String newVal = "";
    if (value instanceof String) {
        newVal = ((String) value).trim();
    }
    switch (col) {
        case 0:
            pardesc.setInfoRow((InfoRow) value);
            break;
        case 1:
            pardesc.setAction(newVal);
            break;
        case 2:
            pardesc.setRang(newVal);
            break;
        case 3:
            pardesc.setFld_key(newVal);
            break;
        case 4:
            pardesc.setLib(newVal);
            break;
        case 5:
            pardesc.setDebut(newVal);
            break;
        case 6:
            pardesc.setLg(newVal);
            break;
        case 7:
            pardesc.setDt_cre_maj(newVal);
            break;
    }
     fireTableCellUpdated(row, col);
    if (DEBUG) {
        printDebugData();
    }
}

private void printDebugData() {
    int numRows = getRowCount();
    int numCols = getColumnCount();

    System.out.print("Après set,");
    for (int i = 0; i < numRows; i++) {
        System.out.print(" row " + i + " =");
        for (int j = 0; j < numCols; j++) {
            String toto;
            if (getValueAt(i, j) instanceof InfoRow) {
                toto = ((InfoRow) getValueAt(i, j)).toString();
            } else {
                toto = (String) getValueAt(i, j);
            }
            if (toto.trim().isEmpty()) {
                toto = "_";
            }
            toto+=" |";
            System.out.print(" " + j + " " + toto);
        }
        System.out.println();
    }
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
bill7511
  • 21
  • 7
  • For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). – Andrew Thompson Sep 25 '14 at 01:12
  • This is a common issue with JTables. When performing any action outside the text window, you should end text input on that cell, IIRC. – Compass Sep 25 '14 at 01:22
  • Sorry Andrew, my code is a bit messy, my fault. It is very complicated to create an MVCE. Compass, I will explore your option (stopping edit while dragging). – bill7511 Sep 25 '14 at 09:04
  • Ok Compass, I stopped editing on mouse pressed and I edit again on mouseReleased, thanks for advice. – bill7511 Sep 27 '14 at 14:51

0 Answers0