JTable(BeanTableModel)没有更新/刷新 - Java Swing

时间:2013-10-13 17:56:57

标签: java swing jtable tablemodel

我有2个面板。一个用户插入数据,另一个用JTable显示结果。

我的问题是当用户按下确定(在我的情况下适用)JButton数据被计算但未显示在JTable上时,JTable中没有任何变化。< / p>

对于我的JTable我正在使用tips4Java(http://tips4java.wordpress.com/2008/11/27/bean-table-model/)中的Bean Table Model

一个奇怪的事情是,如果我在程序启动时向表发送数据(让我们调用此数据'A'),它会显示在表中,如果稍后我尝试更新表,则表不会更新。但是当我在启动时没有向表发送数据但尝试更新/发送带有数据'A'的表时它不会更新。

所以我的问题是,为什么JTable显示我发送的任何数据?

这是我的代码:

开始处理并将数据发送到表的JButton监听:

crashForm.setFormListener(new FormListener() {
    @Override
    public void formEvent(OptionsFormEvent oe) {
        String readTable = oe.getReadFromTable();
        int access = oe.getAccess();
        int transition = oe.getTransition();
        boolean smooth = oe.isTrainCrash();
        ArrayList<String> allTrains = new ArrayList<>();
        List crashedTrainList = new ArrayList<>();

        try {
            allTrains = controller.getUniqueTrains(controller.connectServer(), readTable, "trainid");
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, "An error occured while getting trains data\n"
                    + "Error description: " + ex.getMessage(), "Error",
                    JOptionPane.ERROR_MESSAGE);
        }

        try {
            for (int i = 0; i < allTrains.size(); i++) 
            {
                ArrayList<Train> trainDataList = new ArrayList<>();
                ArrayList<Train> crashedProccessedData = new ArrayList<>();

                String query = "the sql query...";

                trainDataList = controller.getTrainData(controller.connectServer(), readTable, query);

                crashedProccessedData = controller.detectCrash(access, transition, trainDataList);
                crashedTrainList.addAll(crashedProccessedData);

            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, "An error occured while detecting a crash.\n"
                    + "Error description: " + ex.getMessage(), "Error",
                    JOptionPane.ERROR_MESSAGE);
        }

        System.out.println("Total crashes detected:" + crashedTrainList.size());
        tablePanel.createTable(Train.class, crashedTrainList, true, false, tableLabels);
        tablePanel.fireTableDataChanged();
    }
});
}

这是我的tablePanel类:

    public TablePanel() {
    }
    public void createTable(Class c, List data, boolean toolBarUp, 
            boolean toolBarBottom, ArrayList<String> labelsCheckBox) {

        beanTableModel = new BeanTableModel(c, data);
        columnModel = new XTableColumnModel();
        table = new JTable(beanTableModel);
        table.setColumnModel(columnModel);
        table.createDefaultColumnsFromModel();

        if(toolBarUp == true)
        {
            final JToolBar toolBarTop = new JToolBar();

            // Create the Show ALL
            JButton reset = new JButton("Reset");

            reset.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                for(Component c : toolBarTop.getComponents()){
                    if(c instanceof JCheckBox){
                        JCheckBox checkBox = (JCheckBox) c;
                        checkBox.setSelected(false);
                        columnModel.setAllColumnsVisible();
                    }
                }
                int numberOfColumn = columnModel.getColumnCount();

                for(int aux = 0; aux < numberOfColumn; aux++)
                {
                    int num = columnModel.getColumnCount();
                    TableColumn column = columnModel.getColumnByModelIndex(aux);
                    columnModel.setColumnVisible(column, true);
                }
            }
            });

            toolBarTop.add(reset);

            // Create a JCheckBox for each column
            for(int i = 0; i < labelsCheckBox.size(); i++)
            {
                final int index = i;
                toolBarTop.add(new JCheckBox(new AbstractAction(labelsCheckBox.get(i)) {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        TableColumn column = columnModel.getColumnByModelIndex(index);
                        boolean visible = columnModel.isColumnVisible(column);
                        columnModel.setColumnVisible(column, !visible);
                    }
                }));
            }



            setLayout(new BorderLayout());
            add(toolBarTop, BorderLayout.NORTH);
            add(new JScrollPane(table), BorderLayout.CENTER);
//            add(toolBarDown, BorderLayout.SOUTH);
        }


        final JToolBar toolBarDown = new JToolBar();

        toolBarDown.add(new JButton(new AbstractAction("Save Table") {
            @Override
            public void actionPerformed(ActionEvent e) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        }));


    }

    public void createTable(Class c, Class cAncestor) {
        beanTableModel = new BeanTableModel(c, cAncestor);
        table = new JTable(beanTableModel);
        setLayout(new BorderLayout());
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    public void createTable(Class c, Class cAncestor, List data) {
        beanTableModel = new BeanTableModel(c, cAncestor, data);
        table = new JTable(beanTableModel);
        setLayout(new BorderLayout());
        add(new JScrollPane(table), BorderLayout.CENTER);
        beanTableModel.fireTableDataChanged();
    }

    public void createTable(Class c) {
        beanTableModel = new BeanTableModel(c);
        table = new JTable(beanTableModel);
        setLayout(new BorderLayout());
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    public void createTable(Class c, List data)
    {
        beanTableModel = new BeanTableModel(c, data);
        table = new JTable(beanTableModel);
        setLayout(new BorderLayout());
        add(new JScrollPane(table), BorderLayout.CENTER);
    }

    //to refresh the table everytime there is an update
    public void fireTableDataChanged()
    {
        beanTableModel.fireTableDataChanged();
    }

同样,我的问题是:每次向其发送新数据时,我的JTable是否都没有更新新结果?

1 个答案:

答案 0 :(得分:6)

你永远不应该手动调用fireTableDataChanged。只有TableModel负责调用此事件。

从您的代码看,您每次进行更改时都会创建一个新的TableModel,JTable和JScrollPane。每次将组件添加到可见GUI时,基本代码应为:

panel.add(....);
panel.revalidate();
panel.repaint();

默认情况下,所有组件的大小都为零,因此您不会调用revalidate(),因此永远不会获得适当的大小,并且没有任何内容可以绘制。此外,由于旧组件仍然是容器的一部分,因此简单地将组件添加到面板的CENTER绝不是一个好主意。

然而,有一个更好的解决方案。无需继续创建新组件。您需要做的就是创建一个新的TableModel,然后使用:

table.setModel( newlyCreatedModel );

,模型将被添加到表格中,表格将自动重新绘制。