JXTable没有刷新按钮点击 [英] JXTable not refreshed upon button click

查看:141
本文介绍了JXTable没有刷新按钮点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JFrame which holds a JXTable (from SwingX dependency) and a JButton.

一旦我点击了JButton表,每次都应该更新。在我的情况下,它只是在第一次更新。其他事件也会触发按钮点击(每次点击按钮时都会发生)。

Once I click the JButton the table should get updated each time. In my case it gets updated only at the first time. Other events also get triggered on the button click (which happens each time I click the button). Only the table is not refreshed with the new rows added.

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

I am using DeafultTableModel and have tried (explicit trigger) all suggested methods like repaint, fireTableDataChanged etc.

有人可以帮忙吗?

EDIT-1(添加了代码段): -

EDIT-1 (code snippet added): -

// 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();
            }
        } 
    }
});


推荐答案

以下行中有一些概念上的错误: / p>

There are some conceptual mistakes in the lines below:

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 当您按按钮,但使用表模型,而不是通过清除当前表模型和添加行或直接设置一个新的。例如:

1) Don't create a new JXTable when you press the button but work with the table model instead either by clearing the current table model and adding rows to it or directly by setting a new one. For example:

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

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

2) These lines suggests that overviewPanel has already been displayed by the time you are trying to add the new table by clicking the button, thus invalidating the components hierarchy and in consequence you have to revalidate and repaint the panel like this:

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

但是,我们可以在Swing中动态添加组件,我们将所有组件放在顶级容器之前(窗口)可见。因此,在第1点描述的方法是非常可取的,而且我补充说,只是为了完整性。

However while we can add components dynamically in Swing we tipically place all our components before the top-level container (window) is made visible. Thus the approach described in point 1 is highly preferable over this one and I'm adding this point just for completeness.

3)注意耗时的任务,如数据库通话或IO操作可能会阻止事件发送线程(EDT)导致GUI无响应。 EDT是一个单一和特殊的线程,其中Swing组件创建和更新发生。为避免阻止此线程考虑使用 SwingWorker 在后台线程中执行繁重的任务,并在EDT中更新Swing组件。请参阅 Swing中的并发课程。

3) Be aware that time consuming tasks such as database calls or IO operations may block the Event Dispatch Thread (EDT) causing the GUI become unresponsive. The EDT is a single and special thread where Swing components creation and update take place. To avoid block this thread consider use a SwingWorker to perform heavy tasks in a background thread and update Swing components in the EDT. See more in Concurrency in Swing lesson.

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

Please consider the following example illustrating point 1:


  • 在之前创建并放置表格,使顶级容器(窗口)可见。

  • 这两个操作都可以与表模型一起使用:其中一个设置一个新的表模型,另一个清除并重新填充当前的表模型。

  • The table is created and placed once before making the top-level container (window) visible.
  • Both actions work with the table model: one of them sets a new table model and the other one clear and re-fill the current table model.

这是代码。希望它有帮助!

Here is the code. Hope it helps!

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();
            }
        });
    }    
}

这篇关于JXTable没有刷新按钮点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