单击按钮时JTable不刷新

时间:2014-10-29 11:58:33

标签: java swing event-handling jtable swingx

我有一个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<String>> validationErrors = validateSheet(Driver.this.fileLocation, list
                    .getSelectedValuesList(), regulatorTypeCB.getSelectedItem().toString(), sheetTypeCB
                    .getSelectedItem().toString());
                // creates the validation error overview to be added to roTable 
                Map<String, Integer> 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<String> tlist = new ArrayList<String>();
                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<String, Integer> 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();
            }
        } 
    }
});

1 个答案:

答案 0 :(得分:2)

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

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,而是通过清除当前表模型并向其添加行或直接设置新表来处理表模型。例如:

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

2)这些行表明,当您尝试通过单击按钮添加新表时已显示overviewPanel,因此invalidating the components hierarchy因此您必须重新验证并重新绘制像这样的小组:

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

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

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


更新

请考虑以下示例说明第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();
            }
        });
    }    
}