I m building a Java Swing application with Java 8. So I need to create a JTable with a custom TableModel that contains a JDateChooser or similar object to set a LocalDate in one column. This is my custom TableCellRendered.
@SuppressWarnings("serial")
public class JDateChooserRenderer extends JDateChooser implements TableCellRenderer {
public JDateChooserRenderer(JDateChooser dateChooser) {
if (dateChooser != null) {
this.setDate(dateChooser.getDate());
}
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Date) {
this.setDate((Date) value);
} else if (value instanceof String) {
if(!value.toString().isEmpty()){
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
try {
Date myDate = formatter.parse(value.toString());
this.setDate(myDate);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return this;
}
}
This is my custom TableCellEditor:
@SuppressWarnings("serial")
public class JDateChooserCellEditor extends AbstractCellEditor implements TableCellEditor {
private JDateChooser dateChooser = new JDateChooser();
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
Date date = null;
if (value instanceof Date) {
date = (Date) value;
}
dateChooser.setDateFormatString("dd-MM-yyyy");
dateChooser.setDate(date);
return dateChooser;
}
public Object getCellEditorValue() {
dateChooser.setDateFormatString("dd-MM-yyyy");
return dateChooser.getDate();
}
}
This is the code to set JDateChooserRenderer in a column of my JTable:
JDateChooser dateChooser = new JDateChooser();
tableScadenza.getColumnModel().getColumn(1).setCellRenderer(new JDateChooserRenderer(dateChooser));
tableScadenza.getColumnModel().getColumn(1).setCellEditor(new JDateChooserCellEditor());
When I start my java swing application this is that I can see:
This is my custom JTableModel:
public class MyTableModelScadenza extends defaultTableModel{
/**
*
*/
private static final long serialVersionUID = -6384221858449579588L;
static String[] ColName = {"Qtà", "Data Sc.", "Lotto"};
public List<ArticoliScadenza> listaArticoli;
final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-mm-yyyy");
public MyTableModelScadenza(int n) {
super(ColName, n);
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
public String getColumnName(int col) {
return ColName[col];
}
public int getColumnCount() {
return ColName.length;
}
public Class<Float> getColumnClass(Float columnIndex) {
return Float.class; // Le due colonne sono numeri interi
}
public void stampaTabella(){
int i=0;
for(Iterator<ArticoliScadenza> it= listaArticoli.iterator(); it.hasNext();){
ArticoliScadenza mag = it.next();
super.setValueAt(mag.getQuantita(), i, 0);
//super.setValueAt(mag.getSconto(), i, 1);
i++;
}
}
public void pulisciValori(){
this.setListaArticoli(new ArrayList<ArticoliScadenza>());
this.setRowCount(0);
this.addRow(new Vector());
}
public void setValueAt(Object value, int row, int column){
if(listaArticoli==null){
listaArticoli = new ArrayList<ArticoliScadenza>();
}
if(column ==0){
if(value!=null){
try{
ArticoliScadenza art = null;
if(listaArticoli.size() > row){
art = listaArticoli.get(row);
}
if(art==null){
art = new ArticoliScadenza();
art.setQuantita(Integer.parseInt(value.toString()));
listaArticoli.add(row, art);
}else{
art.setQuantita(Integer.parseInt(value.toString()));
}
super.setValueAt(value, row, column);
}catch(Exception e){
super.setValueAt("0", row, column);
VisualMessage.getErrore();
log.logStackTrace(e);
}
}
}else if(column ==1){
if(value!=null){
try{
ArticoliScadenza art = null;
if(listaArticoli.size() > row){
art = listaArticoli.get(row);
}
if(art==null){
art = new ArticoliScadenza();
listaArticoli.add(row, art);
}else{
Date d = (Date)value;
LocalDate localDate= d.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
art.setData(localDate);
String string = localDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));
super.setValueAt(string, row, column);
}
//super.setValueAt(value, row, column);
}catch(Exception e){
super.setValueAt("0", row, column);
VisualMessage.getErrore();
log.logStackTrace(e);
}
}
}else if(column ==2){
if(value!=null){
try{
ArticoliScadenza art = null;
if(listaArticoli.size() > row){
art = listaArticoli.get(row);
}
if(art==null){
art = new ArticoliScadenza();
listaArticoli.add(row, art);
}else{
art.setLotto(value.toString());
}
super.setValueAt(value, row, column);
}catch(Exception e){
super.setValueAt("0", row, column);
VisualMessage.getErrore();
log.logStackTrace(e);
}
}
}
checkRow(row);
}
private void checkRow(int row){
ArticoliScadenza art = listaArticoli.get(row);
if(art.getQuantita()==null)
return;
if(art.getData()!=null){
//verifico quante righe ci sono in tabella.
int nArticoli = listaArticoli.size();
int nRighe = this.getRowCount();
if(nArticoli>=nRighe)
this.addRow(new Vector());
}
}
public List<ArticoliScadenza> getListaArticoli() {
return listaArticoli;
}
public void setListaArticoli(List<ArticoliScadenza> listaArticoli) {
this.listaArticoli = listaArticoli;
}
}
So when I try to insert the value of the first row this is that I see:
As you can see in the first row there is the correct value, after that with checkRow method, I add new Row, but in the second row, there is also the LocalDate selected in the previous row, if I try to change the date value of the second row, also the date value of the first row is changed.
What can I do to fix this?