单击按钮时,JXTable不会刷新

我有一个JFrame ,它包含一个JXTable (来自SwingX依赖)和一个JButton

一旦我点击JButton,表格每次都会更新。 在我的情况下,它只在第一次更新。 其他事件也会在按钮单击时触发(每次单击按钮时都会发生这种情况)。 添加新行时,不会刷新表。

我正在使用DeafultTableModel并尝试(显式触发)所有建议的方法,如repaintfireTableDataChanged等。

有人可以帮忙吗?

EDIT-1(已添加代码段): –

 // the actions will take place when VALIDATE button is clicked validateButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent ae) { if (evCheckbox1.isSelected() || !list.isSelectionEmpty()) { try { // store the validation errors for future use List<List> validationErrors = validateSheet(Driver.this.fileLocation, list .getSelectedValuesList(), regulatorTypeCB.getSelectedItem().toString(), sheetTypeCB .getSelectedItem().toString()); // creates the validation error overview to be added to roTable Map tmpMap = getValidationErrorsOverview(validationErrors); System.out.println(tmpMap); // create the report overview table String[] columnNames = {"SHEET_NAME", "VALIDATION_NAME", "#"}; DefaultTableModel tmodel = new DefaultTableModel(0, 0); tmodel.setColumnIdentifiers(columnNames); JXTable roTable = new JXTable(); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); roTable.addHighlighter(HighlighterFactory.createSimpleStriping()); List tlist = new ArrayList(); JScrollPane scrPane = new JScrollPane(roTable); scrPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); scrPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); overviewPanel.add(scrPane); // create a list from the validation error overview map to insert as a row in table for (Map.Entry entry : tmpMap.entrySet()) { tlist.add(entry.getKey().split(":")[0]); tlist.add(entry.getKey().split(":")[1]); tlist.add(String.valueOf(entry.getValue())); } // add rows in table for (int i = 0; i < tmpMap.size(); i++) { tmodel.addRow(new Object[] {tlist.get((i * 3) + 0), tlist.get((i * 3) + 1), tlist.get((i * 3) + 2)}); } FileUtils.writeStringToFile(logFile, "\n" + new Date().toString() + "\n", true); roTable.setModel(tmodel); roTable.repaint(); // frame refresh Driver.this.frame.revalidate(); Driver.this.frame.repaint(); // open the log file in notepad.exe ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "verifier.log"); pb.start(); } catch (BiffException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }); 

以下几行中存在一些概念性错误:

 String[] columnNames = {"SHEET_NAME", "VALIDATION_NAME", "#"}; DefaultTableModel tmodel = new DefaultTableModel(0, 0); tmodel.setColumnIdentifiers(columnNames); JXTable roTable = new JXTable(); ... JScrollPane scrPane = new JScrollPane(roTable); ... overviewPanel.add(scrPane); 

1)当您按下按钮但不使用表格模型而是通过清除当前表格模型并向其添加行或直接设置新JXTable时,不要创建新的JXTable 。 例如:

 String[] columnNames = {"SHEET_NAME", "VALIDATION_NAME", "#"}; DefaultTableModel tmodel = new DefaultTableModel(0, 0); tmodel.setColumnIdentifiers(columnNames); yourTable.setModel(tmodel); 

2)这些行表明,当您尝试通过单击按钮添加新表时, overviewPanel已经显示,从而使组件层次结构无效 ,因此您必须重新validation并重新绘制面板,如下所示:

 overviewPanel.add(scrPane); overviewPanel.revalidate(); overviewPanel.repaint(); 

然而,虽然我们可以在Swing中动态添加组件,但我们会在顶级容器(窗口)可见之前将所有组件放置。 因此,第1点中描述的方法比这更好,我只是为了完整性而添加这一点。

3)请注意,数据库调用或IO操作等耗时的任务可能会阻止事件调度线程(EDT),导致GUI无响应。 EDT是一个单独的特殊线程,用于创建和更新Swing组件。 为避免阻塞此线程,请考虑使用SwingWorker在后台线程中执行繁重的任务并更新EDT中的Swing组件。 有关详细信息,请参阅Swing课程中的Concurrency 。


更新

请考虑以下示例说明第1点:

  • 使顶层容器(窗口)可见之前 ,创建并放置一次表。
  • 这两个操作都与表模型一起使用:其中一个设置了一个新的表模型,另一个清除并重新填充当前的表模型。

这是代码。 希望能帮助到你!

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableModel; import org.jdesktop.swingx.JXTable; public class Demo { private void createAndShowGUI() { final JXTable table = new JXTable(5, 6); table.setPreferredScrollableViewportSize(new Dimension(500, 200)); Action resetModelAction = new AbstractAction("Set a new model") { @Override public void actionPerformed(ActionEvent e) { Random random = new Random(System.currentTimeMillis()); DefaultTableModel model = new DefaultTableModel(0, 6); for (int i = 0; i < model.getColumnCount(); i++) { model.addRow(new Object[]{ random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt() }); } table.setModel(model); } }; Action clearAndFillModelAction = new AbstractAction("Clear and fill model") { @Override public void actionPerformed(ActionEvent e) { Random random = new Random(System.currentTimeMillis()); DefaultTableModel model = (DefaultTableModel)table.getModel(); model.setRowCount(0); // clear the model for (int i = 0; i < model.getColumnCount(); i++) { model.addRow(new Object[]{ random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt(), random.nextInt() }); } } }; JPanel buttonsPanel = new JPanel(); buttonsPanel.add(new JButton(resetModelAction)); buttonsPanel.add(new JButton(clearAndFillModelAction)); JPanel content = new JPanel(new BorderLayout(8,8)); content.setBorder(BorderFactory.createEmptyBorder(8,8,8,8)); content.add(new JScrollPane(table)); content.add(buttonsPanel, BorderLayout.PAGE_END); JFrame frame = new JFrame("Demo"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.add(content); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Demo().createAndShowGUI(); } }); } }