# Probleme mit Java-Programm



## bertram (25. Okt 2006)

Guten Morgen,

ich schreibe gerade ein Java-Programm, mit dem ich auf eine MySQL Datenbank zugreife.
Ich habe auch schon einiges fertig, nur hänge ich gerade an einem Teil des Programms, bei dem die Felder automatisch generiert werden sollen, das Programm soll die Anzahl der Einträge in der DB auslesen und dann dementsprechend viele Textfelder in dem Programm anlegen.
Außerdem habe ich noch das Problem, das die Anzahl der Spalten über den Seitenrand hinausgeht, und ich nicht weiss, wie ich es realisieren kann, das ich zu den Einträgen ausserhalb des Bildschirms hinscrollen kann.

Schon ein mal vielen Dank im voraus.

MfG

bertram


----------



## The_S (25. Okt 2006)

Warum verwendest du für die Anzeige deiner Datensäzte keine JTable oder JList?

Für das Scrollen schauste dir am Besten mal das JScrollPane an.


----------



## bertram (25. Okt 2006)

Das Problem ist, das nicht nur Textfelder auf der Oberfläche erscheinen sollen, sondern auch Checkboxen und außerdem sollen einige Spalten aus einem Eintrag veränderbar sein, während andere fest und unveränderbar sein sollen.

Ein Beispiel um es zu verdeutlichen:

Pos      Anzahl          Bezeichnung             Lieferschein kontrolliert         Betrag
1         25                Taschenrechner         Ja/Nein                                250 €

Das Programm soll jetzt so arbeiten, das es sich die Anzahl der Einträge aus der Datenbank holt und dann dementsprechend viele Zeilen generiert.
In der Spalte "Lieferschein kontrolliert", soll dann eine Checkbox hin, damit der Endbenutzer ein Haken setzen kann, nach dem er Überprüft hat, ob ein Lieferschein bei der Lieferung dabei war.
Und da so ein Eintrag in der DB, die ich gerade bearbeite noch wesentlich mehr Attribute aufweist, geht das ganze über den Rechten Bildschirmrand hinaus, darum muss da ja auch hinscrollen können.

MfG

bertram


----------



## The_S (25. Okt 2006)

bertram hat gesagt.:
			
		

> Das Problem ist, das nicht nur Textfelder auf der Oberfläche erscheinen sollen, sondern auch Checkboxen und außerdem sollen einige Spalten aus einem Eintrag veränderbar sein, während andere fest und unveränderbar sein sollen.



Das alles bietet dir eine JTable  . Alternative schreibst du dir nen eigenen Container, der deine Felder enthält und addest dann pro Datensatz einen neuen, solchen Container zu deiner Ansicht und setzt die Daten.


----------



## bertram (25. Okt 2006)

Erstmal danke für deine Tipps.

Ich probier gerade das JTable, wenn ich mehr Einträge habe wird eine vertikale Scrollbar angelegt, aber sobald ich mehr Spalten anlege, werden die Spalten angepasst, damit sie noch auf die Seite passen, mein Ziel ist es aber, das die Spaltenbreite gleich bleibt, und automatisch eine horizontale Scrollbar eingeblendet wird.


----------



## The_S (25. Okt 2006)

Gewöhn dir mal an Fragen zu stellen (erkennt man an einem ? am Satzende  ) und nicht immer nur Aussagen zu treffen.

Du kannst einer column eine minimale und eine maximale Größe zuordnen. beides auf den selben Wert und sie sollten sich nicht mehr verändern lassen.


----------



## bertram (26. Okt 2006)

Ich habe jetzt eine JTable erstellt, die auch funktioniert.
Das Problem ist jetzt die Daten, aus der Datenbank zu lesen und diesen in das JTable zu übertragen.

Hier ist der code des Testprogramms:


