将不可编辑的 JTable 行动态设置为可编辑

Dynamically set non-editable JTable row as editable

我扩展了 AbstractTableModel class 使我的 JTable 不可编辑,期望第一行。顺便说一句,我已经重写了 isCellEditable(int row, int col) methode.By 放置一个整数变量,它保持 nextRow 激活,我得到第一行尊重我的 creterias.So,问题是当用户填充前一行零列中的单元格时,使下一行处于活动状态(数据已更改且必须具有值)。到目前为止,这是我的代码。

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



}

基本上,如果当前列不是 0,您当前的方法将 return false,否则它将 return true

也许像...

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

会做得更好...

要更新 nextActiveRow 值,您需要验证当前行的有效性并在适当的时候更新它的变量,例如...

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

}

这是对我有用的解决方案,一个在第一列填满时逐行激活的 JTable。

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

}