简体   繁体   中英

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

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();
}

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

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM