# Interaktion Java-Programm <-> Datenbank



## Wang (5. Jan 2012)

Hallo allerseits,

ich habe gerade meine Bachelorarbeit begonnen und bräuchte ein paar Tipps.
Es ist eine Access-Datenbank vorhanden (vom Lehrstuhl leider so vorgegeben), welche die Attribute User-ID, Alter, Geschlecht, Beruf, PLZ und die von ihnen bewerteten Filme mit der Bewertung enthält.
Nun geht es darum, anhand von Clustering für eine Gruppe von Usern einerseits Einzelempfehlungen und andererseits Gruppenempfehlungen für Filme zu berechnen, die von keinem Gruppenmitglied bisher bewertet wurden.

Die Programmiersprache ist Java und ich arbeite gerade das Konzept für die GUI aus. Zwar meinte die Betreuerin, es wäre in Ordnung, wenn man die Auswahl der Gruppenmitglieder hardcoded (eine Auswahl über die GUI soll also nicht erfolgen), dennoch würde es mich interessieren, wie man eine beliebige Gruppenzusammenstellung über die GUI umsetzen würde.

Gedacht hätte ich an eine JTable, in der der Inhalt der Datenbank angezeigt wird. Problem: wie wählt man die Einträge aus bzw. wie setzt man das technisch um.
Ein weiterer Gedanke war eine JComboBox, in der man nur die IDs aller User angezeigt bekommt, eine ID auswählt und auf "Hinzufügen" klickt, sobald die Auswahl zu Ende ist, geht man auf OK und die Berechnung findet statt.

Es wäre nett, wenn ihr Eure Meinung/Ideen schreiben könntet! 

Danke und Gruß,
Wang


----------



## c_sidi90 (5. Jan 2012)

Also ich arbeite generell bei DB-Anwendungen mit JTables wenn es um die Visualisierung von Datenbanktabellen geht. Dabei geht man in der Regel so vor, zunächst ein für dein Vorhaben passendes TableModel zu erstellen. Dabei erstelle ich eine Klasse welche AbstractTableModel erweitert. Hier kannst du dann festlegen, wie die Tabelle auf verschiedene Ereignisse reagieren soll. (über Google findest du zu dem Thema auch viele Posts).

JTables übergibt man meist über Object Arrays [][] die gewünschten Daten. Diese Arrays oder DataVectoren werden im Konstruktor des vorher erstellten TableModels übergeben. Im Anschluss kann man ein solches Model mit jtable.setModel(meinEigenesModel) zuweisen.



mit der Methode getValueAt(x,x) des JTables kannst du einfach die spezifischen Daten aus der Tabelle bekommen und dementsprechend deine SQL Abfragen gestalten.


----------



## Wang (5. Jan 2012)

c_sidi90 hat gesagt.:


> mit der Methode getValueAt(x,x) des JTables kannst du einfach die spezifischen Daten aus der Tabelle bekommen und dementsprechend deine SQL Abfragen gestalten.



D.h. der Anwender müsste die x- und y-Koordinate eingeben und dann z.B. auf "Hinzufügen" klicken, um einen User der Gruppe hinzuzufügen? Das wäre zwar nicht gerade elegant gelöst, die Anwendung soll aber auch nicht in den Verkauf gehen, sondern dient eher Forschungs- und Demonstrationszwecken.

Meint ihr es ist machbar, den Datenbankinhalt in einer JTable zu präsentieren und neben jeder Zeile ein Auswahlkästchen (JRadioButton) zu haben, sodass der Anwender einfach nur die gewünschten Kästchen anklicken muss, anschließend auf "OK" geht und dann so die Gruppe fertig zusammengestellt ist? Ich kann mir das gerade technisch überhaupt nicht vorstellen... ???:L


----------



## fastjack (6. Jan 2012)

Welche Zuweisungsart ist das überhaupt in deinem Modell? 

* 1->N

oder 

N->M ?


----------



## Wang (6. Jan 2012)

fastjack hat gesagt.:


> Welche Zuweisungsart ist das überhaupt in deinem Modell?
> ...



Es sind drei Tabellen. Die erste Tabelle enthält die Attribute User-ID, Alter, Geschlecht, Beruf, PLZ; die zweite Tabelle enthält die Attribute User-ID, Movie-ID, Bewertung und die dritte Tabelle enthält die Attribute Movie-ID, Titel, diverse Genres. Jeder User kann mehrere Filme bewerten, allerdings pro Film nur eine Bewertung abgeben.

Es ist eine etwas verzwickte Sache. In der Praxis würde das z.B. so aussehen, dass man einen User hat und als Gruppe ihn und seine gesamte Freundesliste verwendet (wie man das von "social" networks kennt). Für die Bachelorarbeit ist nur eine Datenbank mit ca. 1000 Usern gegeben, die in keiner definierten Beziehung zueinander stehen.
Ich denke es kommt nicht gut rüber (man denke an die Präsentation der Bachelorarbeit), wenn die GUI nur einen Button "Berechne Empfehlungen" enthält, ohne dass der User sieht, wie die "Stichprobe" überhaupt aussieht.

Sagt mir bitte einfach wie ihr das seht, Vorschläge sind natürlich weiterhin sehr willkommen:

1. Idee: Gesamte Datenbank über eine JTable anzeigen, sodass der User sich seine Gruppe zunächst selbst zusammenstellt. Das Problem ist für mich die technische Umsetzung, da ich nicht weiß, wie man das Auswählen userfreundlich gestalten kann. Außerdem wäre der User wegen Riesen-Auswahlmöglichkeit wohl wie gelähmt.
2. Idee: Man präsentiert nur die IDs in einer JComboBox, der User wählt immer eine ID aus, klickt dann auf "Hinzufügen" und das setzt er beliebig lange fort, bis die Gruppe zusammengestellt ist. Dann klickt er auf "Berechnen".
3. Idee: Die Mitglieder der Gruppe werden "hardgecoded" und der User sieht in der GUI in Form einer JTable nur die Auswahl der "hardgecodeten" User nach ID, Alter, Geschlecht, Beruf, PLZ. So erscheint dem User das nicht als "Hokuspokus" wie wenn er nur einen Button sieht und dann irgendwelche Empfehlungen kommen.

Eine kleine Anmerkung: Fest vorgegeben ist für die Arbeit, dass bei den Empfehlungen auch angezeigt werden soll, wie sie zustande gekommen sind, sprich welche User in die Kalkulation miteingeflossen sind.

Danke für Eure Hilfe! 

Gruß
Wang


----------



## fastjack (6. Jan 2012)

Okay.

Ich versuche es mal zu beschreiben... Du machst ein Panel mit zwei Teilen (oben und unten). Oben zeigst Du die Liste mit allen Benutzern an. Wenn man einen Benutzer auswählt gehts unten weiter.

Wie sieht unten aus? Unten ist am besten ein TabbedPane, also ein Panel mit Reitern sozusagen. Im ersten Reiter kannst Du Benutzerstammdaten editieren, also Name usw. Im zweiten Tab hast Du wieder eine Liste, und zwar mit Bewertungen. So eine Art Tabelle mit Spalten: Film, Bewertung (eventuell trimmen) usw.

Außerdem gibt es in diesem Tab Buttons, nämlich ADD, DELETE, Bewerten usw. Delete löscht eine ausgewählte Bewertung (natürlich mit Rückfrage), Bewerten ermöglicht das eingeben/ändern einer Bewertung und Add öffnet ein Suchfenster.

Das Suchfenster zeigt die Liste (als Tabelle) aller Filme (am besten Scrollbar) und hat oben eine Textzeile und einen Suchen-Button, der die Suche startet (enter soll normalerweise auch die Suche starten). Durch Doppelclick auf eine Tabellenzeile wird dieser Film für das Hauptfenster ausgewählt und wandert in die Liste von "unten"


```
Tab Daten

+---------------------------------------------+ // eventuell auch ein Suchmodus wie ganz unten
|ID|Name |Vorname                             |
+---------------------------------------------| 
| 1|Abbas|Hans                                | // Scrollbars
| 2|...  |...                                 | // eventuell Seitenanzeige/Navigation
+---------------------------------------------+
|                                             |
+---------------------------------------------|
|DATEN|Filme|                                 |
|---------------------------------------------+
|ID     : ____                                |
|Name   : ____                                |
|Vorname: ____                                |
|                                             |
|Buttons für Submit und Co.                   |
+---------------------------------------------+

Tab Filme

+---------------------------------------------+ // eventuell auch ein Suchmodus wie ganz unten
|ID|Name |Vorname                             |
+---------------------------------------------| 
| 1|Abbas|Hans                                | // Scrollbars
| 2|...  |...                                 | // eventuell Seitenanzeige/Navigation
+---------------------------------------------+
|                                             |
+---------------------------------------------|
|Daten|FILME|                                 |
|---------------------------------------------+ // eventuell auch ein Suchmodus wie ganz unten
|ID|Name     |Bewertung                       |
|---------------------------------------------+
| 1|Planet 51|Nett und bla und sülz und Co ...| // Scrollbars
|---------------------------------------------+ // eventuell Seitenanzeige/Navigation
|                                             |
|Buttons für Add, Delete, Bewerten und Co.    |
+---------------------------------------------+

Suche Filme

+---------------------------------------------+
|_____________________________________  |SUCHE| // Suche mit Button und ENTER
+---------------------------------------------+
|ID|Name                                      |
+---------------------------------------------| 
| 1|Planet 51                                 | // Scrollbars, eventuell Seitenanzeige/Navigation
| 2|...                                       | // Select durch Click, dann schließen des Fensters
+---------------------------------------------+ // und Übernahme in Liste des Filme-Tabs
```

So haben wir das jedenfalls bei uns in der Firma immer gemacht (per Swing für Desktop und auch im Web, mit wingS). Kam immer gut an bei den Nutzern.


----------



## Wang (6. Jan 2012)

Danke fastjack für Deine Mühe. 

Auf die Such- und Editierfunktion werde ich aber sicher verzichten, da sich die Datenbank nicht ändern wird und es nur darum geht, die Funktionsweise zu demonstrieren (wegen der parallel laufenden Vorlesungen fehlt mich leider auch die Zeit für solche Extras).

Ich werde der Betreuerin in der kommenden Woche die Ideen inkl. Deinem Vorschlag präsentieren und mal sehen was sie sagen wird. Gut finde ich den von Dir angesprochenen Punkt mit dem Doppelklick auf eine Tabellenzeile, um dem User die Auswahl der Gruppenmitglieder zu ermöglichen (vielleicht um keine Missverständnisse aufkommen zu lassen: es geht im Moment nur um die Zusammenstellung der User, die Filme selbst interessieren eigentlich erst nach der Empfehlungs-Kalkulation).

Kurzes Szenario mit der JTable:
Der User sieht die erste Tabelle (Attribute User-ID, Alter, Geschlecht, Beruf, PLZ) in Form einer JTable und stellt durch Doppelklick in einer Zeile die User-Stichprobe bzw. Gruppe zusammen. Die Auswahl wird ihm in einer neuen Tabelle präsentiert und sobald er mit dem Auswählen fertig ist, klickt er auf "Empfehlungen generieren".

Wie setzt man aber die Auswahl durch Doppelklick für eine gesamte Zeile um ???:L

Vielen Dank!

Gruß
Wang


----------



## Wang (8. Jan 2012)

Hallo allerseits,

es wäre sehr nett, wenn mir jemand bei der folgenden Problematik etwas unter die Arme greifen könnte (Achtung: es ist NICHT nötig, den Thread zu lesen, sondern nur diesen Beitrag):

Der Inhalt der Datenbank wird in eine JTable geladen, welche sich nach einem Klick auf einen Button im Hauptfenster in einem neuen Fenster öffnet. Dabei erscheinen nur wenige Attribute wie User-ID, Alter und Geschlecht (das Auslesen und Schreiben in die JTable sind für mich kein Problem). Ich möchte nun, dass der Anwender durch Doppelklick in eine Zeile seine Auswahl für die spätere Berechnung trifft, d.h. er klickt solange weitere Zeilen an, bis er die gewünschte Auswahl getroffen hat, dann schließt er das separate Fenster und ist wieder beim Hauptfenster. Dort kann er durch Klicken auf einen weiteren Button in einem sich neu öffnenden Fenster in einer JTable die getroffene Auswahl sehen.

Fragen:
- Muss ich für jede Zeile im separaten Auswahlfenster einen Listener implementieren oder wie setze ich die beschriebene Anforderung überhaupt um?
- Kennt jemand ene Möglichkeit, wie man als Nicht-Grafiker halbwegs einfache TrayIcons kreiert?

Vielen Dank für Eure Unterstützung! 

Gruß
Wang


----------



## Wang (8. Jan 2012)

Ich habe währenddessen recherchiert und bin auf dieses interessante Beispiel gestoßen:

How to Use Tables (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

Ich würde gerne die Datenbank in eine ähnliche JTable laden, wie sie im Beispiel abgebildet ist. Der User soll also bei den gewünschten Zeilen ein Häkchen setzen können und nach Klicken auf O.K. die Auswahl abschließen.

Weiß jemand, mit welchen "Zutaten" man das implementieren kann?

Bin um jeden Beitrag nachwievor sehr dankbar, weil ich leider total auf der Strecke stehe!


----------



## JohannisderKaeufer (9. Jan 2012)

Ein entsprechendes Tablemodel mit einem Boolean für die Spalte in der das Kästchen sein soll. 

How to Use Tables (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

beschreibt wie man auf Änderungswünsche reagieren kann.

Und ein Listener der am Schluß aus deinem Tablemodel die ausgewählten Werte rausfiltert und zurückliefert, dürfte auch nicht die Welt sein.


----------



## Wang (9. Jan 2012)

JohannisderKaeufer hat gesagt.:


> Ein entsprechendes Tablemodel mit einem Boolean für die Spalte in der das Kästchen sein soll.



Perfekt, Danke! Ich dachte ernsthaft, man müsste für jede Zelle eine JCheckBox implementieren, was mal enorm aufwendig gewesen wäre... 



JohannisderKaeufer hat gesagt.:


> How to Use Tables (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)
> 
> beschreibt wie man auf Änderungswünsche reagieren kann.
> 
> Und ein Listener der am Schluß aus deinem Tablemodel die ausgewählten Werte rausfiltert und zurückliefert, dürfte auch nicht die Welt sein.



Das sollte jetzt wirklich kein Problem mehr sein.


----------



## Wang (24. Feb 2012)

Hallo,

leider wird mir in der JTable nicht die Datenbank ausgegeben. Die Verbindung steht und es wird auch alles korrekt im Vektor gespeichert (getestet mit System.out.println) aber ich sehe nicht, wo das Problem ist. ;(

Hier mal der Konstruktor der betroffenen Klasse:


```
public DatabaseJTable()
	{
		super(new GridLayout(1,0));		
		this.dm = new DefaultTableModel(columnNames, 0);
		this.table = new JTable(dm);
		JScrollPane scrollPane = new JScrollPane(table);
		add(scrollPane);
		
		AccessDatabaseConnection adbc = new AccessDatabaseConnection();
		
		try
		{
			adbc.loadDriver();
	        adbc.makeConnection();
	        adbc.buildStatement();
	        ResultSet rs = adbc.executeQuery(sql);
	        
            if(rs != null)
            {
            	Vector<String> v = new Vector<String>();
            	
                while(rs.next())
                {
                	v.addElement(rs.getString("ID"));
                	v.addElement(rs.getString("age"));
                	v.addElement(rs.getString("gender"));
                	v.addElement(rs.getString("occupation"));
                	v.addElement(rs.getString("zipcode"));
                	this.dm.addRow(v);
                	v.clear();
                }
            }
            else
            {
                System.out.println("Resultset is null!!!");
            }
            adbc.connection.close();
		}
		catch(Exception e)
		{
			System.err.println(e.getMessage());
			e.printStackTrace(System.err);
        }
	}
```

Lasse ich das 
	
	
	
	





```
this.dm.addRow(v);
```
 in Zeile 29 weg, wird nur der Header angezeigt und es gibt keine Exceptions. Wenn das dasteht, wird nur das Fenster angezeigt und bei den geringsten Verschiebung gibt es Exceptions ohne Ende...

Ich bitte dringend um Hilfe!

Gruß
Wang


----------



## Wang (24. Feb 2012)

Jetzt habe ich es hingekriegt, es funktioniert, ich stehe aber wie der Ochs vorm Berg... Die Lösung:


```
while(rs.next())
{
    Vector<String> v = new Vector<String>();
                
    v.addElement(rs.getString("ID"));
    v.addElement(rs.getString("age"));
    v.addElement(rs.getString("gender"));
    v.addElement(rs.getString("occupation"));
    v.addElement(rs.getString("zipcode"));
                    
    this.dm.addRow(v);
}
```

Scheinbar hat das vorhin mit dem 
	
	
	
	





```
v.clear();
```
 nicht geklappt. Wenn jemand eine Ahnung hat, warum es so funktioniert, lasst es mich bitte wissen.


----------



## JohannisderKaeufer (25. Feb 2012)

```
Vector v = new Vector();
this.dm.addRow(v);
...
v.clear();
```

Schaut man sich die sourcen von DefaultTableModel an, sieht man, dass bei addRow(Vector v) nur die Reference des Vectors gespeichert wird und nicht dessen Inhalt.
Das hat zur Folge das du bei dem clear, den Vector leerst, das TableModel allerdings immer noch auf den Vector zeigt.

Was das zu bedeuten hat sollte zum Zeitpunkt einer Bachelorarbeit aber schon bekannt sein.

Wenn du bei deiner Ursprünglichen Version bleiben wolltest. Warum auch immer müßte das so aussehen.


```
Vector<String> v = new Vector<String>();
                
                while(rs.next())
                {
                    v.addElement(rs.getString("ID"));
                    v.addElement(rs.getString("age"));
                    v.addElement(rs.getString("gender"));
                    v.addElement(rs.getString("occupation"));
                    v.addElement(rs.getString("zipcode"));
                    this.dm.addRow(new Vector(v));
                    v.clear();
                }
```


----------



## OSBI_Fan (25. Feb 2012)

Hallo Wang,

schau Dir mal das Konzept von XDEV3 an. LinK:

XDEV Software Corp. - Startseite

Die Entwicklungsumgebung ist so konzipiert, das Du beliebige Datenbanken über virtuelle Tabellen (VT) anbinden kannst, unter anderem Access. Alle GUI-Komponenten lassen sich per Drag&Drop auf die Arbeitsfläche einfügen und dort pixelgenau positionieren. Formulare lassen sich so blitzschnell designen und sogar aus Tabellen heraus automatisch generieren. Auch aufwändige Master-Detail Ansichten sind verblüffend einfach zu generieren. Dank eines innovativen Layout-Assistenten ist auch der Umgang mit Layout-Manger simpel.

Um eine Datenbankabfrage durchführen zu können und damit die virtuellen Tabellen mit Daten zu befüllen unterstützt ein Query-Assistent. Über die im Query-Assistenten definierte SQL Abfrage wird datenbankunabhängigen Java Code generiert. Änderungen oder Erweiterungen können danach wahlweise im Assistenten oder direkt im generierten Quellcode vorgenomen werden. Code-Änderungen werden vom Query-Assistenten automatisch registriert und beim nächsten Aufruf des Assistenten automatisch verarbeitet (siehe Online-Dokumentation oder Forum - deutsche Community).

Das XDEV 3 RAD-Konzept stellt eine Vielzahl wichtiger Basisfunktionen für die Entwicklung von Datenbank-Anwendungen und grafischen Oberflächen (GUI) zur Verfügung, die Java Entwickler gewöhnlich mit großem Aufwand selber programmieren müssen, u.a. Databinding, Verarbeitung von Abfrageergebnissen (Resultsets), Transaktions-Management und Daten-Verschlüsselung. Darüber hinaus bietet das Framework eine kompakte Funktionsbibliothek (XAPI) mit einer Vielzahl an Funktionen, die den Zugriff auf Datenbanken, Dateien, den Arbeitsspeicher, Oberflächen und externe Applikationen extrem erleichtert.

Deployment auf Ant-Basis:
XDEV 3 bietet ein vollautomatisiertes Deployment auf Basis von Apache Ant, mit dem im Handumdrehen neue Builds erstellt werden können, ohne dafür extra Scritps schreiben zu müssen. Erst beim Projektabschluss wird entschieden, wie die Anwendung betrieben werden soll. Über den Deployment-Assistenten kann man aus ein und derselben Codebase heraus wählen zwischen:

    Java Applikation
    Rich Internet Application (Java Applet)
    Java Webstart-Applikation

Das XDEV Application Framework ist Open Source. Die RAD-Features von XDEV 3 machen die Anwendungsentwicklung mit Java revolutionär einfach und ersparen eine Menge an Programmierarbeit, was sich wie ein Turbo auf die Entwicklung auswirkt. Da XDEV 3 ähnlich funktioniert wie Access, Oracle Forms und andere 4GL-Tools, ist der Einstieg in XDEV 3 i.d.R. besonders einfach.

XDEV 3 ist völlig lizenzkostenfrei.

Grüße,

OSBI_Fan


----------

