将不可编辑的 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++;
}
}
我扩展了 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++;
}
}