Lösungsansatz manuelle Werteeingabe JTable

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo zusammen,

ich habe folgendes Problem und möchte euren Rat dazu wissen:

Ich habe eine JTable, die mit einer Entität geladen wird. Dazu habe ich zu zwei der Attribute Änderungsspalten hinzugefügt., wobei die Werte der Änderungsspalten zu dem jeweiligen Attribut addiert werden.
Die Entität beinhaltet folgende Attribute:
- Jahr
- Urlaubstage
- Urlaubstage altes Jahr
- Resttage
- Überstunden
- Übertrag Überstunden
- Sonderurlaub

Die Änderungsspalten:
- Änderung Urlaubstage
- Änderung Überstunden

Die Tabelle beinhaltet also folgende Spalten (in der Reihenfolge sortiert):
- Jahr
- Urlaubstage
- Änderung Urlaubstage
- Urlaubstage altes Jahr
- Resttage
- Überstunden
- Änderung Überstunden
- Übertrag Überstunden
- Sonderurlaub

Wenn ich nun auf einen Button klicke, dann sollen die editierten Werte in das Model (DefaultTableModel) der Tabelle an der richtigen Stelle übernommen werden (die Zellenwerte des Models der Tabelle in den Änderungsspalten sind null).

Mein bisheriger Lösungsansatz war, mir ein eigenes TableModel zu erstellen. Dabei stellt sich für mich folgendes Problem:
Mein Model beinhaltet zwei Arten von Datensätzen: Zum einen die Entität selber, zum anderen die ArrayList's für die Änderungsspalten. Ist dies so einfach handhabbar? Oder gibt es einen besseren Ansatz?
Hier mein bisheriges Model:
Code:
package de.cnm.zeitstempel.common;

import java.util.ArrayList;
import java.util.Vector;

import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class Model implements TableModel
{
  private Vector annualStatistics = new Vector<String>();

  private Vector listeners = new Vector();

  private ArrayList<String> changeDays = new ArrayList<String>();

  private ArrayList<String> changeWorkingTime = new ArrayList<String>();

  public void addStatistic(AnnualStatistics statistic)
  {
    int index = annualStatistics.size();
    annualStatistics.add(statistic);
  }
  
  public void addChangeDays(String changeDay)
  {
    changeDays.add(changeDay);
  }
  
  public void addChangeWorkingTime(String changeWorkingTime)
  {
    this.changeWorkingTime.add(changeWorkingTime);
  }
  
  // Die Anzahl Columns
  public int getColumnCount()
  {
    return 9;
  }

  // Die Anzahl der Jahresstatistiken
  public int getRowCount()
  {
    return annualStatistics.size();
  }

  // Die Titel der einzelnen Columns
  public String getColumnName(int column)
  {
    switch (column)
    {
    case 0:
      return "Jahr";
    case 1:
      return "U";
    case 2:
      return "Änderung Urlaubstage";
    case 3:
      return "RT";
    case 4:
      return "Üb U";
    case 5:
      return "ÜS";
    case 6:
      return "Änderung Überstunden";
    case 7:
      return "Üb ÜS";
    case 8:
      return "SU";
    default:
      return null;
    }
  }

  // Der Wert der Zelle (rowIndex, columnIndex)
  public Object getValueAt(int rowIndex, int columnIndex)
  {
    AnnualStatistics statistic = (AnnualStatistics) annualStatistics
        .get(rowIndex);

    switch (columnIndex)
    {
    case 0:
      return statistic.getYear();
    case 1:
      return statistic.getHolidays();
    case 2:
      return changeDays.get(rowIndex);
    case 3:
      return statistic.getTakenHolidays();
    case 4:
      return statistic.getAmountHolidaysOldYear();
    case 5:
      return statistic.getOvertime();
    case 6:
      return changeWorkingTime.get(rowIndex);
    case 7:
      return statistic.getOverTimeOldYear();
    case 8:
      return statistic.getSpecialHolidays();
    default:
      return null;
    }
  }

  // Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
  public Class getColumnClass(int columnIndex)
  {
    switch (columnIndex)
    {
    case 0:
      return Integer.class;
    case 1:
      return Integer.class;
    case 2:
      return String.class;
    case 3:
      return Integer.class;
    case 4:
      return Integer.class;
    case 5:
      return String.class;
    case 6:
      return String.class;
    case 7:
      return String.class;
    case 8:
      return Integer.class;
    default:
      return null;
    }
  }

  public void addTableModelListener(TableModelListener l)
  {
    listeners.add(l);
  }

  public void removeTableModelListener(TableModelListener l)
  {
    listeners.remove(l);
  }

  public boolean isCellEditable(int rowIndex, int columnIndex)
  {
    switch (columnIndex)
    {
    case 2:
      return true;
    case 6:
      return true;
    default:
      return false;
    }
  }

  // Wird von der JTable aufgerufen, falls in eine Zelle ein neuer Wert gesetzt
  // werden soll
  public void setValueAt(Object aValue, int rowIndex, int columnIndex)
  {
    AnnualStatistics statistic = (AnnualStatistics) annualStatistics
        .get(rowIndex);
    switch (columnIndex)
    {
    case 2:
      changeDays.set(rowIndex, (String) aValue);
    case 6:
      changeWorkingTime.set(rowIndex, (String) aValue);
    }
  }

}
 
