Dynamically set non-editable JTable row as editable

十年热恋 提交于 2019-12-11 20:20:03

问题


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++;
     }



}

回答1:


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!
    }

}



回答2:


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++;
    }

}


来源:https://stackoverflow.com/questions/27758904/dynamically-set-non-editable-jtable-row-as-editable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!