Search code examples
javaswingjtablecellchangelistener

Add content to cell when user clicks it


I have a functionality in a JTable, that when user clicks the cell, it removes certain character in it (like when there's content - Hello, when user clicks it, it shows Hello). When it's no longer edited, it shows
- Hello again.

My problem is that when some cell is selected (but not being edited yet) and I start typing Hi, it doesn't remove the character, so the editable cell looks like - Hello Hi.

Same problem is when some cell is selected and user presses space key.

I want to add the functionality to the JTable, so that when the content of the cell starts to be edited (by any way - clicking/typing when selected/space key/and maybe there are more options I don't know about), I want to programatically change the content first. Another option would be removing it when the cell is selected (but then I have to remember position of the last selected cell, so that the character could be readded to it).

I've tried in propertyChange in class TableChangeListener:

 table.setValueAt(removeCharacter(table.getValueAt(row,column)), row, column);

but it doesn't work as the cell is already being edited and I cant change it.


Solution

    1. You will have to use your own implementation of Cell Editor to meet your own set of requirements.
    2. So create a custom CellEditor implementing FocusLisetener and ActionListener and implement the FocusGained and FocusLost function
    3. Implement the actionPerformed function too to update value on enter click.
    4. Handling the Focus event is a little bit tricky. As it tends to update the cell wrongly. That is why i had to pass the reference table to the CellEditor as a constructor parameter and read the cell row, col on Focus gain.
    5. To reflect the - xxxx: placing - before the cell value, try using a custom CellRenderer. Check out the official tutorial page for details with example. And the part of the credit goes to @mKobel.

    An implemented custom cell editor for direction: assign it to your target table column and test.

    Giff of my test result:

    enter image description here

    Code:

    class CustomRenderer extends DefaultTableCellRenderer {
    
         public void setValue(Object value) 
         {
             setText("- "+value);
          }
      }
    
    class MyCellEditor extends AbstractCellEditor
                             implements TableCellEditor,
                                        FocusListener,
                                        ActionListener
    {
        JTextField textFeild;
        String currentValue;
    
        JTable table;
        int row, col;
        public MyCellEditor(JTable table) {
            this.table = table;
            textFeild = new JTextField();
            textFeild.addActionListener(this);
            textFeild.addFocusListener(this);
        }
    
    
        @Override
        public Object getCellEditorValue() {
            return currentValue;
        }
    
        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    
            currentValue = (String)value;
            return textFeild;
    
        }
    
        @Override
        public void focusGained(FocusEvent e) {
            textFeild.setText("");
            row = table.getSelectedRow();
            col = table.getSelectedColumn();
    
        }
    
        @Override
        public void focusLost(FocusEvent e) {
    
            if(!textFeild.getText().equals(""))
               //currentValue = textFeild.getText();
               table.setValueAt(textFeild.getText(), row, col);
    
            fireEditingStopped();
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
           if(!textFeild.getText().trim().equals(""))
               currentValue = textFeild.getText();
           fireEditingStopped();
        }
    
    
    }