简体   繁体   English

JTable(BeanTableModel)不更新/刷新-Java Swing

[英]JTable (BeanTableModel) not updating/refreshing - Java Swing

I've 2 panels. 我有2个面板。 One where the user inserts the data and the other with a JTable where the results will be shown. 一个用户在其中插入数据,另一个用户在JTable中显示结果。

My problem is when the user press's the ok (in my case apply) JButton the data is computed but is not shown on the JTable , nothing changes in the JTable . 我的问题是,当用户按下的确定(在我的案件,不适用) JButton数据进行计算,但是,没有显示JTable ,没有在改变JTable

For my JTable I'm using the Bean Table Model from tips4Java ( http://tips4java.wordpress.com/2008/11/27/bean-table-model/ ). 对于我的JTable我使用的是来自tips4Java( http://tips4java.wordpress.com/2008/11/27/bean-table-model/ )的Bean Table Model

One weird thing is if I send data (lets call this data 'A') to the table when the program starts it is shown on the table and if later on I try to update the table, the table does not update. 一件奇怪的事情是,如果我在程序启动时向表发送数据(让我们称此数据为“ A”),并且稍后再尝试更新表,则该表不会更新。 But when I don't send data to the table at start up but try to update/send the table with data 'A' it does not update. 但是,当我在启动时不向表发送数据但尝试使用数据“ A”更新/发送表时,它不会更新。

So my question is, why is not the JTable showing whatever data I send to? 所以我的问题是,为什么JTable显示我发送给的任何数据?

Here's my code: 这是我的代码:

JButton listenere that starts the processing and sends the data to the table: 启动处理并将数据发送到表的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();
    }
});
}

And here's my tablePanel class: 这是我的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();
    }

So again, my question is: Isn't my JTable not updated with the new results every time I send new data to it? 再说一遍,我的问题是:每次发送新数据到JTable不会用新结果更新JTable吗?

You should never invoke fireTableDataChanged manually. 您永远不要手动调用fireTableDataChanged。 Only the TableModel is responsible for invoking this event. 仅TableModel负责调用此事件。

From your code it looks like you are creating a new TableModel, JTable and JScrollPane every time you make a change. 从您的代码看来,您每次进行更改时都在创建一个新的TableModel,JTable和JScrollPane。 Any time you add a component to a visible GUI the basic code should be: 每当您将组件添加到可见的GUI时,基本代码应为:

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

By default all components have a size of zero so since you don't invoke revalidate() then never get a proper size and there is nothing to paint. 默认情况下,所有组件的大小都为零,因此,由于您不调用revalidate(),因此永远不会获得适当的大小,因此无需绘制任何内容。 Also, it is never a good idea to simply keep adding components to the CENTER of your panel since the old component are still part of the container. 而且,永远不要简单地继续向面板的CENTER添加组件,因为旧的组件仍然是容器的一部分。

However, there is a better solution. 但是,有一个更好的解决方案。 There is no need to keep creating new components. 无需继续创建新组件。 All you need to do is create an new TableModel and then use: 您需要做的就是创建一个新的TableModel,然后使用:

table.setModel( newlyCreatedModel );

and the model will be added to the table and the table will repaint itself automatically. 并将模型添加到表格中,表格将自动重新绘制自身。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM