0

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

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

对于我来说JTable,我正在使用Bean Table Model来自tips4Java(http://tips4java.wordpress.com/2008/11/27/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每次我向它发送新数据时,我不是都没有更新新结果吗?

4

1 回答 1

6

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

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

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

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

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

table.setModel( newlyCreatedModel );

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

于 2013-10-13T18:20:42.107 回答