Tabellenähnliche Darstellung

Fitzi21

Aktives Mitglied
Hallo,

Zur Ausgangssituation:
Ich habe eine Access Datenbank Tabelle. Diese Tabelle habe ich ausgelesen und in einer ArrayList gespeichert.

Nun möchte ich diese ArrayList wieder ausgeben, in einer Tabellenform, z. B. so:
Bild siehe Anhang!


Wie man aber sieht, ist da alles Verschoben. Grund hierfür ist, dass ich jeweils nur die Attribute ausgegeben habe und diese durch einen Tabulator getrennt habe.


Wie ist es möglich, den Abstand überall gleich zu machen, ohne dass sich alles verschiebt ?
Es geht nicht um die absolute perfektionierte Programmierkunst. Wenn es andere Wege gibt, wie die JTable würde ich das gerne machen, da das doch ziemlich kompliziert ist mit kleinem Basis Wissen und die Zeit sehr knapp ist.


Vielen Dank für eure Hilfe

Liebe Grüße Fitzi


PS: Außer unserem Lehrer wird nie jemand das Programm zu Gesicht bekommen 😉
 

Anhänge

  • mitglieder.jpg
    mitglieder.jpg
    77,6 KB · Aufrufe: 58
Zuletzt bearbeitet von einem Moderator:
Am Besten wäre es tasachlich über eine JTabel aber wenn du dies nicht möchtest kannst du es ja so machen wie du es bisher hast, nur dass du dir zum Formatieren des Strings noch String.format() ansehen solltest. Da kannst du dann Sachen einstellen wie etwa wieviele Zeichen du pro Spalte haben möchtest.

Ansonsten würd wahrscheinlich auch ein GridLayout mit JLabel gehen, das ist aber furchtbar hässlich und hab ich jetzt eher nur erwähnt weil es machbar wäre und nicht weil du es machen solltest.
 
Zuletzt bearbeitet:
Schau dir mal JTable und TableModel an.

Wenn du das nicht willst kannst du auch wie schon vorgeschlagen String.format() verwenden, da kann man angeben, wie viel Platz pro String reserviert werden soll, also praktisch spaltenweise aufteilen.
Probleme dabei gibts aber wenn der String länger als der Platzhalter ist, dan verschiebt sich wieder alles.
 
Hallo,

schau dir mal diese Themen an:
http://www.java-forum.org/java-basics-anfaenger-themen/102137-problem-listcellrenderer-fuer-jpanel.html
http://www.java-forum.org/awt-swing-swt/102014-jlist-jspinner.html

Da sind einige Beispiele, wie man mit den ListCellRenderer umgeht. Ist aber teilweise nicht so einfach und kann schnell kompliziert werden.

Wenn du nur einfachen Text ohne Besonderheiten darstellen willst, dann ist eine JTable evtl. doch einfacher, als eine JList wie eine Tabelle aussehen zu lassen.

MfG
hansmueller
 
Hallo,

ich habe mich nun mal an der format() - Methode versucht und bin kläglich gescheitert. Es hat leider etwas länger gedauert aber mit ausgekugelter Schulter ging leider nichts 🙁
Das ist alles irgendwie ziemlich verwirrend, genau wie mein nicht funktionierendes Ergebnis (wie zu erwarten war) 😀

Java:
	public void alleMitgliederAusgeben()
	{
		for(int i=0; i<alleMitgliederMitgliedsnummer.size(); i++)
		{
			String a = alleMitgliederMitgliedsnummer.get(i).getMitgliedsNr();
			String b = alleMitgliederMitgliedsnummer.get(i).getNachname();
			String c = alleMitgliederMitgliedsnummer.get(i).getVorname();
			String d = alleMitgliederMitgliedsnummer.get(i).getWohnort();
			String e = alleMitgliederMitgliedsnummer.get(i).getStraße();
			String f = alleMitgliederMitgliedsnummer.get(i).getGeburtsdatum();
			String g = alleMitgliederMitgliedsnummer.get(i).getMitgliedsstatus();
			String h = alleMitgliederMitgliedsnummer.get(i).getEintrittsdatum();
			String j = alleMitgliederMitgliedsnummer.get(i).getInstrument();
			taMitglieder.append(String.format("|%-8a|%n", a) + String.format("|%-25a|%n", a) + String.format("|%-25b|%n", b) + String.format("|%-50c|%n", c) + String.format("|%-50d|%n", d) + String.format("|%-20d|%n", e) + String.format("|%-30f|%n", f) + String.format("|%-30g|%n", g) + String.format("|%-30h|%n", h) + String.format("|%-30j|%n", j) + "\n");
			//taMitglieder.append(alleMitgliederMitgliedsnummer.get(i).getMitgliedsNr() + "	" + alleMitgliederMitgliedsnummer.get(i).getNachname() + "	" + alleMitgliederMitgliedsnummer.get(i).getVorname() + "	" + alleMitgliederMitgliedsnummer.get(i).getWohnort() + "	" + alleMitgliederMitgliedsnummer.get(i).getStraße() + "	" + alleMitgliederMitgliedsnummer.get(i).getGeburtsdatum() + "	" + alleMitgliederMitgliedsnummer.get(i).getMitgliedsstatus() + "	" + alleMitgliederMitgliedsnummer.get(i).getEintrittsdatum() + "	" + alleMitgliederMitgliedsnummer.get(i).getInstrument() +"\n");
		}
	}

