Swing JTable: edit Cell -> versteckten Wert ändern

chrissy

Bekanntes Mitglied
Hallo,

iregendwie steh ich grad voll auf dem Schlauch ...
Ich habe eine JTable mit eigenem TableModel ... editieren an sich funktioniert auch. Jetzt möchte ich nur nach einem manuellem Update einer Zelle, einen Wert in einer versteckten Spalte ändern. Das sollte ja eigentlich über mymodel.setValueat("OK", row, column) ohne weiteres funktionieren. Aber wo muss ich die Methode aufrufen. Im Moment habe ich irgendwie den Überblick von Listenern und Events verloren.

Wär echt nett, wenn mir mal schnell jemand auf die Sprünge hilft ...

Danke,
chrissy
 

ymene

Bekanntes Mitglied
Ist etwas schwierig so pauschal zu beantworten, da es auch von der Datenstruktur die hinter dem TableModel liegt abhängig ist. Vermute mal du nutzt ein mehrdimensionales ObjektArray, die Daten haben sonst zueinander keinen Bezug und die Tabelle soll der einzige Ort sein, an dem du die Daten editieren kannst?

Dann wäre vermutlich ein TableModelListener das richtige für dich. Diesen addest du einfach an das Model und kannst so alle Änderungen verfolgen:

Java:
class CustomTableModel extends AbstractTableModel implements TableModelListener
{
  public CustomTableModel()
  {
    addTableModelListener( this );
  }

  //ggf. weitere Methoden.

  @Override
  public void tableChanged( TableModelEvent e )
  {
    if( e.getType() == TableModelEvent.UPDATE )
    {
      if ( getColumnName( e.getColumn() ).equals( "SpalteXY" ) )
      {//Wurde die Spalte XY editiert, dann setz das value von SpalteToEdit auf "Ok"
        setValueAt( "Ok", e.getFirstRow(), SpalteToEditIndex );
      }
    }
  }
}

Vielleicht nicht die eleganteste Lösung, aber zweckmäßig. Das Ganze ist Pseudocode und setzt natürlich vorraus, dass du die Spalten entsprechend mit Namen versehen hast und den Index der zu editierenden Spalte kennst. Diesen musst ggfs. dann natürlich ermitteln.

Grüße,
ymene
 
Zuletzt bearbeitet:

KrokoDiehl

Top Contributor
Eigentlich könnte man es auch direkt im TableModel machen:
Java:
class MyTableModel implements TableModel
{
    ...

    @Override
    public void setValueAt( Object value, int row, int col )
    {
        // ...normaler set value at code
        if (col == meineBestimmteSpalte)
        {
            myTableData[row][meineVersteckteSpalte] = machWasMit(value);
            // vermutlich ist ein update-event vom Modell hier nicht nötig,
            // weil man die Spalte nicht sieht :)
        }
    }    
}
 

chrissy

Bekanntes Mitglied
Danke für die Hilfe, leider habe ich das so ähnlich implementiert ... sorry hab vergessen meinen Code anzuhängen

Tabelle:
Java:
    model = new MyTableModel((Vector) datas.elementAt(1), columnNames);
    model.addTableModelListener(new TableModelListener()
      {
        public void tableChanged(TableModelEvent e) 
        {
          model.setValueAt("CHANGED", e.getFirstRow(), 11);   
        }
      }
    );
    table = new JTable(model);
Model:
Java:
package models;

import java.io.Serializable;

import java.util.Vector;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;

public class MyTableModel
  extends AbstractTableModel implements Serializable
{  
  protected Vector    dataVector;
  protected Vector    columnIdentifiers;

  public MyTableModel(Vector data, Vector columnNames)
  {
    setDataVector(data, columnNames);
  }
 
  public int getColumnCount() 
  {
      return columnIdentifiers.size();
  }

  public int getRowCount() 
  {
      return dataVector.size();
  }
  
  public String getColumnName(int column) 
  {
      Object id = null; 
      // This test is to cover the case when 
      // getColumnCount has been subclassed by mistake ... 
      if (column < columnIdentifiers.size()) 
      {  
          id = columnIdentifiers.elementAt(column); 
      }
      return (id == null) ? super.getColumnName(column) 
                          : id.toString();
  }

  public Object getValueAt(int row, int column) 
  {
      Vector rowVector = (Vector)dataVector.elementAt(row);
      return rowVector.elementAt(column);
  }

  public boolean isCellEditable(int row, int column) 
  {
      return true;
  }

  public void setValueAt(Object aValue, int row, int column) 
  {
      Vector rowVector = (Vector)dataVector.elementAt(row);
      rowVector.setElementAt(aValue, column);
      fireTableCellUpdated(row, column);
  }
  
  public Vector getDataVector() {
      return dataVector;
  }  
  
  public void setDataVector(Vector dataVector, Vector columnIdentifiers) 
  {
      this.dataVector = nonNullVector(dataVector);
      this.columnIdentifiers = nonNullVector(columnIdentifiers); 
      justifyRows(0, getRowCount()); 
      fireTableStructureChanged();
  }
  
  public void addRow(Vector rowData) {
      insertRow(getRowCount(), rowData);
  }
  
  public void insertRow(int row, Vector rowData) {
      dataVector.insertElementAt(rowData, row); 
      justifyRows(row, row+1); 
      fireTableRowsInserted(row, row);
  }
  

  public void updateRow(int row, Vector rowData )
  {
    dataVector.setElementAt(rowData, row); 
    fireTableRowsUpdated(row, row);
  }
    
  public Vector getRowData(int row)
  {
    return (Vector)dataVector.elementAt(row);
  }
  
  public void removeRow(int row) {
      dataVector.removeElementAt(row);
      fireTableRowsDeleted(row, row);
  }
  
  private static Vector nonNullVector(Vector v) 
  { 
      return (v != null) ? v : new Vector(); 
  }
  
  private void justifyRows(int from, int to) 
  { 
      dataVector.setSize(getRowCount()); 

      for (int i = from; i < to; i++) { 
          if (dataVector.elementAt(i) == null) { 
              dataVector.setElementAt(new Vector(), i); 
          }
          ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
      }
  }
  
  public Class getColumnClass(int columnIndex)
  {
    return Object.class;
  }
}

Da in meinem setValueAt ein fireTableCellUpdated(row, column) aufgerufen wird, ende ich immer in einer Endlosschleife. Allerdings benötige ich das Update, da Werte nicht nur manuell geändert werden könnnen, sondern auch durch Klick auf Buttons z.B. Datensätze neu generiert.
Noch ne Idee, was man da machen kann? Ich habe für die Table eine Eigenschaft "editingstopped" gefunden, kann man die irgendwie nutzen?

Danke
 

KrokoDiehl

Top Contributor
Nun, du darfst nicht beides machen! Entweder den Wert der versteckten Spalte in einem TableModelListener setzen, oder in der
Code:
setValueAt()
. Natürlich kommt es sonst zu einer Endlosschleife, wenn beim setValue ein Update-Event ausgelöst wird und in der Event-Behandlung wieder ein setValue aufgerufen wird.

Das
Code:
editingStopped()
könnte auch funktionieren, ist jedoch vom Zusammenhang her nicht passend. So wie ich dein Modell verstehe, ist es eben eine Eigenschaft des Modells, dass bei gewissen Änderungen in einer weiteren Spalte Werte angepasst werden.
 

chrissy

Bekanntes Mitglied
hm, soweit war ich auch schon mal ... allerdings wird ja setValueAt ja immer aufgerufen, wenn Daten in die Tabelle geschrieben werden, also auch beim Füllen.
Kann man irgendwie abfragen, ob die Daten händisch, also über den CellEditor, geändert wurden?

Danke
 

KrokoDiehl

Top Contributor
Dafür wäre das
Code:
editingStopped()
der Tabelle eine Anlaufstelle, oder ein CellEditorListener, den müsste man aber direkt an den CellEditor hängen.
 

ymene

Bekanntes Mitglied
Wenn ich das auf den ersten Blick so richtig deute, landest du in der Endlosschleife, da du in der tableChanged(TableModelEvent e) - Methode deines TableListeners nicht abfragst, welche Spalte sich geändert hat. Daher wird bei jeder Änderung wieder die setValueAt(...) - Methode dort aufgerufen wodurch wiederum ein TableChangedEvent ausgelöst wird und so weiter.

Nun ist die Frage: Beim Füllen der Daten ins Model möchtest du nicht, dass dieses automatische setzen des Feldes passiert? Wenn der Wert ohnehin vom Inhalt des Feldes abhängig ist, dann dürfte das keine Rolle spielen, oder wie genau soll es ablaufen?
 

chrissy

Bekanntes Mitglied
@ymene

Ich frage das Feld nicht ab, da es egal ist welches Feld in der Tabelle geändert wird und nicht vom Inhalt des Feldes abhängig st, immer soll der Wert in der versteckten Spalte geändert werden. Beim Füllen möchte ich das nicht tun, da ich den Wert nur ändern möchte, wenn er händisch geändert wurde.
Ich wered jetzt versuchen, wie von KrokoDiehl vorgeschlagen und von mir befürchtet, über den CellEditoListener und editingstopped() der Tabelle zu gehen.

