创建自定义表模型以从ArrayList提供数据

时间:2017-03-30 00:16:48

标签: java swing arraylist jtable

我正在尝试创建一个基于ArrayList信息创建表的JTable。 ArrayList充满了用户在GUI中输入的信息。每次用户按下JButton时,它都应该向表中添加一行新数据。

谷歌搜索后,似乎最好的方法是创建一个自定义表模型。我找不到一个关于如何做到这一点的体面教程。我查看了官方文档,以及一些随机网站和其他帖子。希望你们其中一个能指出我正确的方向。

这是我当前GUI的图片。 JTable应该填充中心区域: My Current GUI

这是我的一些代码:

 class dataModel extends AbstractTableModel
{
    private String[] columnName = {"Emp Num", "Base Pay", "Hours Worked", "Pay Amt"};

    public int getColumnCount()
    {
        return 4;
    }


    public int getRowCount()
    {
        return empData.size();
    }

    public Object getValueAt(int row, int col)
    {
        return new Integer(row*col);
    }
}

点击按钮时出现的类。

class listener implements ActionListener
{
    @SuppressWarnings("unchecked")
    public void actionPerformed(ActionEvent e)
    {
        ArrayList empData = new ArrayList();

        int empNum = 0;
        double hourlyRate = 0;
        double hoursWorked = 0;
        try
        {
            empNum = Integer.parseInt(empNumField.getText());
        }
        catch(NumberFormatException event)
        {
            JOptionPane.showMessageDialog(null, "Invalid entry.\n\nPlease enter a number for the Employee ID.", "Error", JOptionPane.WARNING_MESSAGE);
            return;
        }
        try
        {
            hourlyRate = Double.parseDouble(basePayField.getText());
        }
        catch(NumberFormatException event)
        {
            JOptionPane.showMessageDialog(null, "Invalid entry.\n\nPlease enter a number for the Hourly Pay Rate.", "Error", JOptionPane.WARNING_MESSAGE);
            return;
        }
        try
        {
            hoursWorked = Double.parseDouble(hrsField.getText());
        }
        catch(NumberFormatException event)
        {
            JOptionPane.showMessageDialog(null, "Invalid entry.\n\nPlease enter a number for the Hours Worked.", "Error", JOptionPane.WARNING_MESSAGE);
            return;
        }

        double payAMT = calculatePay(hourlyRate, hoursWorked);

        empData.add(empNum);
        empData.add(hourlyRate);
        empData.add(hoursWorked);
        empData.add(payAMT);

    }

2 个答案:

答案 0 :(得分:1)

你可以......

使用DefaultTableModel,这应该涵盖您的基本需求

private DefaultTableModel model;
//...
model = new DefaultTableModel(new String[] {"Emp Num", "Base Pay", "Hours Worked", "Pay Amt"}, 0);
table.setModel(model);

然后你可以直接向它添加新数据

class listener implements ActionListener {

    private DefaultTableModel model;

    listener(DefaultTableModel model) {
        this.model = model;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        int empNum = 0;
        double hourlyRate = 0;
        double hoursWorked = 0;
        double payAMT = calculatePay(hourlyRate, hoursWorked);

        model.addRow(new Object[]{empNum, hourlyRate, hoursWorked, payAMT});
    }
}

这没关系,这很简单,但它确实意味着您需要了解您所呈现的数据的结构,并且不允许您管理可能有更多您可能希望稍后使用的对象

现在,如果你想要一些更可定制的东西......

你可以......

使用自定义TableModel,首先,让我们从需求开始

public interface Employee {
    public int getNumber();
    public double getHourlyRate();
    public double getHoursWorked();
    public double getPay();
}

这定义了我们的模型可以管理的数据的基本期望。为什么?因为您可能有不同类型的员工或员工实施,其中包含更多信息,这与此表格模型无关

接下来,我们实施TableModel ...

public class DefaultWorkSheetTableModel extends AbstractTableModel {

    private List<Employee> items;

    public DefaultWorkSheetTableModel() {
        items = new ArrayList<>(25);
    }

    public DefaultWorkSheetTableModel(List<Employee> items) {
        this.items = items;
    }

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

    @Override
    public int getColumnCount() {
        return 4;
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0: return Integer.class;
            case 1: 
            case 2: 
            case 3: return Double.class;
        }
        return Object.class;
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
            case 0: return "Emp Num";
            case 1: return "Base Pay";
            case 2: return "Hours Worked";
            case 3: return "Pay Amount";
        }
        return null;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Employee item = items.get(rowIndex);
        switch (columnIndex) {
            case 0: return item.getNumber();
            case 1: return item.getHourlyRate();
            case 2: return item.getHoursWorked();
            case 3: return item.getPay();
        }
        return null;
    }

    public void add(Employee item) {
        items.add(item);
        int row = items.indexOf(item);
        fireTableRowsInserted(row, row);
    }

    public void remove(Employee item) {
        if (items.contains(item)) {
            int row = items.indexOf(item);
            items.remove(row);
            fireTableRowsDeleted(row, row);
        }
    }

}

这里有很多内容,但这涵盖了允许JTable提供我们想要的数据的所有基本要求。

现在,当您想要添加数据时,可以创建Employee的新实例,只需将其添加到模型中即可...

class listener implements ActionListener {

    private DefaultWorkSheetTableModel model;

    listener(DefaultWorkSheetTableModel model) {
        this.model = model;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        int empNum = 0;
        double hourlyRate = 0;
        double hoursWorked = 0;
        //...
        DefaultEmployee employee = new DefaultEmployee(empNum, hourlyRate, hoursWorked);
        model.add(employee);
    }
}

是的,我知道我没有通过payRate,因为这是一个特定于Employee的实施的计算字段;)

答案 1 :(得分:1)

  

JTable,它根据ArrayList中的信息创建表。

     

每次用户按下JButton时,都应该向表中添加一行新数据。

因此,您真正的要求是从某些文本字段中获取数据并将数据添加到表中。

因此无需使用ArrayList来执行此操作。

您可以使用DefaultTableModelDefaultTableModel支持addRow(...)方法。使用此方法,您可以添加VectorArray,其中包含4个文本字段中的数据。

因此,对代码的唯一真正改变是:

//ArrayList empData = new ArrayList();
Vector empData = new Vector();

然后在将所有数据添加到Vector后,您需要将Vector添加到DefaultTableModel:

empData.add(payAMT);
model.addRow( empData );

当然,您需要先创建一个空的DefaultTableModel,只使用列名,然后您的侦听器需要访问此模型。

  

似乎最好的方法是创建自定义表模型。我找不到关于如何做到这一点的体面教程

另一种选择是创建包含TableModel个对象的自定义Employee。在这种情况下,您可以使用ArrayList来保存单个Employee对象。有关为此方法创建TableModel的示例,请查看Row Table Model