Mit dem auskommentierten Code kam ich zu dem obigen Ergebnis (siehe Bild).
Beim neuen Versuch mit format() kommt garnichts mehr außer einer Fehlermeldung.

Ich wäre super dankbar, wenn jemand das gerade biegen könnte und das entsprechend kurz erklärt. Bei der Online Variante von Java ist eine Insel habe ich immer das Gefühl, das mit die Basis fehlt. Wenn man noch keine Erfahrungen mit anderen Sprachen hatte geht das ziemlich steil los ^^

Vielen Dank

Gruß Fitzi
 
JTables sind die wohl schwierigsten Swing-Komponenten überhaupt, ich würde dir abraten welche zu verwenden, wenn es nicht umbedingt sein muss.
Eine weitere Möglichkeit wären Boxen. Zwar sicher nicht so schön wie ein JTable, aber sehr viel einfacher zu realisieren, wenn man nicht direkt Werte verändern möchte. Und das geht offenbar bei dir eh über einen Button und dementsprechend ein eigenes Menü. Bin gerade beim editieren, hatte dabei selbst eine JTable, die mir aber einfach viel zu kompliziert wurde, deshalb habe ich auf Boxen umgebaut. Aber derzeit ist noch einiges da drinnen durcheinander. Nimm einfach raus, was du brauchen kannst, bins mal überflogen und habe alles entfernt, wo ich sicher war, das es nicht gebraucht wird.

#1747123 - Pastie
(Wegen der Größe ausgelagert)
 
Hey Volvagia,

danke für deine Antwort.
Du hast mir von der JTable abgeraten, weil diese sehr komplex ist.
Das hatte ich auch schon gelesen und daher gedacht, dass ich diese lieber mal umgehe.

In der format() Methode sehe ich für meine Zwecke eine sehr gute Lösung. Daher würde ich dies auch gerne so machen, allerdings wie man oben sieht hatte ich wenig Erfolg dabei.

Wenn ich jetzt Boxen nehme, wie du in deinem Beispiel hast, dann kommt wieder etwas mir bislang völlig unbekanntes dazu. Dabei muss ich erst mal die Sachen verstehen, die ich angefangen habe --> format()

Aber nochmal auch dir vielen Dank 🙂

Liebe Grüße
Fitzi
 
Schau mal das an:

Java:
public static void main(String [] args)
{
	String formatString = "%s\t%s\t%s\n";
	String[][] data = {
			new String[] { "0001", "Fritz", "Karl" },
			new String[] { "0002", "Ballermann", "Frank" }	
    	};
    	
    	
	StringBuilder input = new StringBuilder();
	input.append(String.format(formatString, data[0][1], data[0][1], data[0][2]));
	input.append(String.format(formatString, data[1][0], data[1][2], data[1][2]));
	
	JFrame frame = new JFrame();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	JTextArea area = new JTextArea(input.toString());
	area.setEditable(false);
	frame.add(area);
	frame.pack();
	frame.setVisible(true);
}

%s werden der Reihe nach, durch die Strings, die übergeben werden ersetzt, \t ist ein Tabulator, und \n ein Zeilenumbruch.
 
Schau mal das an:
...
%s werden der Reihe nach, durch die Strings, die übergeben werden ersetzt, \t ist ein Tabulator, und \n ein Zeilenumbruch.


