title: TableModel setCellEditable and automatically setting the value back to false
body: <p>I'm currently trying to implement a JPopupMenu in my JTable that allows the unlocking of a cell for editing using</p>
  
  <pre><code>@Override 
  public void actionPerformed(ActionEvent e){
      if(e.getActionCommand() == "Unlock"){
          pTableModel.setCellEditable(this.getSelectedRow(), this.getSelectedColumn(), true);
      }
  }
  </code></pre>
  
  <p>This is the related method in the TableModel</p>
  
  <pre><code>public void setCellEditable(int row, int col, boolean value) {
      editableCells[row][col] = value;
      this.fireTableCellUpdated(row, col); // I don't think I actually need this 
                                           //because nothing in the cell has changed yet?
  }
  </code></pre>
  
  <p><code>isCellEditable()</code> then returns the value of the editableCells[][] array.
  but where in my code should I change the cell back to uneditable when focus is lost?</p>
  
  <p>On a slightly related note, I'd also like to have the cell immediately gain focus. I've read about <code>getEditorComponent().requestFocus()</code> - but that doesn't seem quite right because nothing is being edited at that time, the cell is only selected (and using that method throws a nullpointerexception which would seem to support my thought process).</p>
  
  <p>Can anyone point me in the right direction please? I can't see where I'm going wrong. Thanks</p>
  
  <p>**Edit: For locking the cell when focus is lost I tried adding a custom cellrenderer with a focusListener:</p>
  
  <pre><code>private class CustomCellRenderer extends DefaultTableCellRenderer{
      public CustomCellRenderer(){
          addFocusListener(new FocusAdapter(){
              @Override
              public void focusLost(FocusEvent e) {
                  pTableModel.setCellEditable(getSelectedRow(), getSelectedColumn(), false);
  
              }
          });
      }
  }
  </code></pre>
  
  <p>but that hasn't seemed to work either, but I'm probably implementing it incorrectly (although I've checked that the renderer has been added)</p>
  
  <hr>
  
  <p>SSCCE</p>
  
  <pre><code>import java.awt.event.*;
  import java.util.*;
  import javax.swing.*;
  import javax.swing.table.AbstractTableModel;
  
  public class CellTest {    
      public static void main(String[] args){
          SwingUtilities.invokeLater(new Runnable(){
              @Override
              public void run(){
                  createAndShowGUI();
              }
          });
      }
      private static void createAndShowGUI(){
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          MyPanel panel = new MyPanel();
  
          f.add(panel);
          f.pack();
          f.setVisible(true);
      }
  }
  
  
  class MyPanel extends JPanel implements ActionListener{
      private JTable table;
      private MyTableModel model;
      private JScrollPane sp;
      private List&lt;Person&gt; people;
  
      MyPanel(){
          people = new ArrayList&lt;&gt;();
          people.add(new Person("Will", 1));
          model = new MyTableModel(people);
  
          table = new JTable(model);
          table.addMouseListener(new MouseAdapter(){
              @Override
              public void mousePressed(MouseEvent e){
                  maybeShowPopup(e);
              }
              @Override
              public void mouseReleased(MouseEvent e){
                  maybeShowPopup(e);
              }
          });
  
          table.setFillsViewportHeight(true);
          sp = new JScrollPane(table);  
          this.add(sp);
      }
  
      @Override
      public void actionPerformed(ActionEvent e){
          if(e.getActionCommand().equals("Unlock")) {
                  model.setCellEditable(table.getSelectedRow(),table.getSelectedColumn(),true);   
          }
      }
  
      private JPopupMenu createPopupMenu(){
          JPopupMenu pop = new JPopupMenu();
          JMenuItem item = new JMenuItem("Unlock");
          item.addActionListener(this);
          pop.add(item);
          return pop;
      }
  
      private void maybeShowPopup(MouseEvent e){
          int currentRow = table.rowAtPoint(e.getPoint());
          if(currentRow &gt;= 0 &amp;&amp; currentRow &lt; table.getRowCount())
              table.setRowSelectionInterval(currentRow, currentRow);
          else
              table.clearSelection();
  
          if(table.getSelectedRow() &lt; 0) return;
          if(e.isPopupTrigger() &amp;&amp; e.getComponent() instanceof JTable){
              JPopupMenu pop = createPopupMenu();
              pop.show(e.getComponent(), e.getX(), e.getY());
          }
      }
  }
  </code></pre>
  
  <p>And the TableModel and data class:</p>
  
  <pre><code>class MyTableModel extends AbstractTableModel{
      private List&lt;Person&gt; data;  
      private String[] colNames = new String[]{"Name","Age"};
      private boolean[][] editableCells;
  
      public MyTableModel(List&lt;Person&gt; data){
          this.data = data;
          this.editableCells = new boolean[this.getRowCount()][this.getColumnCount()];
      }
  
      @Override
      public int getRowCount() { return data.size(); }
  
      @Override
      public int getColumnCount() { return colNames.length; }
  
      @Override
      public Object getValueAt(int row, int col){
          Person p = data.get(row);
          switch(col){
              case 0 : return p.getName();
              case 1 : return p.getAge();
          }
          return null;
      }
  
      @Override
      public boolean isCellEditable(int row, int col){
          return editableCells[row][col];
      }
  
      public void setCellEditable(int row, int col, boolean value){
          editableCells[row][col] = value;
      }
  
      @Override
      public void setValueAt(Object value, int row, int col){
          Person p = data.get(row);
          switch(col){
              case 0 : p.setName((String)value);break;
              case 1 : p.setAge((int)value);break;
          }
          this.setCellEditable(row, col, false);
          this.fireTableCellUpdated(row, col);
      }
  
      public void setData(List&lt;Person&gt; data){
          this.data = data;
          this.fireTableDataChanged();
      }
  }
  
  class Person {
      private String name;
      private int age;
  
      public Person(String name, int age){
          this.name = name;
          this.age = age;
      }
  
      public void setName(String name){ this.name = name;}
      public String getName(){ return name; }
      public void setAge(int age){ this.age = age;}
      public int getAge(){ return age; }
  }
  </code></pre>
  
  <p>Apologies for the length - I didn't know how to make it shorter without perhaps poorly recreating what I wanted to achieve. There's a mistake in this code in that to right click and 'Unlock' you have to have already left-clicked a row otherwise they'll be an arrayIndexOutOfBounds exception. I haven't been able to find the exact cause yet.</p>
  
  <p>But basically when you right-click and then select unlock, I'd like the cursor to appear in the cell. At the moment you click unlock and then have to double click the cell.</p>