```
public JComponent createTable()
  {
      try 
      {
          System.out.println("Treiber laden");
          Class.forName("com.mysql.jdbc.Driver").newInstance();
      }
      catch (Exception sqle) 
      {
          JOptionPane.showMessageDialog(null,"No suitable driver"+"\n"+sqle.getStackTrace(),"Unable to load driver",JOptionPane.ERROR_MESSAGE);
      }
      try
      {
          System.out.println("* Verbindung aufbauen");
          String url = "jdbc:mysql://"+hostname+":"+port+"/"+dbname;
          conn = DriverManager.getConnection(url, user, pw);
          
          System.out.println("* Statement beginnen");
          Statement stmt = conn.createStatement();
            
            
          System.out.println("* Abfrage beginnen");
          String sqlCommand1 = "SELECT * FROM test";

          ResultSet rs = stmt.executeQuery(sqlCommand1);
      
      
      Object[][] values = 
      { 
          { "Mary", new Double(1.2), "yes", "w", "blond"}, 
          { "Gordy", new Double(1.5), "no", "w", "braun"},
          { "Billy", new Double(2.5), "no", "m", "gelb"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"},
          { "Jimmy", new Double(5.5), "maybe", "m", "grün"}
      };
      String[] colNames = { "Sp. 1", "Sp. 2", "Sp. 3", "Sp. 4", "Sp. 5"};
      JTable elem = new JTable(values, colNames);
      elem.setPreferredScrollableViewportSize(new Dimension(200, 150));
      javax.swing.table.TableColumn col = elem.getColumnModel().getColumn(0);
      col.setMinWidth(100);
      javax.swing.table.TableColumn col2 = elem.getColumnModel().getColumn(1);
      col2.setMinWidth(100);
      javax.swing.table.TableColumn col3 = elem.getColumnModel().getColumn(2);
      col3.setMinWidth(100);
      javax.swing.table.TableColumn col4 = elem.getColumnModel().getColumn(3);
      col4.setMinWidth(100);
      javax.swing.table.TableColumn col5 = elem.getColumnModel().getColumn(4);
      col5.setMinWidth(100);
      JPanel panel = new JPanel();
      panel.add(new JLabel("Table:"));
      panel.add(new JScrollPane(elem));
      elem.setAutoscrolls(true);
      elem.setEnabled(true);
      elem.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
      return panel;
      }
      catch (SQLException sqle) 
      {
          JOptionPane.showMessageDialog(null, "SQLException: "+ sqle.getMessage()+"\nSQLState: "+ sqle.getSQLState()+"\nVendorError: "+sqle.getErrorCode()+"\n"+sqle.getStackTrace(),"ACCESS DENIED",JOptionPane.ERROR_MESSAGE);
      }
      
  }
  public NewJFrame()
	{
		super("Interaktionselemente");
                Box box = new Box(BoxLayout.Y_AXIS);
                box.add(createTable());
                getContentPane().add(box, BorderLayout.CENTER);
                pack();
	}
```

Wenn ich ohne Datenbankanbindung arbeite geht alles einwandfrei.
Mit der Datenbankanbindung bekomme ich aber die Fehlermeldung : "missing return statement".
Wie kann ich die Datenbankanbindung mit einbringen, ohne das ich diese Fehlermeldung bekomme?

Schon einmal vielen Dank im voraus.

MfG

bertram


----------



## The_S (26. Okt 2006)

bertram hat gesagt.:
			
		

> "missing return statement"



Das bedeutet einfach nur, dass du irgendwo eine Methode hast, die ein Objekt zurück geben soll (also nicht void ist) bei der ein return statement fehlt. Würde z. B. bei folgender Methode auftreten:


```
public int getAnInteger(int i) {

    if (i < 5) {
        return 0;
    }
    else if (i > 5) {
        return 1;
    }
}
```

Abhilfe kann dann z. B. so geschaffen werden


```
public int getAnInteger(int i) {

    if (i < 5) {
        return 0;
    }
    else if (i > 5) {
        return 1;
    }
    return -1;
}
```

