JTable: Edit Colums

Dear sirs,
I am trying to achieve this:
- Having a JTable where the user can enter data. Only few columns will be editable.
- Controlling the input: Setting up a min value and a max value, as this works for spinner model.
- Which listener can I implement to track these change.

I made the columns editable available by overridding the isCellEditable method of the Table model, unfortunately  everytime I type something, the content is just cleared, after pressing Enter.

Any guidance, any tutorial, or any working example, on how this can be implemented, will be highly appreciated.

Regards
Omer-PitouAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Maidine FouadEngineerCommented:
Try this whitout overrriding the method

JTable table = new JTable();
...
table.setEnabled(True);

Open in new window

0
Omer-PitouAuthor Commented:
HI Fouad,
Sorry this doesn't work
0
Omer-PitouAuthor Commented:
This is my custom table model used to load my JTable, it works perfectly.
For some  interfaces, I have to offer a way to enter data into the JTable cell.
I tried several times without success.  The column is already editable, and I can type inside. Unfortunately when I press ENTER, the data entered disappears.
I don't know what I am doing wrong.

package com.finger.general.classes;

import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

public final class MyTableModel extends AbstractTableModel {
    
    private ResultSetMetaData modelMetaData;
    private ResultSet modelResultSet;
    private MyDataAccessObject oDAO;
    private PreparedStatement modelPrepStmt;
    private final boolean isPrepStmt;
    private boolean isModelEditable=false;
    
    private int editColumn;
    
    private String defaultStmt;
    private String modelQueryStmt;
        
    private final MyDictionary oDictionary = new MyDictionary();
        
    public MyTableModel (String pSQLStmt) {
        super();
        this.isPrepStmt = false;
        this.defaultStmt = pSQLStmt;
        this.modelQueryStmt = this.defaultStmt;
        populateData(getResultSet(this.isPrepStmt));
    } 
    
    public MyTableModel (PreparedStatement pPrepStmt) {
        super();
        this.isPrepStmt = true;
        this.modelPrepStmt = pPrepStmt;
        populateData(getResultSet(this.isPrepStmt));
    } 
    
    public MyTableModel (PreparedStatement pPrepStmt, boolean pEditable, int pEditColumn) {
        super();
        this.isModelEditable = pEditable;
        this.editColumn = pEditColumn;
        this.isPrepStmt = true;
        this.modelPrepStmt = pPrepStmt;
        populateData(getResultSet(this.isPrepStmt));
    } 
    
    private ResultSet getResultSet(boolean pIsPrepStmt) {
        if (oDAO == null) {
            oDAO = new MyDataAccessObject();
        }
        if (pIsPrepStmt) {
            try {
                return modelPrepStmt.executeQuery();
            } catch (SQLException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);    
            }
        } else {
            return oDAO.executeQuery(this.modelQueryStmt);  
        }  
        return null;
    }
    
    private void populateData(ResultSet pResultSet) {
        try {
            modelResultSet = pResultSet;
            modelMetaData = modelResultSet.getMetaData();
                                           
            this.fireTableDataChanged();
            
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }            
    }
        
    public void refreshData() {
        this.modelQueryStmt = this.defaultStmt;
        this.populateData(getResultSet(this.isPrepStmt));
    }
    
    public void exportData(boolean pIsPrepStmt) {
        String cFilePath = new MyFileIO().getSaveToFilePath("csv");
        if (! cFilePath.isEmpty()) {
            try {
                CSVWriter writer;
                modelResultSet = getResultSet(pIsPrepStmt);
                writer = new CSVWriter(new FileWriter(cFilePath, true));
                writer.writeAll(modelResultSet, true);
                writer.flush();
                writer.close();
                JOptionPane.showMessageDialog(null, oDictionary.getConfirmationExportMessage(), oDictionary.getConfirmationTitle(),
                        JOptionPane.INFORMATION_MESSAGE);

            } catch (IOException | SQLException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
            } 
        }       
    }
              
    public void disconnectFromDB() {
        try {
            if (modelResultSet != null) {
                modelResultSet.close();
            }
            if (modelPrepStmt != null) {
                modelPrepStmt.close();
            }
            if (oDAO != null) {
                oDAO.closeConnection();
            }
        } catch (SQLException sqlException) {
            JOptionPane.showMessageDialog(null, sqlException.getMessage(), oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }    
    }        

    //Native methods
    @Override
    public Class getColumnClass(int column) {
        try {
            String className = modelMetaData.getColumnClassName(column + 1);
            return Class.forName(className);
        } catch (SQLException | ClassNotFoundException exception) {
            JOptionPane.showMessageDialog(null, exception.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }
        return Object.class;
    }   
    
    @Override
    public int getColumnCount() {
        try {
            return modelMetaData.getColumnCount();
        } catch (SQLException sqlException) {
            JOptionPane.showMessageDialog(null, sqlException.getMessage(), oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }
        return 0;
    } 
    @Override
    public String getColumnName(int column) {
        try {
            return modelMetaData.getColumnName(column + 1);
        } catch (SQLException sqlException) {
            JOptionPane.showMessageDialog(null, sqlException.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }
        return "";
    }   
    @Override
    public int getRowCount() {
        try {
            modelResultSet.last();
            return modelResultSet.getRow();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);           
        }
        return 0;            
    }
    @Override
    public Object getValueAt(int row, int column) {
        try {
            modelResultSet.absolute(row + 1);
            return modelResultSet.getObject(column + 1);
        } catch (SQLException sqlException) {
            JOptionPane.showMessageDialog(null, sqlException.getMessage(),oDictionary.getErrorTitle(), JOptionPane.ERROR_MESSAGE);
        }
        return null; // ""
    }    
   
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if (this.isModelEditable) {
            if (columnIndex == this.editColumn) {
                return true;
            }
        }
        return super.isCellEditable(rowIndex, columnIndex);
    }
   
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        super.setValueAt(aValue, rowIndex, columnIndex);    
        super.fireTableCellUpdated(rowIndex, columnIndex);
        
    }
      
}