G

Guest

Gast
Das eigene TableModel funktioniert so wie es soll, allerdings frage ich mich, wie ich den bzw. die editierten Werte in das Model bekommen kann. Der Benutzer kann zwar die richtigen Felder editieren, die Datenänderungen werden jedoch nicht übernommen.
 
G

Guest

Gast
Meine Klasse sieht nun so aus:
Code:
package de.cnm.zeitstempel.common;

import java.util.ArrayList;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

public class UserSettingsTableModel extends AbstractTableModel
{
  private Vector annualStatistics = new Vector<String>();

  private Vector listeners = new Vector();

  private ArrayList<String> changeDays = new ArrayList<String>();

  private ArrayList<String> changeWorkingTime = new ArrayList<String>();

  public void addStatistic(AnnualStatistics statistic)
  {
    int index = annualStatistics.size();
    annualStatistics.add(statistic);
  }

  public void addChangeDays(String changeDay)
  {
    changeDays.add(changeDay);
  }

  public void addChangeWorkingTime(String changeWorkingTime)
  {
    this.changeWorkingTime.add(changeWorkingTime);
  }

  // Die Anzahl Columns
  public int getColumnCount()
  {
    return 9;
  }

  // Die Anzahl der Jahresstatistiken
  public int getRowCount()
  {
    return annualStatistics.size();
  }

  // Die Titel der einzelnen Columns
  public String getColumnName(int column)
  {
    switch (column)
    {
    case 0:
      return "Jahr";
    case 1:
      return "U";
    case 2:
      return "Änderung Urlaubstage";
    case 3:
      return "RT";
    case 4:
      return "Üb U";
    case 5:
      return "ÜS";
    case 6:
      return "Änderung Überstunden";
    case 7:
      return "Üb ÜS";
    case 8:
      return "SU";
    default:
      return null;
    }
  }

  // Der Wert der Zelle (rowIndex, columnIndex)
  public Object getValueAt(int rowIndex, int columnIndex)
  {
    AnnualStatistics statistic = (AnnualStatistics) annualStatistics
        .get(rowIndex);

    switch (columnIndex)
    {
    case 0:
      return statistic.getYear();
    case 1:
      return statistic.getHolidays();
    case 2:
      return changeDays.get(rowIndex);
    case 3:
      return statistic.getTakenHolidays();
    case 4:
      return statistic.getAmountHolidaysOldYear();
    case 5:
      return statistic.getOvertime();
    case 6:
      return changeWorkingTime.get(rowIndex);
    case 7:
      return statistic.getOverTimeOldYear();
    case 8:
      return statistic.getSpecialHolidays();
    default:
      return null;
    }
  }

  // Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
  public Class getColumnClass(int columnIndex)
  {
    switch (columnIndex)
    {
    case 0:
      return Integer.class;
    case 1:
      return Integer.class;
    case 2:
      return String.class;
    case 3:
      return Integer.class;
    case 4:
      return Integer.class;
    case 5:
      return String.class;
    case 6:
      return String.class;
    case 7:
      return String.class;
    case 8:
      return Integer.class;
    default:
      return null;
    }
  }

  public boolean isCellEditable(int rowIndex, int columnIndex)
  {
    switch (columnIndex)
    {
    case 2:
      return true;
    case 6:
      return true;
    default:
      return false;
    }
  }

  // Wird von der JTable aufgerufen, falls in eine Zelle ein neuer Wert gesetzt
  // werden soll
  public void setValueAt(Object aValue, int rowIndex, int columnIndex)
  {
    if (columnIndex == 2 || columnIndex == 6)
    {
      if (columnIndex == 2)
      {
        changeDays.set(rowIndex, (String) aValue);
      }
      if (columnIndex == 6)
      {
        changeWorkingTime.set(rowIndex, (String) aValue);
      }
      fireTableCellUpdated(rowIndex, columnIndex);
    }
  }
}

Allerdings wird die setValueAt-Methode nicht aufgerufen, wenn der Benutzer einen neuen Wert in die Zelle einfügt. Somit wird der neue Wert im Model nicht verändert. Muss da noch ein TableModelEvent eingefügt werden? Ich habe im Moment leider keinen Anhaltspunkt, wie man so etwas lösen könnte.
 
G

Guest

Gast
Die Methode setValueAt wird erst aufgerufen, wenn die Zelle verlassen wird. Angenommen der Benutzer ändert nur einen Wert in der Zelle und klickt sofort auf den Button, dann wird die Zelle nicht verlassen, es muss jedoch die Änderung trotzdem erfolgen. Ist dies durch einen Listener zu regeln?
 

André Uhres

Top Contributor
Versuch mal, nach dem Erzeugen der JTable diese Property zu setzen:
Code:
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben