title: Using TableCellEditor and TableCellRenderer at the same time?
body: <p>I am using a TableCellEditor :</p>
  
  <pre><code>    package gui.table;
  
  import java.awt.Component;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.MouseAdapter;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseListener;
  import java.util.EventObject;
  import java.util.LinkedList;
  import java.util.List;
  
  import javax.swing.BorderFactory;
  import javax.swing.ButtonModel;
  import javax.swing.JButton;
  import javax.swing.JTable;
  import javax.swing.event.CellEditorListener;
  import javax.swing.table.TableCellEditor;
  
  import org.jdom2.Document;
  import org.jdom2.Element;
  
  import event.TableClickEvent;
  import event.TestController;
  import gui.DaimlerColor;
  import gui.MainWindow;
  
  @SuppressWarnings("serial")
  public class TestcaseCellEditor extends TestcasePanel implements TableCellEditor {
  
      int row;
      List&lt;String&gt; data;
      TestController tgc;
      transient protected TableClickEvent changeEvent = null;
  
      public int getRow() {
          return row;
      }
  
      public void setRow(int row) {
          this.row = row;
      }
  
      public TestcaseCellEditor(final JTable table, MainWindow gui, List&lt;String&gt; data, TestController tgc) {
  
          super();
          super.gui = gui;
          this.data = data;
          this.tgc = tgc;
  
          MouseListener ml = new MouseAdapter() {
              @Override
              public void mousePressed(MouseEvent e) {
  
                  ButtonModel m = ((JButton) e.getSource()).getModel();
                  setRow(table.getEditingRow());
                  if (m.isPressed() &amp;&amp; table.isRowSelected(table.getEditingRow()) &amp;&amp; e.isControlDown()) {
                      setBackground(DaimlerColor.LIGHT_BLUE);
                  }
              }
  
          };
          playButton.addMouseListener(ml);
  
          playButton.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                  fireEditingStopped();
              }
          });
  
          addMouseListener(new MouseAdapter() {
              @Override
              public void mousePressed(MouseEvent e) {
  
                  setRow(table.getEditingRow());
                  fireEditingCanceled();
  
              }
          });
      }
  
      @Override
      public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
  
          this.setToolTipText("Click play to rerun this Testcase");
          this.setName(data.get(row));
  
          setPlaybuttonIcon(gui.getTestcasetableModelIcon(row));
  
          setClickable(tgc.clickable);
  
          if (row &lt;= gui.currentTestcase) {
              Document doc = tgc.getDoc();
              List&lt;Element&gt; cases = doc.getRootElement().getChildren();
              List&lt;Element&gt; teststeps = cases.get(row).getChildren();
              List&lt;String&gt; attributes = new LinkedList&lt;String&gt;();
              for (Element teststep : teststeps) {
  
                  try {
                      if (teststep.getChildren("result").get(gui.sutPaths.getSelectedIndex()).getAttributeValue("status") != null) {
                          attributes.add(teststep.getChildren("result").get(gui.sutPaths.getSelectedIndex())
                                  .getAttributeValue("status"));
                      }
  
                      else {
                          attributes.add("empty");
                      }
                  } catch (Exception e) {
                      attributes.add("empty");
                  }
  
              }
  
              if (attributes.contains("empty")) {
                  setButton("");
              } else if (attributes.contains("failed")) {
  
                  setButton("failed");
  
              } else {
                  setButton("passed");
              }
  
          } else {
              setButton("");
          }
  
          this.setBorder(BorderFactory.createEmptyBorder());
          this.setBackground(isSelected ? DaimlerColor.LIGHT_BLUE : (row % 2 == 1 ? DaimlerColor.DARK_WHITE
                  : DaimlerColor.WHITE));
  
          System.out.println("CLCIKED");
  
          return this;
  
      }
  
      @Override
      public Object getCellEditorValue() {
          return "";
      }
  
      @Override
      public boolean isCellEditable(EventObject e) {
          return true;
      }
  
      @Override
      public boolean shouldSelectCell(EventObject anEvent) {
          return true;
      }
  
      @Override
      public boolean stopCellEditing() {
          return true;
      }
  
      @Override
      public void cancelCellEditing() {
          fireEditingCanceled();
  
      }
  
      @Override
      public void addCellEditorListener(CellEditorListener l) {
          listenerList.add(CellEditorListener.class, l);
      }
  
      @Override
      public void removeCellEditorListener(CellEditorListener l) {
          listenerList.remove(CellEditorListener.class, l);
      }
  
      public CellEditorListener[] getCellEditorListeners() {
          return listenerList.getListeners(CellEditorListener.class);
      }
  
      protected void fireEditingStopped() {
  
          Object[] listeners = listenerList.getListenerList();
  
          for (int i = listeners.length - 2; i &gt;= 0; i -= 2) {
  
              if (listeners[i] == CellEditorListener.class) {
  
                  changeEvent = new TableClickEvent(this.playButton, getRow());
                  ((CellEditorListener) listeners[i + 1]).editingStopped(changeEvent);
              }
          }
      }
  
      protected void fireEditingCanceled() {
  
          Object[] listeners = listenerList.getListenerList();
  
          for (int i = listeners.length - 2; i &gt;= 0; i -= 2) {
  
              if (listeners[i] == CellEditorListener.class) {
  
                  changeEvent = new TableClickEvent(this, getRow());
                  ((CellEditorListener) listeners[i + 1]).editingCanceled(changeEvent);
              }
          }
      }
  }
  </code></pre>
  
  <p>and a TableCellrenderer :</p>
  
  <pre><code>    package gui.table;
  
  import event.TestController;
  import gui.DaimlerColor;
  import gui.MainWindow;
  
  import java.awt.Component;
  import java.util.LinkedList;
  import java.util.List;
  
  import javax.swing.BorderFactory;
  import javax.swing.JTable;
  import javax.swing.table.TableCellRenderer;
  
  import org.jdom2.Document;
  import org.jdom2.Element;
  
  @SuppressWarnings("serial")
  public class TestcaseCellRenderer extends TestcasePanel implements TableCellRenderer {
  
      public List&lt;String&gt; data;
      MainWindow gui = null;
      public TestController tgc = null;
  
      public TestcaseCellRenderer() {
          super();
          setName("Table.cellRenderer");
      }
  
      public TestcaseCellRenderer(List&lt;String&gt; names, MainWindow gui2, TestController tgc) {
          super();
          this.data = names;
          this.gui = gui2;
          this.tgc = tgc;
          setName("Table.cellRenderer");
      }
  
      @Override
      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
              int row, int column) {
  
          this.setToolTipText("Click play to rerun this Testcase");
          System.out.println("Rendering your ass!");
          this.setName(data.get(row));
          setPlaybuttonIcon(gui.getTestcasetableModelIcon(row));
          setClickable(tgc.clickable);
  
          if (row &lt;= gui.currentTestcase) {
              Document doc = tgc.getDoc();
              List&lt;Element&gt; cases = doc.getRootElement().getChildren();
              List&lt;Element&gt; teststeps = cases.get(row).getChildren();
              List&lt;String&gt; attributes = new LinkedList&lt;String&gt;();
              for (Element teststep : teststeps) {
  
                  try {
                      if (teststep.getChildren("result").get(gui.sutPaths.getSelectedIndex()).getAttributeValue("status") != null) {
                          attributes.add(teststep.getChildren("result").get(gui.sutPaths.getSelectedIndex())
                                  .getAttributeValue("status"));
                      }
  
                      else {
                          attributes.add("empty");
                      }
                  } catch (Exception e) {
                      attributes.add("empty");
                  }
  
              }
  
              if (attributes.contains("empty")) {
                  setButton("");
              } else if (attributes.contains("failed")) {
  
                  setButton("failed");
  
              } else {
                  setButton("passed");
              }
  
          } else {
              setButton("");
          }
  
          if (tgc.isRerunning() &amp;&amp; tgc.getEventRow() == row) {
              setButton("");
          }
  
          this.setBorder(BorderFactory.createEmptyBorder());
          this.setBackground(isSelected ? DaimlerColor.LIGHT_BLUE : (row % 2 == 1 ? DaimlerColor.DARK_WHITE
                  : DaimlerColor.WHITE));
  
          return this;
      }
  
  }
  </code></pre>
  
  <p>Somehow if I click on the text in the table it only sets the focus every second click? It also only fires the fireEdizingCanceled Event every second time? Why is that?</p>
  
  <p>Thanks for any ideas.</p>