0

I have implemented a JTree and populated some data. The table contains three columns and based on some values on a specific cell it should have either labels or combo boxes. All the values in the 3rd column are editable. I too have a JTree from which a node is selected and based on it the table values change accordingly. The issue exists when I edit a cell in the table and move to another node in the tree (which populates a new set of data in the table), the previously edited cell values exist in the table on top of the new cell values. Below is how I implemented TableCellRenderer and TableCellEditor. I might have used some concepts wrong since I am a beginner for swing. Please help me figure out what I have done incorrectly.

        public void populateTableData(List<Field> list,JTree jTree){
        fieldList = null;
        tcBuilderTree = jTree;
        fieldList = list;
        md=new PropertiesTableModel(fieldList);
        getPropertieseTable().setModel(md);

        final TableCellRenderer cellRenderer = new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable arg0, 
                                                            Object value, 
                                                            boolean isSelected, 
                                                            boolean hasFocus, 
                                                            int row, 
                                                            int col) {

                if(value instanceof List<?>) {
                    List<Value> valueList=(ArrayList)value;
                    return createComboBox(valueList);
                }
                else{
                    JLabel lbl=new JLabel();
                    lbl.setText((String)value);
                    return lbl;
                }

            }
        };
        propertiesTable.setDefaultRenderer(Object.class, cellRenderer);

        final TableCellEditor cellEditor = new TableCellEditor() {
            private DefaultCellEditor textEditor;
            private DefaultCellEditor currentEditor;
            @Override
            public Component getTableCellEditorComponent(JTable table,
                                                        Object value, 
                                                        boolean isSelected, 
                                                        int row, 
                                                        int column) {
                textEditor = new DefaultCellEditor(new JTextField());
                PropertiesTableModel model = (PropertiesTableModel) table.getModel();
                List<Value> values = model.getPossibleValues(row, column);
                if (values != null) {
                    List<Value> valueList=(ArrayList)value;
                    currentEditor = new DefaultCellEditor(createComboBox(valueList));
                } else {
                    currentEditor = textEditor;
                }
                return currentEditor.getTableCellEditorComponent(table, value,
                        isSelected, row, column);
            }

            @Override
            public Object getCellEditorValue() {
                return currentEditor.getCellEditorValue();
            }

            @Override
            public boolean isCellEditable(EventObject anEvent) {
                JTable tbl = (JTable) anEvent.getSource();
                int row, col;
                if (anEvent instanceof MouseEvent) {
                    MouseEvent evt = (MouseEvent) anEvent;
                    row = tbl.rowAtPoint(evt.getPoint());
                    col = tbl.columnAtPoint(evt.getPoint());
                } else {
                    row = tbl.getSelectedRow();
                    col = tbl.getSelectedColumn();
                }
                if(col<2){
                    return false;
                }
                else
                {
                    return true;
                }
            }

            @Override
            public boolean shouldSelectCell(EventObject anEvent) {
                return true;
            }

            @Override
            public boolean stopCellEditing() {
                Object obj = currentEditor.getCellEditorValue();
                fieldList.get(propertiesTable.getEditingRow())
                                                .setDefaultValue(obj);
                return currentEditor.stopCellEditing();
            }

            @Override
            public void  cancelCellEditing() {
                currentEditor.cancelCellEditing();
            }

            @Override
            public void addCellEditorListener(CellEditorListener l) {
            }

            @Override
            public void removeCellEditorListener(CellEditorListener l) {

            }
        };
        propertiesTable.setDefaultEditor(Object.class,cellEditor);
    }

enter image description here

sher17
  • 607
  • 1
  • 12
  • 31

1 Answers1

3

The issue exists when I edit a cell in the table and move to another node in the tree (which populates a new set of data in the table), the previously edited cell values exist in the table on top of the new cell values.

I would guess you are not stopping editing of the table cell before you reload the table with new data.

You probably should add the following to your code when you create the JTable:

JTable table = new JTable(...);
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

See Table Stop Editing for more information.

The table contains three columns and based on some values on a specific cell it should have either labels or combo boxes

You may not need to create custom editors. Just have the table choose the appropriate default editor based on the cell being edited. You can do this by overriding the getCellEditor(...) method of the JTable. Check out: How to add unique JComboBoxes to a column in a JTable (Java) for an example of this approach.

Community
  • 1
  • 1
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Stopping the cell editing did not solve the issue. I too have added a picture on how it looks like. Apparently edited cells creates an editable control but it does not get disappear. – sher17 Mar 24 '16 at 04:07
  • @Sherihan And what happened when you got rid of your custom editors and renderers? – camickr Mar 24 '16 at 04:13
  • I didn't try using the default editor option. I feel that every time I update a cell, a new JTextField gets created and its the issue. Is there a way to handle this? – sher17 Mar 24 '16 at 04:54
  • 1
    `I didn't try using the default editor option` - why not? Why are you trying to reinvent the wheel if it is not necessary? `I feel that every time I update a cell, a new JTextField gets created ` When you edit a cell, a single editor is displayed to cover the entire area of the cell. So even if you are creating a new editor, it would still cover the previous editor. – camickr Mar 24 '16 at 15:27