简体   繁体   中英

Dynamically set non-editable JTable row as editable

I have extended the AbstractTableModel class to make my JTable non-editable,expects the first row. By the way, i have overrided the isCellEditable(int row, int col) methode.By putting an integer variable, that hold the nextRow to activate, i got the first row respects my creterias.So, the problem is to make the next row active when the the cell in previous row column zero is filled by the user (data changed and must have a value).Her is my code so far.

package MODEL.tableModel;

import MODEL.Produit;
import MODEL.ProduitInBonDachat;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;


public class BonDachatTableModel extends AbstractTableModel implements TableModelListener {

    private String headerTitle[] = {"Designation", "Qté", "Prix Unitaire", "Sous Total"};
    private List<ProduitInBonDachat> data;
// variable that hold the next 
    private int nextActiveRow = 0;

    public BonDachatTableModel() {
        data = new ArrayList<ProduitInBonDachat>();
    }

    @Override
    public String getColumnName(int i) {
        return headerTitle[i];
    }

    @Override
    public int getRowCount() {
        return 10;
    }

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

    public void tableChanged(TableModelEvent event) {
        int col = event.getColumn();
        int fRow = event.getFirstRow();

        if ((col == 1) && (col == 2)) {
            setValueAt(getValueAt(fRow, col), fRow, col);
            fireTableCellUpdated(fRow, col);
        } 
    }

    public Object getValueAt(int row, int col) {
        try {
            data.get(row);
        } catch (IndexOutOfBoundsException e) {
            return null;
        }
        ProduitInBonDachat pInBonDachat = data.get(row);

        switch (col) {
            case 0:
                if (pInBonDachat.getDesignationProduit() == null) {
                    return null;
                }
                if(!pInBonDachat.getDesignationProduit().isEmpty()){
                     nextActiveRow++ ;
                fireTableCellUpdated(row, col);
                }

                return pInBonDachat.getDesignationProduit();
            case 1:
                if (pInBonDachat.getQte() == null) {
                    return null;
                }
                return pInBonDachat.getQte();
            case 2:
                if (pInBonDachat.getPrixDeVente() == null) {
                    return null;
                }
                return pInBonDachat.getPrixDeVente();
            case 3:
                if (pInBonDachat.getPrixDeVente() == null || pInBonDachat.getQte() == null) {
                    return null;
                }
                return pInBonDachat.getQte().multiply(pInBonDachat.getPrixDeVente());
            default:
                return null;

        }
    }



  public boolean isCellEditable(int row, int col) {
     if(col == 1 || col == 2 || row == nextActiveRow)
        return true; 
     else 
        return false ;

}

    @Override
    public void setValueAt(Object value, int row, int col) {
        ProduitInBonDachat tableEtry;
        try {
            tableEtry = data.get(row);
        } catch (IndexOutOfBoundsException e) {
            tableEtry = new ProduitInBonDachat();
            data.add(row, tableEtry);
        }

        switch (col) {
            case 0:
                tableEtry.setDesignationProduit((String) value);
                nextRowActive();
fireTableCellUpdated(int row, int col);
                break;
            case 1:
                tableEtry.setQte((BigDecimal) value);
                break;
            case 2:
                tableEtry.setPrixDeVente((BigDecimal) value);
                break;
            default:
                super.setValueAt(value, row, col);

        }

    }

    @Override
    public Class<?> getColumnClass(int col) {
        switch (col) {
            case 0:
                return String.class;
            case 1:
                return BigDecimal.class;
            case 2:
                return BigDecimal.class;
            case 3:
                return BigDecimal.class;
            default:
                return super.getColumnClass(col);
        }
    }

    public void nextRowActive(){
        nextActiveRow++;
     }



}

Basically, your current method will return false if the current column is not 0 , otherwise it will return true

Maybe something like...

public boolean isCellEditable(int row, int col) {
    boolean isEditable = false;
    System.out.println("update cell edittable");
    if(col != 0 && row == nextActiveRow){
        isEditable = true;
    }
    return isEditable;
}

Will do a better job...

To update the nextActiveRow value, you need to verify the validity of the current row and update it the variable when it's appropriate, for example...

public void setValueAt(Object value, int row, int col) {
    ProduitInBonDachat tableEtry;
    try {
        tableEtry = data.get(row);

        switch (col) {
            case 0:
                tableEtry.setDesignationProduit((String) value);
                break;
            case 1:
                tableEtry.setQte((BigDecimal) value);
                break;
            case 2:
                tableEtry.setPrixDeVente((BigDecimal) value);
                break;
        }
        fireTableCellUpdated(row, col);
        if (row == nextActiveRow && activeRowIsVaid()) {
            nextRowActive();
        }
    } catch (IndexOutOfBoundsException e) {
        // IMHO, this is not an appropriate action for the
        // setValueAt method, as the contract suggest that you are
        // editing an existing row, instead provide a method in your model
        // which is responsible for inserting/adding new rows
        //tableEtry = new ProduitInBonDachat();
        //data.add(row, tableEtry);
        // don't forget to fireRowInserted!
    }

}

Here is solution that work for me, a JTable that is activated row by row , when the first column is filled up.

package MODEL.tableModel;

import MODEL.Produit;
import MODEL.ProduitInBonDachat;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;


public class BonDachatTableModel extends AbstractTableModel implements TableModelListener {

    private String headerTitle[] = {"Designation", "Qté", "Prix Unitaire", "Sous Total"};
    private List<ProduitInBonDachat> data;
    private int nextActiveRow = 0;

    public BonDachatTableModel() {
        data = new ArrayList<ProduitInBonDachat>();
    }

    @Override
    public String getColumnName(int i) {
        return headerTitle[i];
    }

    @Override
    public int getRowCount() {
        return 10;
    }

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

    public void tableChanged(TableModelEvent event) {
        int col = event.getColumn();
        int fRow = event.getFirstRow();

        if ((col == 1) && (col == 2)) {
            setValueAt(getValueAt(fRow, col), fRow, col);
            fireTableCellUpdated(fRow, col);
        }
    }

    public Object getValueAt(int row, int col) {
        try {
            data.get(row);
        } catch (IndexOutOfBoundsException e) {
            return null;
        }
        ProduitInBonDachat pInBonDachat = data.get(row);

        switch (col) {
            case 0:
                if (pInBonDachat.getDesignationProduit() == null) {
                    return null;
                }

                return pInBonDachat.getDesignationProduit();
            case 1:
                if (pInBonDachat.getQte() == null) {
                    return null;
                }
                return pInBonDachat.getQte();
            case 2:
                if (pInBonDachat.getPrixDeVente() == null) {
                    return null;
                }
                return pInBonDachat.getPrixDeVente();
            case 3:
                if (pInBonDachat.getPrixDeVente() == null || pInBonDachat.getQte() == null) {
                    return null;
                }
                return pInBonDachat.getQte().multiply(pInBonDachat.getPrixDeVente());
            default:
                return null;

        }
    }

    public boolean isCellEditable(int row, int col) {
        if (col == 0 && row <= nextActiveRow) {
            return true;
        }
        if (col == 1 && row <= nextActiveRow) {
            return true;
        }
        if (col == 2 && row <= nextActiveRow) {
            return true;
        }
        return false;
    }

    @Override
    public void setValueAt(Object value, int row, int col) {
        ProduitInBonDachat tableEtry;
        try {
            tableEtry = data.get(row);
        } catch (IndexOutOfBoundsException e) {
            tableEtry = new ProduitInBonDachat();
            data.add(row, tableEtry);
        }

        switch (col) {
            case 0:
                String valueCast = (String) value;
                if (valueCast.isEmpty()) {
                    break;
                }
                nextActiveRow++;
                tableEtry.setDesignationProduit((String) value);

                break;
            case 1:
                tableEtry.setQte((BigDecimal) value);
                break;
            case 2:
                tableEtry.setPrixDeVente((BigDecimal) value);
                break;
            default:
                super.setValueAt(value, row, col);

        }
        fireTableCellUpdated(row, col);

    }

    @Override
    public Class<?> getColumnClass(int col) {
        switch (col) {
            case 0:
                return String.class;
            case 1:
                return BigDecimal.class;
            case 2:
                return BigDecimal.class;
            case 3:
                return BigDecimal.class;
            default:
                return super.getColumnClass(col);
        }
    }

    public void nextRowActive() {
        nextActiveRow++;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM