# JTable & TableCellEditor Problem



## Sjoeren (27. Feb 2009)

Ich habe einen eigenen "TableCellEditor" für eine JTable geschrieben.
Dieser Funktioniert auch einwandfrei bis auf ein nervigen Bug.

Ich hab auf einem Panel die JTable und ein Element (Button oder andere Tabelle).

Klicke ich nun in der Tabelle auf eine Feld geht der TableCellEditor auf und alles geht.

Wenn ich aber vorher auf das andere Element klicke und dann direkt mein Feld mit dem TableCellEditor, wird dieser zwar ganz kurz geöffnet, aber schließt sich im gleichen Augenblick auch wieder.
Nachdem ich in dieser Tabelle dann ein Feld ohne einen selbstgeschriebenen TableCellEditor auswähle geht wieder alles.

Kann mir da jemand weiter helfen?


----------



## Ebenius (27. Feb 2009)

Sjoeren hat gesagt.:


> Kann mir da jemand weiter helfen?


Ohne Quelltext wahrscheinlich nicht.

Ebenius


----------



## Sjoeren (27. Feb 2009)

Hier bitte.
Das gleiche Problem hab ich aber auch bei Ableitung die nicht auf dem AbstractCellEditor bassieren.


```
package Table.Renderer;

import java.awt.Component;
import java.text.DateFormat;
import javax.swing.AbstractCellEditor;
import javax.swing.JFormattedTextField;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.tree.TreeCellEditor;
import sun.swing.DefaultLookup;

/**
 *
 * @author Büro
 */
public class time extends AbstractCellEditor implements TableCellEditor, TreeCellEditor,TableCellRenderer{
    private DefaultFormatterFactory DateFormatter = new DefaultFormatterFactory(new DateFormatter(DateFormat.getTimeInstance(DateFormat.SHORT)));
    private static final Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
    private static final Border DEFAULT_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
    protected static Border noFocusBorder = DEFAULT_NO_FOCUS_BORDER;
    
    JFormattedTextField time = new JFormattedTextField();

    public time() {
        time.setFormatterFactory(DateFormatter);
    }

    public Object getCellEditorValue() {
        //new Exception("Test").printStackTrace();
        return time.getText();
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        time.setText(value.toString());
        time.setOpaque(true);

        return time;
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        time.setFont(table.getFont());
        time.setBorder(getNoFocusBorder());

        time.setText(value.toString());

        return time;
    }

    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
        time.setFont(tree.getFont());
        time.setBorder(getNoFocusBorder());

        time.setText(value.toString());

        return time;
    }

    private Border getNoFocusBorder() {
        Border border = DefaultLookup.getBorder(time, time.getUI(), "Table.cellNoFocusBorder");
        if (System.getSecurityManager() != null) {
            if (border != null) return border;
            return SAFE_NO_FOCUS_BORDER;
        } else if (border != null) {
            if (noFocusBorder == null || noFocusBorder == DEFAULT_NO_FOCUS_BORDER) {
                return border;
            }
        }
        return noFocusBorder;
    }
}
```


----------



## Ebenius (27. Feb 2009)

Benutzt Du die selbe Instanz als CellRenderer und CellEditor? Wenn ja, dann eklärt das Dein Problem. Nie dieselbe Instanz dafür benutzen, das kann noch einige andere Probleme geben.

Ebenius


----------



## Sjoeren (27. Feb 2009)

Ich hab das jetzt mal Schnell in 2 Verschiedene Klassen gesteckt. Leider immer noch das gleiche Problem.

Ich hab irgendwie das Gefühl das hier 2 Sachen gleichzeitig in der Tabelle passieren.
Der Editor wird geladen und dann Millisekunden Später vom Cell-Renderer ersetzt wird.


----------



## Ebenius (27. Feb 2009)

Ich meinte nicht, dass es unbedingt in zwei Klassen muss. Nur nicht dieselbe Instanz benutzen.

Vorschlag zum weiteren Vorgehen: Bau alles in eine Main()-Methode mit so wenig anderem Zeug wie möglich und poste das mal. Dann kann man's nachvollziehen. Damit meine ich ungefähr sowas:

[HIGHLIGHT="Java"]public static void main(String[] args) {
  final JTable table =
        new JTable(new Object[][] { { new Date() }, { new Date() } },
              new String[] { "Test" });
  class MyCellEditor extends AbstractCellEditor implements TableCellEditor {

    @Override
    public Component getTableCellEditorComponent(
          JTable table,
          Object value,
          boolean isSelected,
          int row,
          int column) {
      // YOUR CODE HERE!
      return null;
    }

    @Override
    public Object getCellEditorValue() {
      // YOUR CODE HERE!
      return null;
    }
  }

  table.setDefaultEditor(Object.class, new MyCellEditor());

  final JPanel panel = new JPanel(new BorderLayout(6, 6));
  panel.add(new JScrollPane(table));
  panel.add(new JButton("Focus"), BorderLayout.SOUTH);

  final JFrame f = new JFrame("Table Cell Editor Fun");
  f.setContentPane(panel);
  f.pack();
  f.setLocationRelativeTo(null);
  f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  f.setVisible(true);
}[/HIGHLIGHT]

Ebenius


----------