[edit] Flüchtigkeitsfehler ausgebessert


----------



## bertram (26. Okt 2006)

Erst einmal Danke für deine schnelle Antwort.

Das ein return statement fehl war mir schon klar, das wird wahrscheinlich daran liegen, das es im try-catch block liegt, und von daher ausserhalb des blocks nicht erkannt wird.

Nur brauche ich den try-catch block, für die Verbindung mit der Datenbank, und wenn ich den try-catch block vorher einsetze, bekomme ich die Daten aus der Datenbank, kann aber außerhalb des try-catch block nicht damit arbeiten, jedoch benötige ich diese Daten, damit sie in das JTable eingetragen werden.

Wie kann ich meinen source so ändern, dass ich den try-catch block behalten kann und das return statement trotzdem erkannt wird.


----------



## L-ectron-X (26. Okt 2006)

@hobbit: Sicher nur ein Flüchtigkeitsfehler.  :wink: Deine Methode soll doch gar nichts zurück liefern (void)
Wenn du in diesem Fall _return -1;_ schreibst, wird dein Compiler dir den Code um die Ohren hauen.
Die Methode muss demnach also so aussehen:

```
public int getAnInteger(int i)
```


----------



## The_S (26. Okt 2006)

@L-ectron-X

joa  die Häufen sich aber irgendwie in letzter Zeit. Habs mal ausgebessert thx.

@Bertram

bau in deinen catch-Block noch ein


```
return null;
```

am Ende ein. So weißt du auch gleich, wenn irgendwas in deiner Methode nicht geklappt hat.


----------



## bertram (26. Okt 2006)

Danke für die Tipps, die Fehlermeldung bekomme ich jetzt nicht mehr.

Leider habe ich jetzt ein anderes Problem.
Wie gesagt, möchte ich das die Daten aus einer Datenbank gelesen und dann in die JTable eingetragen werden.

Hier erstmal mein source:

```
try
      {
          System.out.println("* Verbindung aufbauen");
          String url = "jdbc:mysql://"+hostname+":"+port+"/"+dbname;
          conn = DriverManager.getConnection(url, user, pw);
          
          System.out.println("* Statement beginnen");
          Statement stmt = conn.createStatement();
            
            
          System.out.println("* Abfrage beginnen");
          String sqlCommand1 = "SELECT * FROM test";

          ResultSet rs = stmt.executeQuery(sqlCommand1);
          
          while(rs.next())
          {
              String Name = rs.getString("Sp1");
              String t = rs.getString("Sp2");
              String u = rs.getString("Sp3");
              String ges =rs.getString("Sp4");
              String hf =rs.getString("Sp5");
              System.out.println(Name);
      
      Object[][] values = 
      { 
          { Name, t, u, ges, hf}, 
      };
          
      String[] colNames = { "Sp. 1", "Sp. 2", "Sp. 3", "Sp. 4", "Sp. 5"};
      JTable elem = new JTable(values, colNames);
      elem.setPreferredScrollableViewportSize(new Dimension(200, 150));
      javax.swing.table.TableColumn col = elem.getColumnModel().getColumn(0);
      col.setMinWidth(100);
      javax.swing.table.TableColumn col2 = elem.getColumnModel().getColumn(1);
      col2.setMinWidth(100);
      javax.swing.table.TableColumn col3 = elem.getColumnModel().getColumn(2);
      col3.setMinWidth(100);
      javax.swing.table.TableColumn col4 = elem.getColumnModel().getColumn(3);
      col4.setMinWidth(100);
      javax.swing.table.TableColumn col5 = elem.getColumnModel().getColumn(4);
      col5.setMinWidth(100);
      JPanel panel = new JPanel();
      panel.add(new JLabel("Table:"));
      panel.add(new JScrollPane(elem));
      elem.setAutoscrolls(true);
      elem.setEnabled(true);
      elem.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
      return panel;
          }
      }
      catch (SQLException sqle) 
      {
          JOptionPane.showMessageDialog(null, "SQLException: "+ sqle.getMessage()+"\nSQLState: "+ sqle.getSQLState()+"\nVendorError: "+sqle.getErrorCode()+"\n"+sqle.getStackTrace(),"ACCESS DENIED",JOptionPane.ERROR_MESSAGE);
      }
      return null;
  }
```

Wie kann ich die Daten auslesen und dann in der JTable ausgeben?

Schon einmal vielen Dank im voraus.

MfG

bertram


----------



## The_S (26. Okt 2006)

Du könntest dir z. B. eine Klasse erstellen, die alle Daten in einem Datensatz aus der DB speichert. Diese addest du dann für jede Zeile an einer Liste. Anschließend kannst ja die Daten so bearbeiten, dass sie für die JTable "passen".


----------



## bertram (26. Okt 2006)

Sry, habe mich nicht richtig ausgedrückt.

Der Quellcode, so wie er jetzt ist funktioniert, nur ist das Problem, das ich nur den ersten Wert aus der Datenbank bekomme.
Könnte es sein, das die while-Schleife nur einmal durchlaufen wird?

Wenn ich return plane; weglasse, bekomme ich zwar mehr Werte aus der DB, bekomme aber folgende Fehlermeldung:


```
Exception in thread "main" java.lang.NullPointerException
        at java.awt.Container.addImpl(Container.java:1019)
        at java.awt.Container.add(Container.java:351)
        at NewJFrame.<init>(NewJFrame.java:111)
        at NewJFrame.main(NewJFrame.java:142)
Java Result: 1
```

Kann mir jemand sagen, wie ich alle Werte aus der DB bekomme, ohne das ich das statement return panel weglassen muss?

Schon einmal vielen Dank im voraus.

MfG

bertram


----------



## The_S (26. Okt 2006)

Du hast dich imho schon richtig ausgedrückt und ich hab imho dein Prob auch schon verstanden, aber du überschreibst ja immer dein Object values. Da kann ja nur der letzte Satz drin stehen.


----------



## SlaterB (26. Okt 2006)

wie schön wäre eine richtige Formatierung des Codes.....

was soll deine Operation überhaupt machen?
wenn du innerhalb der while-Schleife ein return stehen hast, 
dann wird die Operation natürlich nach dem ersten Teilschritt abgebrochen,
was ist daran so schwer zu verstehen, das ist doch die Funktion eines returns?

wenn du das auskommentierst wird anscheinend am Ende der Operation null zurückgegeben, und dieses null-Objekt irgendwo in eine graphischee Oberfläche eingefügt,
dass das nicht gutgeht sollte dir genauso klar sein,
oder welches Verhalten erwartest du stattdessen von der Anwendung?

dass sie in großer roter Schrift 'null' anzeigt?
dann füge ein JPanel ein mit entsprechendem Label!

dass die GUI gar nicht reagiert?
dann füge auch nix ein!

null irgendwo einzufügen macht in keiner Hinsicht Sinn,

----
also bevor du weiter rumrätselst bzw. andere für dich rätseln läßt,
beschreibe doch erstmal in Worten, was diese Operation eigentlich tun soll
(steht sicherlich schon irgendwie am Anfang, aber ein Update zum aktuellen Stand ist immer nett)


----------



## bertram (26. Okt 2006)

Ok, dann werde ich es dir erklären.

Es sollen Daten aus einer Datenbank ausgelesen und dann in einer JTable wieder ausgegeben werden.


----------



## André Uhres (26. Okt 2006)

Probier mal die Forumsuche, Stichwort: tablefromdatabase


----------



## SlaterB (26. Okt 2006)

du erstellst die Tabelle und das JPanel in der while-Schleife nach dem Auslesen der ersten Zeile nur mit den Daten dieser ersten Zeile,
das ist falsch,

du musst erst alle Daten auslesen und in ein Object[][]mit vielen Zeilen speichern,
und erst dann die JTable + das JPanel erzeugen

-----------

Tipp:
versuche die Daten erstmal in einer Konsolenanwendung in ein Object[][] zu kriegen und (danach) per System.out.println() auszugeben,
so musst du dir bei diesem Problem über die graphische Darstellung gar keine Sorgen machen,
die ist dafür irrelevant,

idealerweise erstelle eine Operation
Object[][] getData()

die du dann in deiner GUI verwenden kannst,
dann sieht createTable() so aus:

JComponent createTable() {
data = getData()
erstelle Tabelle
erstelle JPanel
}

also die Operation createTable() sollte völlig frei von Datenbank-Code sein,
nur dieser eine Aufruf getData(),
evtl. werden die Daten auch als Parameter übergeben,
dann kannst du die Operation für beliebige Daten wiederverwenden

getData() ist im Gegensatz völlig frei von GUI-Code


----------



## bertram (26. Okt 2006)

Danke für eure Tipps, das Programm läuft jetzt einwandfrei   .


----------



## bertram (27. Okt 2006)

Ich habe das Problem so gelöst:


```
public NewJFrame()
  {   
      Vector columnNames = new Vector();
      Vector data = new Vector();
      Vector columntype = new Vector();
      try
      {
          Class.forName("com.mysql.jdbc.Driver").newInstance();
          String url="jdbc:mysql://"+hostname+":"+port+"/"+dbname;
          conn=DriverManager.getConnection(url,user,pw);
          
          String sql ="SELECT * FROM test";
          Statement stmt=conn.createStatement();
          ResultSet rs=stmt.executeQuery(sql);
          ResultSetMetaData rsmd=rs.getMetaData();
          int columns=rsmd.getColumnCount();
          for (int i = 1; i <= columns; i++) 
          {
                columnNames.addElement( rsmd.getColumnName(i) );
          }
          while (rs.next()) 
          {
                Vector<Object> row = new Vector<Object>(columns);
               
                for (int i = 1; i <= columns; i++) 
                {
                    row.addElement( rs.getObject(i) );
                }
                data.addElement( row );
            }
            rs.close();
            stmt.close();
        } 
      catch(Exception e) 
      {
            System.out.println( e );
      }
      JTable table = new JTable(data, columnNames);
      javax.swing.table.TableColumn col = table.getColumnModel().getColumn(0);
      col.setMinWidth(250);
      javax.swing.table.TableColumn col2 = table.getColumnModel().getColumn(1);
      col2.setMinWidth(250);
      javax.swing.table.TableColumn col3 = table.getColumnModel().getColumn(2);
      col3.setMinWidth(250);
      javax.swing.table.TableColumn col4 = table.getColumnModel().getColumn(3);
      col4.setMinWidth(250);
      javax.swing.table.TableColumn col5 = table.getColumnModel().getColumn(4);
      col5.setMinWidth(250);
      javax.swing.table.TableColumn col6 = table.getColumnModel().getColumn(5);
      col6.setMinWidth(250);
      
      JScrollPane scrollPane = new JScrollPane( table );
      table.setAutoscrolls(true);
      table.setEnabled(true);
      table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
      getContentPane().add( scrollPane );
      JPanel buttonPanel = new JPanel();
      getContentPane().add( buttonPanel, BorderLayout.SOUTH );
        }
```

Es klappt auch wunderbar.
Meine frage ist jetzt, wie kann ich col6 sagen, das in der Spalte eine checkbox und kein TextFeld hin soll.
Das Programm erkennt automatisch, das es sich um ein boolean Wert handelt und schreibt bisher "true" und "false" in die Zeile.

Schon einmal vielen Dank im voraus.

MfG

bertram


----------



## The_S (27. Okt 2006)

Wirf doch hier mal einen Blick rein 

http://www.java-forum.org/de/viewtopic.php?t=5321


----------

