MammouthQc
MammouthQc

Reputation: 7

Can't update cells from JTable

I've been trying to find a way to update my cells by direct input. From my reshearch, everyone seems to say that you have to use

myJTable.fireTableCellUpdated()

Althought, it keeps asking me to cast myJTable --> It can't be casted to an AbstractTableModel which is what, from what I understood, is needed.

Here is my current code for the Table if that can helps :

    myJTable= new JTable();

    myJTable.setModel(new DefaultTableModel(
        new Object[][] {
            {null, null, null},
        },
        new String[] {
            "Thing#1", "Thing#2", "Thing#3"
        }
    ));

    myJTable.getModel().addTableModelListener(new TableModelListener() { 
         public void tableChanged(TableModelEvent e) { 
             myJTable.fireTableCellUpdated(e.getFirstRow(), e.getColumn());
             myJTable.repaint(tblCG.getCellRect(e.getFirstRow(), e.getColumn(), false));
             myJTable.putClientProperty("terminatedEditOnFocusLost", true);
         } 
         });

How is it possible for me to save the datas from the cell that has been updated by direct input from the user? Thanks !

Upvotes: 0

Views: 353

Answers (2)

matthiasboesinger
matthiasboesinger

Reputation: 458

Here is my proposal (hope I understand the problem right):

  1. I would declare the data fields which are passed to the DefaultListModel as class attributes. Then you can access the objects of your table via these attributes.

  2. I would override the DefaultTableModel#setValueAt(Object, int, int) and DefaultTableModel#getValueAt(int, int) in the implicit constructor.

So try the following solution:

//declared as class attributes
Object[][] data = {{null, null, null},};
String[] columns = {"Thing#1", "Thing#2", "Thing#3"};

/*...*/

table.setModel(new DefaultTableModel(data, columns) {
    @Override
    public Object getValueAt(int row, int col) { return data[row][col]; }
    @Override
    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }
}); 

hope this can help ...

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347184

Depending on what you are trying to do, you can use...

For example...

enter image description here

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    private JTable myJTable;

    private String values[] = {"Orange", "Green", "Blue", "Pink", "Yellow"};
    private int count;

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                myJTable = new JTable();

                myJTable.setModel(new DefaultTableModel(
                                new Object[][]{{"Banana", "Yellow"}},
                                new Object[]{"Fruit", "Color"}
                ));

                JButton change = new JButton("Change");
                change.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        count++;
                        String value = values[Math.abs(count % values.length)];
                        myJTable.setValueAt(value, 0, 1);
                    }

                });
                JButton add = new JButton("add");
                add.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        DefaultTableModel model = (DefaultTableModel) myJTable.getModel();
                        model.addRow(new Object[]{"Apple " + model.getRowCount(), "Green"});
                    }

                });
                JButton delete = new JButton("delete");
                delete.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int rowIndex = myJTable.getSelectedRow();
                        rowIndex = myJTable.convertRowIndexToModel(rowIndex);
                        if (rowIndex > 0) {
                            DefaultTableModel model = (DefaultTableModel) myJTable.getModel();
                            model.removeRow(rowIndex);
                        }
                    }

                });

                JPanel actions = new JPanel();
                actions.add(change);
                actions.add(add);
                actions.add(delete);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(myJTable));
                frame.add(actions, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

You should only need to call one of the helper fireXxx event methods if you have customised the class yourself in some way and should ONLY be called from within the classes context, they should not be triggered externally, it's the responsibility of the implementing class to do this

So, with no additional code...

Editing

Cell editing is built in by default...

See...

for more details...

Upvotes: 1

Related Questions