Eng.Fouad
Eng.Fouad

Reputation: 117685

Adding TableModelListener to AbstractTableModel

I've faced an issue in adding TableModelListener to AbstractTableModel. The program stops working and the JFrame doesn't response for any button-clicking or even closing the JFrame.

What I want is to make a JButton enabled iff the number of rows in myTable is equal or more than 2 rows.

Here is my code ...

My custom Table:

public class MyTable extends JPanel
{
    public Main main;
    public ArrayList<MyData> lstData;
    public JTable table;
    public MyTableModel model;
    // ...

    public MyTable(ArrayList<MyData> lstData, Main main)
    {
        this.lstData = lstData;
        this.main = main;
        model = new MyTableModel(lstData);
        table = new JTable(model);
        // ...
    }

    // ...

    public int getTableSize()
    {
        return model.getRowCount();
    }
    public TableModel getModel()
    {
        return model;
    }

    public class MyTableModel extends AbstractTableModel
    {  
        protected String[] columnNames = new String[ ] {"#","Name", "Phone Number"};
        protected ArrayList<MyData> lstData;
        protected Class[] types = new Class[]{String.class, String.class, String.class};

        public MyTableModel(ArrayList<MyData> lstData)
        {    this.lstData = lstData;    }

        public void SetData(ArrayList<MyData> lstData)
        {    this.lstData = lstData; fireTableDataChanged();    }

        @Override
        public String getColumnName(int columnIndex)
        {    return columnNames[columnIndex];   }

        @Override
        public Class getColumnClass(int columnIndex)
        {    return types[columnIndex];   }

        public Object getValueAt(int row, int column)
        {
            if (row < 0 || row > lstData.size()) return null;
            MyData obj = lstData.get(row);
            switch(column)
            {
                case 0: return obj.getID();
                case 1: return obj.getName();
                case 2: return obj.getPhoneNumber();
                default: return null;
            }
        }

        public int getRowCount() {  return lstData.size();   }
        public int getColumnCount() {  return columnNames.length;   }

    }
}

Main class:

public class Main extends JFrame implements TableModelListener
{
    public static ArrayList<myData> lstData;
    public static MyTable table;
    public static JButton myButton;
    public Main()
    {
        // ...
        table = new MyTable(lstData, this);
        table.getModel().addTableModelListener(this);
        myButton = new JButton();
        myButton.setEnabled(false);
        // ...
    }

    // ...

    public void tableChanged(TableModelEvent e)
    {
       int firstRow = e.getFirstRow();
       int lastRow = e.getLastRow();
       int mColIndex = e.getColumn();

       switch(e.getType())
       {
           case TableModelEvent.INSERT:
           if(table.getTableSize() >= 2) myButton.setEnabled(true);
           else myButton.setEnabled(false);
           break;

           case TableModelEvent.DELETE:
           if(table.getTableSize() >= 2) myButton.setEnabled(true);
           else myButton.setEnabled(false);
           break;
       }
    }
}

Could you help me to solve this issue? Thanks in advance.

EDIT:

The GUI stop responding only if I add or delete elements from the table.

EDIT2:

No errors or exceptions are thrown after I add elements to the table, it's just freezing the gui with no response

Upvotes: 0

Views: 9481

Answers (3)

Eng.Fouad
Eng.Fouad

Reputation: 117685

Thank you guys for your help, I solve this issue by modifying the tableChanged method:

public void tableChanged(TableModelEvent e)
{
   if(table.getTableSize() >= 2) myButton.setEnabled(true);
       else myButton.setEnabled(false);
}

Upvotes: 0

Perception
Perception

Reputation: 80598

In your MyTableModel class, remove the following line:

protected TableModel model = this;

And also remove the following methods:

public void setModel(TableModel model){
    this.model = model;
}

public TableModel getModel() {
    return model;
}

You are already implementing a custom table model, there is no need to create that self reference inside of it. When your class is getting instantiated the this variable is not fully initialized and I suspect that is what is causing problems for you. But in any case the code is definitely not needed. Also, in your MyTable class I would recommend changing the getModel() function to defer to your wrapped table variable. Like so:

public TableModel getModel() {
    return model.getModel();
}

Upvotes: 1

mKorbel
mKorbel

Reputation: 109823

basic tutorial about TableModelListener here or here or here

best would be camickr Table Cell Listener that implements deepest funcionalities for Listening in the TableCell

Upvotes: 1

Related Questions