Womit er genau die Ausgabe hinbekommen würde, die er jetzt schon hat. ;o)

Fitzi21 hat gesagt.:
Wie man aber sieht, ist da alles Verschoben. Grund hierfür ist, dass ich jeweils nur die Attribute ausgegeben habe und diese durch einen Tabulator getrennt habe.
 
Hallo Fritz,

hier mal ein Beispiel zur Verdeutlichung:

Java:
public class Main {

    public static void main(String[] args) {
        out("1",     "Fritz",      "Mustermann", "10010",   "Musterstadt");
        out("22",    "Hans",       "Pohl",       "D-10101", "Dorfstadt");
        out("33",    "Markus",     "Ballermann", "1234",    "Überlingen");
        out("444",   "Volker",     "Kramer",     "",        "Oberlingen");
        out("66666", "Adrian",     "Lutz",       "10015",   "Gerg");
        out("5555",  "Karl Heinz", "Meier",      "123",     "Winkelzug");
    }

    public static void out(String s1, String s2, String s3, String s4, String s5) {
        // Format-String mit Längenangaben plus einem Leerzeichen zwischen den Spalten...
        String form = "%8s %-8s %-20s %-10s %-10s";
        System.out.println(String.format(form, s1 , s2, s3, s4, s5));
    }

}

Das "Minus" erzeugt eine linksbündige Ausrichtung.

Das Beispiel erzeugt die folgende Ausgabe:

Code:
       1 Fritz    Mustermann           10010      Musterstadt
      22 Hans     Pohl                 D-10101    Dorfstadt 
      33 Markus   Ballermann           1234       Überlingen
     444 Volker   Kramer                          Oberlingen
   66666 Adrian   Lutz                 10015      Gerg      
    5555 Karl Heinz Meier                123        Winkelzug

Wie Du in der letzten Zeile siehst, verspringt auch da die
Ausgabe ab Spalte 3.

Du musst also selbst dafür sorgen, dass im Format-String der Wert
für die Spaltenbreite >= der längsten Zeichenkette der jeweiligen
Spalte ist, um dies zu verhindern. Hätte ich im Format-String "form"
den Wert für Spalte 2 von "%-8s" in "%-10s" geändert, hätte in diesem
Beispiel die Ausgabe gepasst.

Ich hoffe, das hilft Dir weiter.

VG ROlf
 
Upsi. 😳
Zur Automatisierung gäbe es noch diese Möglichkeit:

Java:
public static void main(String [] args)
{
	String[][] data = {
			new String[] { "0001", "Fritz", "Karl" },
			new String[] { "0002", "Ballermann", "Frank" }	
    	};

	JTextArea area = new JTextArea();
	area.setEditable(false);
	Font f = area.getFont(); //TODO
	area.setFont(f);
	
	FontMetrics metrics = area.getFontMetrics(f);
	int[] needingTabWidth = compMaxColumnWidth(data, metrics);
	String space = " ";
	int spaceWidth = metrics.stringWidth(space);
    
    StringBuilder input = new StringBuilder();
	for(int i = 0; i < data.length; i++)
	{
		for(int j = 0; j < data[0].length; j++)
		{
			String dataString = data[i][j];
			int thisStringWidth = metrics.stringWidth(dataString);
			input.append(dataString);

			for(int k = 0; k < (needingTabWidth[j] - thisStringWidth) / spaceWidth; k++)
				input.append(space);
		}
		input.append(System.getProperty("line.separator"));
	}
    area.setText(input.toString());
    
	JFrame frame = new JFrame();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.add(area);
	frame.pack();
	frame.setVisible(true);
}
private static int[] compMaxColumnWidth(String[][] data, FontMetrics metrics)
{
	int[] needingTabWidth = new int[data[0].length];

	for(int i = 0; i < data[0].length; i++)
	{
		int width = 0;
		for(int j = 0; j < data.length; j++)
		{
			String dataString = data[j][i];
			width = Math.max(width, metrics.stringWidth(dataString));
		}
		needingTabWidth[i] = width + 10;
	}
	return(needingTabWidth);
}
 
;-)

Upsi. 😳
Zur Automatisierung gäbe es noch diese Möglichkeit:
...

Wobei das Ganze, wie auch meine Lösung, so natürlich nur mit
nichtproportionalen Schriftarten, wie z.B. Courier funktioniert.
So würde ich das bei diesem Beispiel machen.

Bei proportionalen Schriftarten ist der Aufwand größer und damit
wahrscheinlich für die gestellte Aufgabe nicht angemessen, da es
hier anscheinend nicht vorrangig um die Ausgabe geht.

Noch ein Tipp: Sollten die Daten aus einer Datenbank stammen,
kann man bei großen Tabellen die maximale Spaltenbreite wahrscheinlich
schneller aus den Metadaten der Tabelle auslesen.

VG ROlf
 
Vielen Dank euch beiden ! 🙂

Der Code sieht jetzt so aus:
Java:
	public void alleMitgliederAusgeben()
	{
		String form = "%-6s | %-20s | %-20s | %-30s | %-30s | %-12s | %-18s | %-12s | %-20s\n";
		taMitglieder.append(String.format(form, "MitNr", "Nachname", "Vorname", "Wohnort", "Straße", "Geb.", "Mitgliedsstatus", "Eintrittssd.", "Instrument"));
		taMitglieder.append("=====================================================================================================================================================================================\n\n");

		for(int i=0; i<alleMitgliederMitgliedsnummer.size(); i++)
		{
			String s1 = alleMitgliederMitgliedsnummer.get(i).getMitgliedsNr();
			String s2 = alleMitgliederMitgliedsnummer.get(i).getNachname();
			String s3 = alleMitgliederMitgliedsnummer.get(i).getVorname();
			String s4 = alleMitgliederMitgliedsnummer.get(i).getWohnort();
			String s5 = alleMitgliederMitgliedsnummer.get(i).getStraße();
			String s6 = alleMitgliederMitgliedsnummer.get(i).getGeburtsdatum();
			String s7 = alleMitgliederMitgliedsnummer.get(i).getMitgliedsstatus();
			String s8 = alleMitgliederMitgliedsnummer.get(i).getEintrittsdatum();
			String s9 = alleMitgliederMitgliedsnummer.get(i).getInstrument();
			//taMitglieder.append(alleMitgliederMitgliedsnummer.get(i).getMitgliedsNr() + "	" + alleMitgliederMitgliedsnummer.get(i).getNachname() + "	" + alleMitgliederMitgliedsnummer.get(i).getVorname() + "	" + alleMitgliederMitgliedsnummer.get(i).getWohnort() + "	" + alleMitgliederMitgliedsnummer.get(i).getStraße() + "	" + alleMitgliederMitgliedsnummer.get(i).getGeburtsdatum() + "	" + alleMitgliederMitgliedsnummer.get(i).getMitgliedsstatus() + "	" + alleMitgliederMitgliedsnummer.get(i).getEintrittsdatum() + "	" + alleMitgliederMitgliedsnummer.get(i).getInstrument() +"\n");
			taMitglieder.append(String.format(form, s1, s2, s3, s4, s5, s6, s7, s8, s9));	
		}
	}


Die Ausgabe so:
Code:
MitNr  | Nachname             | Vorname              Wohnort                        | Straße                         | Geb.         | Mitgliedsstatus    | Eintrittssd. | Instrument          
=====================================================================================================================================================================================

0001   | Fitz                 | Karl                 88999 Ballerman                | Markdorferstraße 999           | 1991-07-21   | aktiv              | 2005-08-01   | Tenorhorn           
0002   | Ballermann           | Frank                77777 Waldmannsheil            | Seeweg 7                       | 1968-05-01   | Ehrenmitglied      | 1987-09-05   | Schlagzeug          
0003   | Mustermann           | Max                  Musterstadt                    | Musterstraße 00                | 2001-01-01   | beurlaubt          | 2010-12-01   | Musterinstrument    
0004   | Kramer               | Volker               88662 Überlingen               | Rosenweg 7                     | 1961-06-21   | aktiv              | 1981-03-01   | Klarinette          
0005   | Maier                | Karl Heinz           99999 Grünwald                 | Dornenweg 5                    | 1986-03-21   | aktiv              | 2001-06-30   | Schlagzeug          
0006   | Lutz                 | Adrian               88662 Überlingen               | Langgasse 14                   | 1991-07-05   | beurlaubt          | 2006-07-08   | Arschgeige          
0007   | test                 | test                 test                           | 12                             | 1991-07-21   | aktiv              | 2002-07-21   | Flügelhorn


Damit bin ich erst mal zufrieden. Durch eure Beispiele und Erklärungen hab ich das jetzt auch verstanden 🙂
Nochmal Danke :toll:


Noch zum Thema "gestellte Aufgabe". Eine konkrete Aufgabe gab es nicht. Nach einem Jahr Java in der Schule (Wirtschaftsgymnasium) sollten wir nun ein Projekt machen, welches Teile beinhaltet, das über den behandelten Stoff hinaus geht. Da hatte ich mir einiges vor genommen, muss aber doch mehr und mehr Abstriche dabei machen 😀


Nur noch eine kleine Frage zum Schluss. Wäre es arg kompliziert, die Daten einer ArrayList in einen zwei-dimensionalen array zu übertragen ?


Liebe Grüße, und nochmal einen Dank an meine beiden Retter

Fitzi
 
Nein, das ginge in etwa so:

Java:
private static final byte MITGLIEDSNUMMER_ANZAHL = 9;
private static final byte MITGLIEDSNUMMER= 0;
private static final byte NACHNAME= 1;
private static final byte VORNAME = 2;
private static final byte WOHNORT = 3;
private static final byte STRASSE = 4;
private static final byte GEBURTSDATUM = 5; //Eher als Stamp/Date in einer long speichern? Vereinfacht Berechnungen.
private static final byte STATUS = 6;
private static final byte EINTRITTSDATUM = 7; //Dito
private static final byte INSTRUMENT = 8;

Mitgliedsnummer[][] array = new Mitgliedsnummer[alleMitgliederMitgliedsnummer.size][9];
for(int i = 0, size = array.size(); i < size; i++)
{
	Mitgliedsnummer mn = alleMitgliederMitgliedsnummer.get(i);
	array[i][MITGLIEDSNUMMER] = mn.getMitgliedsNr();
	array[i][NACHNAME] = mn.getNachname();
	array[i][VORNAME] = mn.getVorname();
	array[i][WOHNORT] = mn.getWohnort();
	array[i][STRASSE] = mn.getStasse();
	array[i][GEBURTSDATUM] = mn.getGeburtsdatum();
	array[i][STATUS] = mn.getMitgliedsstatus();
	array[i][EINTRITTSDATUM] = mn.getEintrittsdatum();
	array[i][INSTRUMENT] = mn.getInstrument();
}

Aber ich finde das Speichern als eigenes Objekt sinnvoller als als Array.
 
Hey,

Das wäre dann wohl die Alternative gewesen. Da ich die JTable lediglich als Ausgabe gebraucht hätte, hätte ich diese ja mit dem Array füllen können.
Aber wie gesagt, bin zufrieden wie es jetzt ist. War ja schwer genug für euch als Geburtshelfer 😀

LG Fitzi
 
Hebamer, bitte. 😉
In so einen Fall würde ich aber die Daten intern in das Objekt (in meinen Beispiel Mitgliedsnummer) in ein Array legen, die Getter/Setter lassen und dann noch einen machen, welcher die Daten per Feldangabe angibt. Und die JTable, die ja x/y-Koordinaten etwa so einsetzen:

Java:
public Object getValueAt (int row, int column)
{
	try
	{
		Mitgliedsnummer mn = alleMitgliederMitgliedsnummer.get(row);
		return(mn.get(column));
	}
	catch(RuntimeException e) {}
	return("");
}

Und das Objekt dann in etwa so:

Java:
public static final byte MITGLIEDSNUMMER= 0;
public static final byte NACHNAME= 1;
public static final byte VORNAME = 2;
public static final byte WOHNORT = 3;
public static final byte STRASSE = 4;
public static final byte GEBURTSDATUM = 5;
public static final byte STATUS = 6;
public static final byte EINTRITTSDATUM = 7;
public static final byte INSTRUMENT = 8;

private String[] values;

public Mitgliedsnummer()
{
	super();
	values = new String[INSTRUMENT + 1];
}
public String get(int i)
{
	return(values[i]);
}
public String get(int i, String s)
{
	values[i] = s;
}
public String getInstrument()
{
	return(values[INSTRUMENT]);
}
//usw...

Von konvertieren würde ich dir abraten, von Arrays eher auch, solange die Daten länger gespeichert und nicht nur für kurze Zeit gehalten werden, wofür eine eigene Klasse zu viel wäre.
 
Zuletzt bearbeitet:

Zurück
Oben