# Eigenes TableModel für ArrayList<String[]>



## expensne (26. Aug 2014)

Hallo Leute,

hab mal eine Frage zu meinem TableModel. 
Ich brauche ein Table das eine ArrayList mit String[] als Zeilen einliest, dafür habe ich nun versucht ein eigenes TableModel zu erstellen, allerdings füllt sich die Tabelle zwar mit leeren Zeilen wenn ich Daten adde, aber es sind halt nur leere Zeilen ohne Inhalt.


Habt ihr vielleicht eine Idee wo der Fehler liegt (bin Anfänger, kann also auch ein ziemlich grober Schnitzer sein :rtfm
Hier ein Ausschnitt des TableModel Code:


```
public class STableModel extends AbstractTableModel {

    private ArrayList rowList;
    private String[] headers = {"Benutzer","Account"};
    
    public STableModel(ArrayList data) {
        rowList = data;
    }

[...]

}
```


Und hier das Erstellen der JTable:


```
public final class Hauptfenster {

ArrayList dataList = new ArrayList();

    public Hauptfenster() {
        
        dataList.add(new String[] {"1", "2"});
        dataList.add(new String[] {"1", "2"});

        STableModel test = new STableModel(dataList);
        final JTable table = new JTable(test);

        final JScrollPane scrollingTable = new JScrollPane(table,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

      frame.add(scrollingTable);
}

[...]

}
```


Mfg
Fabian


----------



## turtle (26. Aug 2014)

Also grundsäzlich solltest auf das Interface List wechseln und dann EINE Implementierung wählen. So ist es besserer Stil.
Also

```
List<String> listStrings = new ArrayList<>();
```
Hier mal mein AbstractTableModel für Daten die aus zwei Strings bestehen.


```
class MeinTableModel extends AbstractTableModel {
	private List<Daten> listDaten;
	private List<String> listColumns;

	public MeinTableModel(List<Daten> daten) {
		this.listDaten = new ArrayList<Daten>();
		for (Daten datenSatz : daten) {
			listDaten.add(datenSatz);
		}
		listColumns = new ArrayList<String>();
		listColumns.add("Benutzer");
		listColumns.add("Account");

	}

	public List<Daten> getListDaten() {
		return listDaten;
	}

	public void addiereNeueDaten(List<Daten> neueDaten) {
		for (Daten daten : neueDaten) {
			listDaten.add(daten);
		}
		fireTableStructureChanged();
	}

	@Override
	public int getRowCount() {
		return listDaten.size();
	}

	public Class<?> getColumnClass(int columnIndex) {
		switch (columnIndex) {
		case 0:
			return String.class;
		case 1:
			return String.class;
		}
		return null;
	}

	@Override
	public int getColumnCount() {
		return listColumns.size();
	}

	public String getColumnName(int column) {
		return listColumns.get(column);
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Daten daten = listDaten.get(rowIndex);
		if (daten != null) {
			switch (columnIndex) {
			case 0:
				return daten.getBenutzer();
			case 1:
				return daten.getAccount();
			}
		}
		return null;
	}

class Daten {
	private String benutzer;
	private String account;

	public Daten(String benutzer, String account) {
		this.benutzer = benutzer;
		this.account = account;
	}

	public String getBenutzer() {
		return benutzer;
	}

	public void setBenutzer(String benutzer) {
		this.benutzer = benutzer;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

}
}
```


----------



## expensne (26. Aug 2014)

Danke sehr, klappt! 

Edit:

Eine Frage noch, wie bekomm ich es nun hin das es sich auch aktualisiert? (ohne die oben erstellte addiereNeueDaten Methode zu nutzen)
Habe folgendes:


```
public void addUserData(String acc, String user, String pass) {

        dataList.add(new Daten(acc, user, pass));
        test.fireTableStructureChanged();
}
```

Allerdings aktualisiert sich nichts.


----------



## Harry Kane (27. Aug 2014)

Da du die gepostete Methode völlig aus dem Zusammenhang gerissen hast, kann man nur vermuten, was passiert:
Die addUserData Methode gehört zu deinem Hauptfenster, und die Daten werden zu deren dataList Objekt hinzugefügt.
Das Objekt, was dein TableModel verwendet, ist jedoch eine andere ArrayList. Sie wurde zwar mal als Kopie aus dem dataList Objekt erstellt, hat danach aber nix mehr damit zu tun.
Mache es so wie turtle und füge die Daten direkt dem TableModel hinzu.
Zu deinem obigen Post noch folgender Hinweis: Wenn in deiner JTable nicht die Daten erscheinen, die du erwartet, solltest du auf jeden Fall die getValueAt(int row, int column) Methode deines TableModels posten. Hast du ernsthaft erwartet, daß jemand anhand deines Codeschnipsels sagen kann, warum keine Daten erscheinen?


----------



## turtle (27. Aug 2014)

Ich zeige dir mal mein Demo-Programm zum Thema JTable

Hier werden über den Button Add/Reload jedesmal 10 neue Einträge hinzugefügt und die JTable aktualisiert.

```
package jtable;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

@SuppressWarnings("serial")
public class Table extends JPanel {
	private MeinTableModel tableModel;
	private List<Daten> listDaten;
	private JTable table;
	private JButton btnAdd;
	private Random random = new Random();
	private TableRowSorter<TableModel> sorter;
	private JScrollPane scrollPane;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Table() {
		setLayout(new BorderLayout());
		// @formatter:off
        Daten[] memoryDaten = new Daten[] { 
            new Daten("Turtle", 20, false,"1.1.1993"),
            new Daten("Andreas", 10, false,"10.5.2003"),
            new Daten("Bärbel", 30, true,"20.02.1986"),
            new Daten("Christian", 40, false,"11.11.1980"),
            new Daten("Doris", 50, false,"22.02.1970"),
            new Daten("Emil", 66, true,"7.2.1966"),
            new Daten("Franziska", 70, true,"12.9.1955"),
            new Daten("Gerhard", 30, false,"16.08.1983"),
            new Daten("Heike", 33, false,"17.08.1986"),
            new Daten("Ingo", 22, false,"30.12.1992"),
        };
        listDaten = new ArrayList<>();
        for (Daten daten : memoryDaten) {
			listDaten.add(daten);
		}
        // @formatter:on
		listDaten = Arrays.asList(memoryDaten);
		tableModel = new MeinTableModel(listDaten);
		table = new JTable(tableModel);
		sorter = new TableRowSorter<>(tableModel);
		RowFilter ageFilter = new RowFilter<MeinTableModel, Integer>() {

			@Override
			public boolean include(javax.swing.RowFilter.Entry<? extends MeinTableModel, ? extends Integer> entry) {
				MeinTableModel model = entry.getModel();
				int row = entry.getIdentifier();
				int alter = (int) model.getValueAt(row, 1);
				if (alter < 30) { return true; }
				return false;
			}

		};
		RowFilter nameFilter = new RowFilter<MeinTableModel, Integer>() {
			@Override
			public boolean include(javax.swing.RowFilter.Entry<? extends MeinTableModel, ? extends Integer> entry) {
				MeinTableModel model = entry.getModel();
				int row = entry.getIdentifier();
				String name = (String) model.getValueAt(row, 0);
				if (name.contains("n")) { return true; }
				return false;
			}

		};
		java.util.List<RowFilter<Object, Object>> allFilter = new ArrayList<RowFilter<Object, Object>>();
		allFilter.add(ageFilter); // Turtle, Andreas, Ingo
		allFilter.add(nameFilter); // Andreas, Christian, Franziska, Ingo
		RowFilter<Object, Object> bothFilterAnded = RowFilter.andFilter(allFilter);
		sorter.setRowFilter(bothFilterAnded); // Andreas, Ingo
		// table.setRowSorter(sorter);
		// table.setAutoCreateRowSorter(true);
		btnAdd = new JButton("Add/Reload");
		btnAdd.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				table.scrollRectToVisible(table.getCellRect(table.getRowCount() - 1, 0, true));

				int suffix = random.nextInt(10);
				// @formatter:off
				Daten[] neueDaten = new Daten[] { 
            new Daten("Turtle-"+suffix, 20, false, "1.1.1993"), 
            new Daten("Andreas-"+suffix, 10, false, "10.5.2003"),
            new Daten("Bärbel-"+suffix, 30, true, "20.02.1988"), 
            new Daten("Christian-"+suffix, 40, false, "11.11.1980"),
            new Daten("Doris-"+suffix, 50, false, "22.02.1970"), 
            new Daten("Emil-"+suffix, 66, true, "7.2.1966"),
            new Daten("Franziska-"+suffix, 70, true, "12.9.1955"), 
            new Daten("Gerhard-"+suffix, 30, false, "16.08.1983"),
            new Daten("Heike-"+suffix, 33, false, "17.08.1986"), 
            new Daten("Ingo-"+suffix, 22, false, "30.12.1992"), };
        // @formatter:on
				List<Daten> neuDaten = Arrays.asList(neueDaten);
				tableModel.addiereNeueDaten(neuDaten);

			}
		});
		scrollPane = new JScrollPane(table);
		add(scrollPane, BorderLayout.CENTER);
		add(btnAdd, BorderLayout.SOUTH);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Table Test");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(new Table());
		frame.pack();
		frame.setVisible(true);
	}
}

@SuppressWarnings("serial")
class MeinTableModel extends AbstractTableModel {
	private List<Daten> listDaten;
	private List<String> listColumns;

	public MeinTableModel(List<Daten> daten) {
		this.listDaten = new ArrayList<Daten>();
		for (Daten datenSatz : daten) {
			listDaten.add(datenSatz);
		}
		listColumns = new ArrayList<String>();
		listColumns.add("Name");
		listColumns.add("Alter");
		listColumns.add("Rentner");
		listColumns.add("Geburtstag");

	}

	public List<Daten> getListDaten() {
		return listDaten;
	}

	public void addiereNeueDaten(List<Daten> neueDaten) {
		for (Daten daten : neueDaten) {
			listDaten.add(daten);
		}
		fireTableStructureChanged();
	}

	@Override
	public int getRowCount() {
		return listDaten.size();
	}

	public Class<?> getColumnClass(int columnIndex) {
		switch (columnIndex) {
		case 0:
			return String.class;
		case 1:
			return Integer.class;
		case 2:
			return Boolean.class;
		case 3:
			return Date.class;
		}
		return null;
	}

	@Override
	public int getColumnCount() {
		return listColumns.size();
	}

	public String getColumnName(int column) {
		return listColumns.get(column);
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		Daten daten = listDaten.get(rowIndex);
		if (daten != null) {
			switch (columnIndex) {
			case 0:
				return daten.getName();
			case 1:
				return daten.getAlter();
			case 2:
				return daten.isRentner();
			case 3:
				return daten.getGeburtstag();
			}
		}
		return null;
	}
}

class Daten {
	private String name;
	private Boolean rentner;
	private Date geburtstag;
	private Integer alter;
	private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");

	public Daten(String name, Integer alter, Boolean rentner, String geb) {
		try {
			this.name = name;
			this.alter = alter;
			this.rentner = rentner;
			this.geburtstag = sdf.parse(geb);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Boolean isRentner() {
		return rentner;
	}

	public void setRentner(Boolean rentner) {
		this.rentner = rentner;
	}

	public Date getGeburtstag() {
		return geburtstag;
	}

	public void setGeburtstag(Date geburtstag) {
		this.geburtstag = geburtstag;
	}

	public int getAlter() {
		return alter;
	}

	public void setAlter(Integer alter) {
		this.alter = alter;
	}
}
```
Das mit den ageFilter bzw. nameFilter ist einkommentiert, weil es "nur" zeigen soll, wie die Anzeige gefiltert werden kann.


----------



## expensne (27. Aug 2014)

Danke Leute, klappt jetzt!


----------