Danke
 

ymene

Bekanntes Mitglied
Ich frage das Feld nicht ab, da es egal ist welches Feld in der Tabelle geändert wird und nicht vom Inhalt des Feldes abhängig st, immer soll der Wert in der versteckten Spalte geändert werden.

Dennoch bräuchtest du eine Abbruchbedingung in deiner tableChanged() - Methode , um die Schleife zu verhindern. Und zwar müsste die dann lauten:

Rufe nur setValue(..) auf, wenn ich nicht die versteckte Spalte bin.

Aber das verhindert natürlich nicht dass beim Füllen der Tabelle die Events gefeuert werden. Über die CellEditorListener sollte es auf jeden Fall klappen.

EDIT: Oh, hätte kein Kaffee holen dürfen beim Schreiben dieses Posts. Da warst du schon deutlich schneller mit der Antwort ;)
 
Zuletzt bearbeitet:

chrissy

Bekanntes Mitglied
so ... *HandgegenKopfklatsch* ... sorry für meine Dummheit.

Habe setValueAt geändert:
Java:
  public void setValueAt(Object aValue, int row, int column) 
  {
      Vector rowVector = (Vector)dataVector.elementAt(row);
      System.out.println("Change");
      rowVector.setElementAt(aValue, column);
      rowVector.setElementAt("CHANGED", 11);
      if ( column != 11 ) fireTableCellUpdated(row, column);
  }
so nun funktioniert das auch, ohne CellEditorListener ...

Aber ... ( im Moment zeig ich die Spalte ja noch an ) warum wird der Wert, wenn ich im Debug-Modus bin und einen Haltepunkt auf die erste Zeile in der Methode setze und die Zelle mit Tab verlasse sofort geändert angezeigt (nach dem weitersteppen) und wenn ich normal laufen lasse, erst wenn ich in eine andere Spalte klicke?

Danke für eure Geduld, aber nach einem Jahr Java-Pause, ist die Gehirnregion fürs Java-Programmieren fast vollstädnig abgestorben.
 

ymene

Bekanntes Mitglied
So kann man es natürlich auch lösen. Das setzt aber natürlich vorraus, dass du den TableModelListener wieder entfernt hast, sonst machst du das doppelt. Eine Kleinigkeit noch: Solltest du im moment die Spalte 11 editieren (was ja aktuell möglich ist), dann wird das Feld auch immer wieder auf "changed" gesetzt und der ursprüngliche Inhalt den man setzen wollte überschrieben. Um es ganz sauber zu haben müsstest

[JAVA=6]
rowVector.setElementAt("CHANGED", 11);
[/code]

in den If Block setzen und

[JAVA=7]
fireTableCellUpdated(row, column);
[/code]

außerhalb des If-Blocks definieren, da dies bei jeder Änderung des TableModels einmal gefeuert werden sollte. Da du es nicht mehr via setValueAt setzt wird es auch nur einmal gefeuert, trotz beider Änderungen. Auch wenn die Column später ausgeblendet werden sollte, so ist das Verhalten so konsistenter.

Das mit dem Debug Modus kann ich so leider nicht so einfach nachvollziehen. Kann ich dir leider nicht sagen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
O JTable Edit cell edit end erzwingen... AWT, Swing, JavaFX & SWT 7
Y DatenEvents in JTable bei User-Edit AWT, Swing, JavaFX & SWT 2
D JTable während edit kein update machen lassen AWT, Swing, JavaFX & SWT 2
M Swing [gelöst] JTable: Edit abstellen AWT, Swing, JavaFX & SWT 3
F JTable Java 1.6 Filtering TableRows EDIT(!) AWT, Swing, JavaFX & SWT 2
R JTable, automatisch im Edit Modus AWT, Swing, JavaFX & SWT 2
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
F Swing JTable - MultiHeader inkl. Eingabemöglichkeit AWT, Swing, JavaFX & SWT 1
S JTable - Feldinhalte anzeigen AWT, Swing, JavaFX & SWT 15
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G jTable - getSelectedRow() AWT, Swing, JavaFX & SWT 3
I JTable mit einem Button zu einer Detail Seite springen AWT, Swing, JavaFX & SWT 4
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
P Checkboxes in JTable nicht editable AWT, Swing, JavaFX & SWT 9
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Kohl Jedes Objekt einer JTable um ein Zeichen verkürzen AWT, Swing, JavaFX & SWT 7
I JTable, DefaultTableModel, zwei Zahlen multiplizieren. AWT, Swing, JavaFX & SWT 26
M JTABLE / wie oft wurde gewürfelt. AWT, Swing, JavaFX & SWT 1
F JTable vergrößern AWT, Swing, JavaFX & SWT 2
H JTable: Diverse NullPointer-Exceptions zur Laufzeit AWT, Swing, JavaFX & SWT 3
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
B JTable Zellen zusammenfügen AWT, Swing, JavaFX & SWT 3
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
H JTable im JSplitPane darstellen AWT, Swing, JavaFX & SWT 2
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
D Zeilenumbruch in einer JTable AWT, Swing, JavaFX & SWT 9
R Swing JTable und Spaltenausrichtung AWT, Swing, JavaFX & SWT 8
G JTable füllen AWT, Swing, JavaFX & SWT 1
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J Datensatz in jTable ausgeben AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JTable aktualisieren AWT, Swing, JavaFX & SWT 5
adiko01 JTable: Nur markierte Zeilen aus der Tabelle in CSV exportiern AWT, Swing, JavaFX & SWT 9
M JTable.setDefaultRenderer(...) greift nicht AWT, Swing, JavaFX & SWT 0
J JTable: Eingabe in Tabellenzelle korrigieren AWT, Swing, JavaFX & SWT 4
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
D MySQL Daten in JTable anzeigen AWT, Swing, JavaFX & SWT 2
H Swing Jtable extra spalte AWT, Swing, JavaFX & SWT 6
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
S Swing Mal wieder JTable Ansicht aktualisieren AWT, Swing, JavaFX & SWT 10
A JTable mit Daten füllen AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
N AWT jTable CellRenderer AWT, Swing, JavaFX & SWT 6
T Swing JTable valueChanged datensatz löschen AWT, Swing, JavaFX & SWT 1
0 Swing JTable aus anderer Klasse updaten AWT, Swing, JavaFX & SWT 5
S Jtable defaultRenderer wohin damit ? AWT, Swing, JavaFX & SWT 23
T Swing JTable / FocusListener AWT, Swing, JavaFX & SWT 0
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
T Swing Double Click bei Buttons in JTable AWT, Swing, JavaFX & SWT 9
J addRow bei JTable AWT, Swing, JavaFX & SWT 6
M Jtable gibt -1 wert bei selectedRow und Column AWT, Swing, JavaFX & SWT 3
Meeresgott Swing JTable AWT, Swing, JavaFX & SWT 4
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
B Swing JTable sortieren AWT, Swing, JavaFX & SWT 2
T Swing JTable auslesen und befüllen AWT, Swing, JavaFX & SWT 8
B JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
J JTable und Suchlogik AWT, Swing, JavaFX & SWT 4
Viktim Swing JTable mit Tab verlassen AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
Viktim Swing JTable Mit Tab druch Zeilen Wechseln AWT, Swing, JavaFX & SWT 5
Thallius Warum refrehsed mein JTable nicht? AWT, Swing, JavaFX & SWT 5
Ghostman1711 Hinzufügen ausgewählter Dateinen des Filechoosers zu einem JTable AWT, Swing, JavaFX & SWT 9
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
K JTable getValueAt() klappt nicht immer AWT, Swing, JavaFX & SWT 1
K JTable in extra Klasse, Zugriff in einer anderen klasse nicht möglich AWT, Swing, JavaFX & SWT 26
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
P JTable - bei Eingabe Selektion AWT, Swing, JavaFX & SWT 0
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
S Swing Deselektion in JTable verhindern AWT, Swing, JavaFX & SWT 0
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
N Swing Print JTable mit AbstractTableModel AWT, Swing, JavaFX & SWT 1
Ananaskirsche Swing jTable Reihen zuviel eingefügt AWT, Swing, JavaFX & SWT 12
P im JTable die Schriftfarbe ändern AWT, Swing, JavaFX & SWT 19
T Swing JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Dreiecke in bestimmte Zellen einer JTable AWT, Swing, JavaFX & SWT 9
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
D Swing JTable Renderer Grafikfehler AWT, Swing, JavaFX & SWT 0
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1
M Swing JTable GroupableHeader Background Color AWT, Swing, JavaFX & SWT 4
K Swing JTable updaten AWT, Swing, JavaFX & SWT 9
thet1983 Swing MySQL >> JTable AWT, Swing, JavaFX & SWT 5
J JTable bounds ändern durch resizing des Fensters AWT, Swing, JavaFX & SWT 9
F JTable Zellen-Hintergrund ändern AWT, Swing, JavaFX & SWT 7
O JTable linksbündig drucken (nicht der Zelleninhalt) AWT, Swing, JavaFX & SWT 2
Crazynet xls Datei in JTable AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben