JTable Duplicates Columns when "Hiding" and "Showing" them

Viewed 73

I am currently using a JTable to display a few patient details. I have a JCheckBox, that when ticked adds a new column to the table and adds the data to the new column. When it is unticked, it should remove the column, sort of like adding extra filters to the table. However, when I tick the box again after unticking it, it duplicates the columns in the table.

I tried to use the fireTableStructureChanged() method, but it would never update the table and so the columns stay there even if the checkbox was unticked. But if I remove it, then when I untick the the checkbox it works, but then the duplication problem comes back. I pasted my actionPerformed() method for when the checkbox is ticked. The first image is of my table before I click my Checkbox. The second is when I click the Checkbox and the column is added. Lastly the third is when I untick the checkbox and tick again. Any help will be much appreciated.

 @Override
        public void actionPerformed(ActionEvent e)
        {
            if (gui.getChkCholesterol().isSelected() == true)
            {
                try {
                    gui.getRightTableModel().addColumn("Cholesterol");
                    newColumnIndeces.put("2093-3",gui.getRightTable().getColumnCount()-1);
                    gui.getRightTableModel().addColumn("Cholesterol Effective Date/Time");
                    newColumnIndeces.put("2093-3e",gui.getRightTable().getColumnCount()-1);
                    if(gui.getRightTable().getRowCount()>0)
                    {
                        int columnNumberValue = newColumnIndeces.get("2093-3");
                        int columnNumberDate = newColumnIndeces.get("2093-3e");
                        for (int i = 0; i<gui.getRightTable().getRowCount(); i++)
                        {
                            String value = op.getPatientObservationValue(gui.getRightTable().getValueAt(i,0).toString(),"2093-3");
                            String date = op.getPatientObservationEffectiveDate(gui.getRightTable().getValueAt(i,0).toString(),"2093-3");
                            gui.getRightTableModel().setValueAt(value, i, columnNumberValue);
                            gui.getRightTableModel().setValueAt(date, i, columnNumberDate);
                        }
                    }
                } catch (ParseException parseException) {
                    parseException.printStackTrace();
                }

                setCellColourForTable();

                timer.schedule(new RefreshTable(), 0, seconds);
            }

            else
            {
                gui.getRightTable().removeColumn(gui.getRightTable().getColumnModel().getColumn(newColumnIndeces.get("2093-3")));
                gui.getRightTable().removeColumn(gui.getRightTable().getColumnModel().getColumn(newColumnIndeces.get("2093-3e")-1));
                newColumnIndeces.remove("2093-3");
                newColumnIndeces.remove("2093-3e");

                timer.cancel();
                timer = new Timer();
            }
            gui.getRightTableModel().fireTableStructureChanged();
        }

Image 1

Image 2

enter image description here

1 Answers

You add a column to the model by using:

gui.getRightTableModel().addColumn("Cholesterol");

This will notify the view that the data has changed and the table will also be updated.

However, you remove the column from the table using:

 gui.getRightTable().removeColumn(…);

This only removes the column from the "table view". The column has not been removed from the DefaultTableModel. So the next time you add a column it just gets added to the end of the DefaultTableModel.

So the solution is to remove the column from the DefaultTableModel, not the table.

Unfortunately there is no removeColumn(…) method.

However because your requirement is to only add/remove columns from the end of the DefaultTableModel you can use:

model.setColumnCount(model.getColumnCount() - 2);

which will effectively remove the last two columns from the model.

The other option is to not keep adding columns to the DefaultTableModel, but instead you can just add/remove TableColumns from the TableColumnModel directly. So this would mean the data for the Cholestoral column would always be in the model, but the view would just not display the columns.

So instead of using the model.addColumn(…) you would use the table.addColumn(…) method.

Related