2

我想在运行时将数据添加到我自己的 JTable 模型中。我的界面上有表格和添加按钮。据我了解,我不能用二维数组来做它,并且想在我的定制表模型中使用 Arraylist,但如果我使用这种类型的数据,我不知道如何制作构造函数。

static String[] columnNames = {"A", "B", "C"};
static Object data[][] = new Object[15][3];

public MyTableModel() {
   super(data, columnNames);
}

这是将数据作为两个维度数组的构造函数,但我想使用:

ArrayList<Object[]> data = new ArrayList<Object[]>();

如何制作

4

3 回答 3

4

一种方法是使用AbstractTableModel. 这是一个例子:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

public class TestTable {

    public static class MyModel extends AbstractTableModel {

        private List<Object[]> data;
        private List<String> columnNames;

        public MyModel(List<String> columnNames, List<Object[]> data) {
            super();
            this.columnNames = columnNames;
            this.data = data;
        }

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

        @Override
        public int getColumnCount() {
            return columnNames.size();
        }

        @Override
        public String getColumnName(int column) {
            return columnNames.get(column);
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return data.get(rowIndex)[columnIndex];
        }

    }

    protected void initUI() {
        JFrame frame = new JFrame(TestTable.class.getSimpleName());
        List<String> columns = Arrays.asList("Name", "Age");
        List<Object[]> data = new ArrayList<Object[]>();
        for (int i = 0; i < 50; i++) {
            Object[] value = new Object[2];
            value[0] = "Name-" + i;
            value[1] = 12 + i;
            data.add(value);
        }
        JTable table = new JTable(new MyModel(columns, data));
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }
}

如果您需要修改您的data List<Object[]>,请不要忘记触发适当的表事件。AbstractTableModel已经包含了它们。

于 2012-11-07T17:48:02.580 回答
0

由于您没有包含表模型的完整源代码,因此很难说出您在做什么,因此我将在这里做一些假设。

您可能正在扩展AbstractTableModelDefaultTableModel. 无论哪种情况,您都不必通过构造函数将数据添加到模型中。相反,您需要在TableModel扩展中覆盖以下方法:

getRowCount()

getColumnCount()

getValueAt(int row, int column)

使这些方法中的每一个都索引到您的ArrayList<Object[]> data对象中-例如,getValueAt(row,column)应该返回类似data.get(row)[column]. 然后将您添加TableModel到 aJTable中,就显示自定义数据而言,您应该一切顺利。

现在...当您data进行更改时(您更改表中单元格的值或添加/删除行),您只需调用fireTableDataChanged()您的TableModel(假设它已扩展AbstractTableModel或其子类之一)。这将强制 UI 使用您对底层data.

于 2012-11-07T17:47:39.073 回答
0

创建自己的表模型最直接的方法是从 AbstractTableModel 继承。然后至少覆盖 getRowCount、getColumnCount 和 getValueAt。

然后,您可以使用“new JTable(mymodel)”创建表,其中“mymodel”是您创建的模型的一个实例,或者您可以只使用“new JTable”创建它,然后稍后执行 setModel 来附加您的模型到 JTable。

例如——虽然我已经做了无数次了,但我还是在脑海中写下了这个,所以没有明示或暗示的保证,很可能在某个地方有一两个语法错误:

class ArrayListModel extends AbstractTableModel
{
  ArrayList<Object[]> list;

  public ArrayListModel(ArrayList<Object[]> list)
  {
    this.list=list;
  }
  public int getRowCount()
  {
    return list.size();
  }
  public int getColumnCount()
  {
    if (list.size()==0)
    {
      return 0;
    }
    else
    {
      return list.get(0).length;
    }
  }
  public Object getValueat(int row, int column)
  {
    return list.get(row)[column];
  }
}

... somewhere else ...
ArrayListModel mymodel=new ArrayListModel(somedata);
JTable mytable=new JTable(mymodel);
... etc ...

旁注:当我第一次学习 Java 时,我认为创建 JTable 的“正常”方法是使用默认模型,创建向量向量或二维数组,然后进行填充。我认为创建自己的模型将是您在罕见的奇怪情况下所做的事情。但我后来发现默认模型只是在罕见的简单情况下的最佳方式。现在我几乎总是创建自己的模型:它通常更容易编码和更容易理解。通常我有一个使用特定字段创建的某个类的 ArrayList,然后在我的模型类中我有类似的东西:

 public Object getValueAt(int row, int col)
 {
   Whatever w=list.get(row);
   if (col==0) return w.foo;
   else if (col==1) return w.bar;
   else if (col==2) return w.plugh;
   else throw SomeException();
 }

或者使用 case 语句。同样的想法。

于 2012-11-07T17:48:38.490 回答