【问题标题】:Recreating a JTable when updating content更新内容时重新创建 JTable
【发布时间】:2012-12-23 13:10:07
【问题描述】:

我有一个在其中使用 JTable 的应用程序。当我向数据库中添加一些内容时,它会进入数据库,但我无法以某种方式重新创建 JTable。我试图重新绘制();创建我的表的方法我已经尝试过 Revalidate();但也没有成功

我什至试图回忆这个方法,但也没有用。

执行的动作如下:

    @Override
public void actionPerformed(ActionEvent e) {

    if(e.getSource() == add) {
        model.insertValue(toDo.getText());
        model.getValue();
        view.createTable();
        toDo.setText("");
    }
}

以及创建JTable的方法

    public void createTable() {

    JTable table = new JTable();

    DefaultTableModel tableModel = new DefaultTableModel(new Object[][]{},new String[]{"To do","Date added", "Modify"});

    table.setSize(450, 600);


    table.setModel(tableModel);
    JScrollPane scrlPan=new JScrollPane(table);

    for(int i = 0; i < model.getId().size(); i++) {

        tableModel.addRow(new Object[]{
                model.getItem().get(i), 
                model.getDate().get(i), 
                model.getId().get(i)
                });
    }

    add(scrlPan);
    add(table.getTableHeader(), BorderLayout.NORTH);
    add(table, BorderLayout.CENTER);
}

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 加标签不花钱,有助于分类浏览和搜索,所以请尽量多选1个。
  • 1) 在启动时创建表并根据需要调整模型。 2) 为了尽快获得更好的帮助,请发帖SSCCE

标签: java swing jdbc jtable tablemodel


【解决方案1】:

tableModel 设为类的一个字段,并在需要时对其进行更新。不要重新创建 table 对象。

【讨论】:

  • 我试过这个..但没用。我认为我以错误的方式实施它。你能给我举个例子吗?
  • @Reshad 在更改模型后尝试tableModel.fireTableDataChanged()。也看看这个:stackoverflow.com/questions/3179136/…
  • 不,永远不要从模型外部的代码中调用任何 fireXX 方法 - model 有责任通知其侦听器发生变化
  • @kleopatra,你为什么说“永远不要从模型外部的代码中调用任何 fireXX 方法”?你怎么解释这个?此外,我提供了该问题的链接及其评价最高的答案。你会和那些专家争论吗?
  • OP 使用的是 DefaultTableModel,所以不需要显式调用 fireXX 方法。 DefaultTableModel 本身会在表数据发生更改时执行此操作。 AFAIK 无论您对表的数据做什么,都应该在 tableModel 上完成。因此,您的表模型应该在更新时调用 fireXX 方法。我认为这就是 kleopatra 这么说的原因。
【解决方案2】:

以下代码直接源自您的代码,可以毫无问题地为我工作:

    JTable table = new JTable();
    final DefaultTableModel model = new DefaultTableModel(
            new Object[][] {}, new String[] { "To do", "Date added",
                    "Modify" });
    table.setModel(model);

    JFrame f = new JFrame();
    f.getContentPane().add(table);

    JButton b = new JButton("More ..");
    f.getContentPane().add(b, BorderLayout.NORTH);
    b.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < 2; i++) {
                model.addRow(new Object[] { "A" + i, "B" + i, "C" + i });
            }
        }
    });
    f.setSize(400, 400);
    f.setVisible(true);
    b.doClick();

只需检查您的做法是否有所不同。我可能怀疑的最后一件事 - 也许您直接从非 Swing 线程设置新值。使用 SwingUtilities.invokeLater 设置值。

从 AbstractTableModel 派生的模型需要在您的模型上调用继承的方法 fireTableCellUpdated。还有更多触发器可以触发 JTable 注册的内容更改侦听器,因此它可以在模型更改时自行更新。使用适合您的情况。另一种可能对完整内容更改有益的方法是创建和设置全新的 TableModel。但是在您的情况下,这可能与您使用 DefaultTableModel 无关:它已经实现了此功能,它不需要 repaint()、revalidate()、fireTableXYZ。设置新内容后,它必须自己完成所有操作。

【讨论】:

  • 我应该在模型的哪个部分使用 fireTableCellUpdated 函数?因为我的模型对 JTable 一无所知,所有这些都在我看来。模型只知道数据库处理和推送到视图。
  • Hmm ... 如果您的意思是从 tableModel 的代码 outside 调用 fireXX - 这是不可以的:由模型本身通知其侦听器。这样做 inside 自定义 tableModel 实现是要走的路:-)
  • 你的模型足够了解它的表,因为它是从 AbstractTableModel 派生的并且继承了代码。最重要的是,它继承了 JTable 在为其设置模型时调用的 addTableModelListener。只需调用您的模型: myModel.fireTableCellUpdated(); .
  • @AudriusMeškauskas 啊等等我误会了..我的错!但是我应该如何处理必须提供给 myModel.fireTableCellUpdate(); 的参数?因为它不能为空:S eclipse 建议使用 fireTableChanged();不需要参数,但使用时实际上什么都没有发生..
  • @Reshad 永远不要为 DefaultTableModel 调用 fireTableXxx,此通知程序已正确实施
【解决方案3】:
  • 不要重复造轮子,搜索ResultSetTableModel (few code workarounds)TableFromDatabase制作的@camickr

  • 上午解决方法是EDT sensitiveJTables 内容等到ResultSet 返回所有行,Swing GUI 冻结或不负责Key &amp; Mouse events,直到长时间和硬Object(JDBC)完成,这个逻辑可能是合适的对于小的ResultSets from small DB tables,没有打开和关闭Connection to Database,否则必须使用SwingWorkerBatch logics(fe更新XxxTableModel with 20rows

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2012-09-07
    • 1970-01-01
    • 2016-03-09
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多