Open in new window


Thank you in advance for your help.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

zzynxSoftware engineerCommented:
First a remark (unrelated to your problem): I would use the same condition that you use in the method isCellEditable() also in the method setValueAt()

Question: when you run in debug mode, do you trigger/reach your setValueAt() method?

Could you post a small, runnable program that uses your table model to demonstrate your problem?

Some examples that can help you:
http://www.java2s.com/Tutorial/Java/0240__Swing/DemonstratestheeditablepropertyofSwingtables.htm
http://www.codejava.net/java-se/swing/editable-jtable-example
0
Omer-PitouAuthor Commented:
Thanks for the remark.
I didn't run it in debug mode.
What I did to find the problem is that I added System.out lines and realized aValue, rowIndex, columnIndex were showing the right values. Still don't understand why they disappear after ENTER is pressed.
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        System.out.println(aValue);
        System.out.println(rowIndex);
        System.out.println(columnIndex);      
    
        super.setValueAt(aValue, rowIndex, columnIndex);    
        super.fireTableCellUpdated(rowIndex, columnIndex);
        
    }

Open in new window


I can make a small program from the current one to demonstrate that.
Briefly this is the code that loads the table
//Liste Prix
        oPrixTableModel = prixmodel.getFilterTableModel(view.getMagasinID().getText(), view.getCategorieID().getText(),
                view.getArticleID().getText(), view.getActifprix().isSelected(), view.getSearchprix().getText());
        view.getMyTablePrix().setModel(oPrixTableModel);

Open in new window

It takes the table model from the custom table model previously posted
0
zzynxSoftware engineerCommented:
I can make a small program from the current one to demonstrate that.
That would be interesting. Then I can run it too and hunting down the mistake, if any.
0
Omer-PitouAuthor Commented:
Hi zzynx,
From this link you just gave me

How I can make this example use The ResultSet to create the table model, instead String[] for column names and Object[][] for rows.  Especially for setValueAt method. That where the problem  is
0
zzynxSoftware engineerCommented:
From this link you just gave me
Which one of the links?
0
zzynxSoftware engineerCommented:
Sorry I can't answer that one in detail.
But basically, you should have a Class (eg. MyData) representing one entry in your table.
That class should match one record out of your database table.
Your table model should be a List of instances of that class: List<MyData>

public final class MyTableModel extends AbstractTableModel {

     private List<MyData> data;

}

Open in new window

and then all methods should get their info out of that data variable.
eg.

public int getRowCount() {
   return data.size();
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Omer-PitouAuthor Commented:
I try this tomorrow and let you know.
0
Omer-PitouAuthor Commented:
I changed to List, and it works. THANK YOU.
I want an advice on the Listener to implement here in order to track the changes. Should I implement TableModelListener or KeyListener (on JTable itself)
0
zzynxSoftware engineerCommented:
You're welcome. Thanx 4 axxepting.
In order to track changes to your table data you should use TableModelListener
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.