Java 将TableModelListener添加到AbstractTableModel

Java 将TableModelListener添加到AbstractTableModel,java,swing,jtable,listener,Java,Swing,Jtable,Listener,在将TableModelListener添加到AbstractTableModel中时,我遇到了一个问题。程序停止工作,JFrame对任何按钮单击甚至关闭JFrame都没有响应 如果myTable中的行数等于或大于2行,我希望启用JButton 这是我的密码 我的自定义表格: public class MyTable extends JPanel { public Main main; public ArrayList<MyData> lstData; pub

在将
TableModelListener
添加到
AbstractTableModel
中时,我遇到了一个问题。程序停止工作,JFrame对任何按钮单击甚至关闭JFrame都没有响应

如果myTable中的行数等于或大于2行,我希望启用
JButton

这是我的密码

我的自定义表格:

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

    }
}
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;
       }
    }
}
公共类MyTable扩展了JPanel
{
公共主体;
公共阵列列表数据;
公共JTable表;
公共MyTable模型;
// ...
公共MyTable(ArrayList lstData,Main)
{
this.lstData=lstData;
this.main=main;
模型=新的MyTableModel(lstData);
表=新JTable(型号);
// ...
}
// ...
public int getTableSize()
{
返回model.getRowCount();
}
公共表模型getModel()
{
收益模型;
}
公共类MyTableModel扩展了AbstractTableModel
{  
受保护字符串[]columnNames=新字符串[]{“#”、“名称”、“电话号码”};
受保护的ArrayList数据;
受保护类[]类型=新类[]{String.Class,String.Class,String.Class};
公共MyTableModel(ArrayList lstData)
{this.lstData=lstData;}
public void SetData(ArrayList lstData)
{this.lstData=lstData;fireTableDataChanged();}
@凌驾
公共字符串getColumnName(int columnIndex)
{返回columnNames[columnIndex];}
@凌驾
公共类getColumnClass(int columnIndex)
{返回类型[columnIndex];}
公共对象getValueAt(int行,int列)
{
if(row<0 | | row>lstData.size())返回null;
MyData obj=lstData.get(行);
开关(列)
{
案例0:返回obj.getID();
案例1:返回obj.getName();
案例2:返回obj.getPhoneNumber();
默认值:返回null;
}
}
public int getRowCount(){return lstData.size();}
public int getColumnCount(){return columnNames.length;}
}
}
主类:

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

    }
}
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;
       }
    }
}
public类主扩展JFrame实现TableModelListener
{
公共静态数组列表数据;
公共静态MyTable表;
公共静态jbuttonmybutton;
公用干管()
{
// ...
表=新的MyTable(lstData,this);
table.getModel().addTableModelListener(此);
myButton=新JButton();
myButton.setEnabled(错误);
// ...
}
// ...
公共作废表已更改(TableModelEvent e)
{
int firstRow=e.getFirstRow();
int lastRow=e.getLastRow();
int mColIndex=e.getColumn();
开关(如getType())
{
案例TableModelEvent.INSERT:
如果(table.getTableSize()>=2)myButton.setEnabled(true);
else myButton.setEnabled(false);
打破
case TableModelEvent.DELETE:
如果(table.getTableSize()>=2)myButton.setEnabled(true);
else myButton.setEnabled(false);
打破
}
}
}
你能帮我解决这个问题吗?提前谢谢

编辑:

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

    }
}
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;
       }
    }
}
仅当我从表中添加或删除元素时,GUI才会停止响应

EDIT2:

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

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

在我向表中添加元素后,不会引发任何错误或异常,只是冻结gui而没有响应。在MyTableModel类中,请删除以下行:

protected TableModel model = this;
并删除以下方法:

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

public TableModel getModel() {
    return model;
}
您已经实现了自定义表模型,不需要在其中创建自引用。当您的类被实例化时,这个变量没有完全初始化,我怀疑这就是给您带来问题的原因。但是在任何情况下,代码绝对是不需要的。另外,在MyTable类中,我建议更改getModel()函数,使其遵从包装的表变量。像这样:

public TableModel getModel() {
    return model.getModel();
}
基本的关于或


最好是camickr,它在TableCell中实现最深层的监听功能

谢谢大家的帮助,我通过修改
tableChanged
方法解决了这个问题:

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

为了快速响应,您应该发布SSCCE。顺便说一句,这很奇怪,或者至少我不明白原因:publictablemodel getModel(){returnmodel;}。它返回这个。您可以删除它。这都发生在Swing事件调度程序线程中,对吗?您是手动调用tableChanged()还是从另一个线程插入/删除表行?@AngerClown抱歉,我不熟悉线程,也不知道什么是
Swing事件调度程序线程
。如何向表中添加元素?您的表格模型不可编辑。您是否检查了控制台以确认没有任何异常?我使用在
MyTableModel
类中定义的方法
setData
添加元素。当我添加元素时,我没有得到任何错误或异常。你是对的,这不是必需的代码。我删除了它,但仍然有相同的问题,如果没有更完整的代码发布,很难判断代码中还可能发生了什么。特别是将MyTable添加到主类的位置以及如何将所有内容设置为可见。我编辑了我的答案,同时提出了另一个可能会有所帮助的建议。