单击按钮更新 JTable

Updating JTable on button click

我正在使用 JTable 和找到的自定义 Table 模型 。我已根据 post 中提供的建议更新了我的代码,并将 运行 变成了一个新问题。我对我的代码所做的更改是将 ArrayList<CompletedPlayer> 注入我的 JTable 以避免线程问题。这样做之后,通过按下按钮更新我的 table 的代码已停止工作。

用于初始化 JTable 的代码如下:

TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
JTable table = new JTable(model);

我用来更新 JTable 的代码如下:

JButton btnRefreshAllPlayers = new JButton("Refresh");

btnRefreshAllPlayers.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent arg0) {

        PlayerTableModel model = (PlayerTableModel) table.getModel();
        model.fireTableDataChanged();

    }

});

我也尝试过使用 repaint() 但这也不起作用。截至目前,让 JTable 更新的唯一方法是关闭并重新打开程序。 FileHandler 具有我正在用于 JTableArrayList,随着用户添加更多玩家,它的大小会增加。

为什么 fireTableDataChanged() 检测不到任何变化?

I have searched on Whosebug and a couple of people have said to use that method.

不,您不应该在 TableModel 本身的上下文之外调用任何 fireTableXxx 方法,否则提出其他建议的人是完全错误的,这会在将来给您带来问题。从代码的外观来看,没有任何变化。如果您根据上一个问题中提供的答案更新了 TableModel,则模型中的数据与外部源没有任何关系。您需要手动从外部源重新加载数据,创建一个新的 TableModel 并将其应用到 table

例如...

JButton btnRefreshAllPlayers = new JButton("Refresh");

btnRefreshAllPlayers.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent arg0) {

        TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
        table.setModel(model);

    }

});

I have also tried setting a new model with the updated ArrayList and it worked but did not keep the table row widths I previously set.

table 这样做是合理的,因为它不知道新模型是否与旧模型具有相同的 properties/columns,所以它会重置它们。

您可以遍历 ColumnModel,将列宽存储在 ListMap 中,然后再应用模型并重新应用宽度

Is there a proper way to update the JTable?

您可以为您的 TableModel 提供刷新方法,它可以加载数据本身并触发 tableDataChanged 事件

public class PlayerTableModel extends AbstractTableModel {
    private final List<PlayerSummary.Player> summaries;

    public PlayerTableModel(List<PlayerSummary.Player> summaries) {
        this.summaries = new ArrayList<PlayerSummary.Player>(summaries);
    }
    // Other TabelModel methods...

    public void refresh() {
        summaries = new ArrayList<>(FileHandler.getCompletedPlayers());
        fireTableDataChanged();
    }
}

那么您需要在 ActionListener...

中调用此方法
PlayerTableModel model = (PlayerTableModel)table.getMode();
model.refresh();