# Combobox im JFrame aus Datenbank befüllen



## Chriss_07 (26. Mai 2010)

Hi folks,
ich bin Neuling in diesem Forum. Also erstmal ein herzliches HALLO an alle.
Zur Zeit probier ich mich am programmieren eines JFrame, dessen Layout ich mit einem JPanel nach folgendem Schema erstellt habe. Eine Klasse beschreibt den Container, eine weitere _KlassennameHandler_ die _ActionEvents_. Dazu kommt noch eine Klasse _Dbconnect_ für den Datenbankzugriff und Vektorklassen für die Datenbanken.
Nun soll eine Combobox mit Inhalten aus einer Datenbank gefüllt werden. Dazu habe ich schon viele Threads gelesen, auch hier im Forum wurde das thematisiert, nur bekomme ich die Funktionen nicht implementiert und zerschiesse mir ständig den Quellcode. Hier mal der Quellcode:

NewJFrame

```
public class NewJFrame extends JFrame {
	
	private static final long serialVersionUID = 1L;
	private JPanel panelContent = null;
	private JTextField numberJTF;
	private JLabel titelLb1;
	private JLabel titelLb2;
	private JLabel titelLb3;
	static String nummer;
	private JButton catchBT;
	private JButton deleteBT;
	private JButton calendarBT;
	private JComboBox fromCB;
	private JTable auftragTbl;

DefaultTableModel defaultTableModel;
	
	public NewJFrame() throws Exception {
		
		NewJFrameHandler startHandler = new NewJFrameHandler(this);


	    addWindowListener(startHandler);
	    setSize( 600, 530 ); 
	    setResizable(true);
	    centerFrame();
	    
		catchBT = new JButton("Erfassen");
		catchBT.setName("Erfassen");
		catchBT.addActionListener(startHandler);
		catchBT.setBounds(400, 100, 100, 30);
		add(catchBT);
		
		deleteBT = new JButton("Löschen"); 
		deleteBT.setName("Löschen");
		deleteBT.addActionListener(startHandler);
		deleteBT.setBounds(400, 150, 100, 30);
		add(deleteBT);
			
		calendarBT = new JButton("Termine"); 
		calendarBT.setName("Termine");
		calendarBT.addActionListener(startHandler);
		calendarBT.setBounds(400, 15, 100,30);
		add(calendarBT);
	    
	       titelLb1 = new JLabel("Von");
		titelLb1.setBounds(50, 15, 30, 50);
		add(titelLb1);
		
		fromCB = new JComboBox();
		fromCB.setBounds(15, 50, 200, 20);
		add(fromCB);
		
		defaultTableModel = new DefaultTableModel();
 		defaultTableModel.setColumnIdentifiers(COLUMN_IDENTIFIERS);
		auftragTbl = new JTable(defaultTableModel);
		TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel> (defaultTableModel);
		auftragTbl.setRowSorter(sorter);
					
		auftragTbl.setBounds(15, 100, 350, 230);
		auftragTbl.setEnabled(false);
		add(auftragTbl);
		
		JScrollPane scrollTable = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
	    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED ); 
		scrollTable.setViewportView(auftragTbl);
		scrollTable.setBounds(15, 100, 350, 230);
		add(scrollTable);
	    
		 JLabel a = new JLabel();
		    a.setLayout(null);
	        a.setOpaque(false);
		    add(a, BorderLayout.CENTER);
		    
		
	    setVisible( true );
	    
	}	
	
public void centerFrame(){
	Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	
	int top = (screenSize.height - this.getSize().height) / 2;
	int left = (screenSize.width - this.getSize().width) / 2; 
	
	this.setLocation(left, top);
}


public void setContent(JPanel content) {
	if(this.isAncestorOf(panelContent)){
		this.remove(panelContent);
	}
	this.panelContent = content;
	add(panelContent);
	this.validate();
}


public void Close() {
	dispose();
}
public static void main(String[] args) throws Exception {			
    new NewJFrame().setVisible(true);
 }

}
```

DBconnect


```
import dbmanager.ComboFill;

public class DBconnectdb {
    
	public static Connection conn;

    
    public DBconnectdb() {    
    	
    }
    
    
    /**
	* - Öffnet Verbindung zur Datenbank ComboFill 
	* 
	*/    
        
    public static void openConnection() throws Exception {
    	try {
    		Class.forName("org.sqlite.JDBC");
    		DriverManager.registerDriver(new org.sqlite.JDBC());
	    	conn = DriverManager.getConnection ("jdbc:sqlite:combo.db");
	        int level = Connection.TRANSACTION_SERIALIZABLE;
	        conn.setTransactionIsolation(level);
    	}catch (SQLException e) {
			String msg = "Es konnte keine Verbindung zur Datenbank hergestellt werden.\n"
				   + "Die Applikation wird nun geschlossen.";
			JOptionPane.showMessageDialog(null, msg, "Datenbank nicht gefunden!", JOptionPane.WARNING_MESSAGE);
			System.exit(0);
    	}
	    	
    }
    /**
	* - Ort abfragen 
	* 
	*/    
     
	public ComboFill getWohnort(String ort) throws Exception {
		ResultSet rs;
		Statement stmnt;
		ComboFill wohnort = new ComboFill();
		
		try {
			openUserConnection();
			stmnt = conn.createStatement();
			String sql = "SELECT * FROM ort";
			System.out.println(sql);
			rs = stmnt.executeQuery(sql);
			
			rs.close();
			stmnt.close();
			disconnet();
			
		} catch (SQLException e) {
			return null;
		}
		disconnet();
		return wohnort;
	}
 public static void disconnet() throws SQLException {
    	if(conn!=null)
    		conn.close();
    }
```

ComboFill


```
import java.util.Vector;

public class ComboFill {

	private String ort = "";
	private Vector<ComboFill> position = new Vector<ComboFill>();
	
	public String Ort() {
		return ort;
	}
	
	public void setOrt(String ort) {
		this.ort = ort;
	}
	
	public void getOrt(String ort) {
		this.ort = ort;
	}

	public Vector<ComboFill> getAllPositionen() {
			position.add(new ComboFill());
			return position;
	}

	public ComboFill get(int row) {
		// TODO Auto-generated method stub
		return null;
	}

	public void addTour(ComboFill fill) {
		// TODO Auto-generated method stub
		
	}
		
}
```

Soweit so gut, die Hilfe die ich bisher gefunden hatte, bozog sich immer auf EINE Klasse, in der die ComboBox, der DBconnect und  addItem stattfand. Da ich es aber sauber trennen möchte, denke ich ich komm nur weiter wenn andere sich den Quellcode ansehen, denn ich seh den Wald vor lauter Bäumen nicht mehr
Gruß Chriss


----------



## KrokoDiehl (27. Mai 2010)

Hallo.
Ich bin mal so ehrlich und sage, dass ich deinen Code nicht komplett gelesen habe. Aber ich gehe nunmal davon aus, dass du es hinbekommst, auf deiner GUI eine ComboBox anzuzeigen und dass du es hinbekommst, Daten aus einer Datenbank zu lesen. Dein Problem nun also ist, eine ComboBox mit diesen DB-Daten zu füllen.

Grundsätzlich gibt es mehrere Wege. Der direkteste ist wohl, dass du deine DB-Abfrage so gestaltest, dass sie ein Array von Objekten zurückliefert. Dieses Array kannst du direkt dem Konstruktor der _JComboBox _übergeben. Das sieht etwa so aus:

```
Object[] dbData = myDBconn.queryData(); // was auch immer dies macht

JComboBox myComboBox = new JComboBox(dbData);
this.add(myComboBox, ...);
```
So in etwa.

Wenn du es mehr trennen willst, ist die sauberste Variante wohl ein eigenes _ComboBoxModel_: Du verfasst eine Klasse die dieses Interface implementiert. Dann ist das eigentliche nur noch, die Daten da rein zu kriegen. Auch hier 1000 Wege...

```
class MyDBDataModel implements ComboBoxModel
{
    // ...
}

JComboBox myComboBox = new JComboBox(new MyDBDataModel());
```
Deinem Modell kannst du entweder auch ein Array mit den DB-Daten geben, oder eine Liste (oder oder oder). Du kannst ihm auch deine DB-Connection direkt geben, sodass das Modell seine eigene DB-Abfrage macht... was in deinem Fall, bzw. dir, am Sinnvollsten erscheint.


----------



## Chriss_07 (27. Mai 2010)

Hi KrokoDiehl,
ich habe die Idee mit dem Array folgenderweise umgesetz:
In der Klasse DBconnect stelle ich die Datenbankverbindung her und den SQLQuery. Die erhaltenen Werte schreibe ich in ein Array _CBobjekte_

```
public class DBconnectdb {
    
	public static Connection conn;

    public DBconnectdb() {    
    	
    }
    /**
	* - Öffnet Verbindung zur Datenbank Combo 
	* 
	*/    
        
    public static void openConnection() throws Exception {
    	try {
    		Class.forName("org.sqlite.JDBC");
    		DriverManager.registerDriver(new org.sqlite.JDBC());
	    	conn = DriverManager.getConnection ("jdbc:sqlite:combo.db");
	        int level = Connection.TRANSACTION_SERIALIZABLE;
	        conn.setTransactionIsolation(level);
    	}catch (SQLException e) {
			String msg = "Es konnte keine Verbindung zur Datenbank hergestellt werden.\n"
				   + "Die Applikation wird nun geschlossen.";
			JOptionPane.showMessageDialog(null, msg, "Datenbank nicht gefunden!", JOptionPane.WARNING_MESSAGE);
			System.exit(0);
    	}   	
    }

public final static ArrayList<String> CBobjekte = new ArrayList<String>();

	public ComboFill getOrt(String ort) throws Exception {
		ResultSet rs;
		Statement stmnt;
		ComboFill wohnort = new ComboFill();
		
		try {
			openConnection();
			stmnt = conn.createStatement();
			String sql = "SELECT * FROM ort";
			System.out.println(sql);
			rs = stmnt.executeQuery(sql);
			 while (rs.next()) {
	                ort = rs.getString(2);
	                CBobjekte.add(ort);
	              }
			rs.close();
			stmnt.close();
			disconnet();
			
		} catch (SQLException e) {
			return null;
		}
		disconnet();
		return wohnort;
	}
	private void disconnet() {
		if(conn!=null);
		
	}
```

Nun ist der Weg mit dem ComboBoxModel der, den ich anstrebe. So kann ich in anderen Frames dieses wieder verwenden. Dafür hatte ich die Klasse _ComboFill _geschrieben. Die scheint mir aber nicht Fehlerfrei zu sein und wie implementiere ich das Array von dort in die ComboBox?
Gruß Chriss


----------



## KrokoDiehl (27. Mai 2010)

Hallo.
Du hast ja selbst schon eine ArrayList erstellt, in der die DB-Daten hinein sollen. Lass diese Liste noch von dem ComboBoxModel direkt verwalten, dann passt das meiste schon. So in etwa sieht das dann aus:

```
public class MyCBModel implements ComboBoxModel
{
    private ArrayList<String> cbData       = null;
    private String            selected     = null;
    private EventListenerList listenerList = null;
    
    public MyCBModel(List<String> cbData)
    {
        super();
        cbData       = new ArrayList<String>(dbData);
        listenerList = new EventListenerList();
    } 

    protected void fireSelectionChange()
    {
        Object[]      listener = listenerList.getListenerList();
        ListDataEvent event    = null;
        
        for (int i = listener.length-2; i >= 0; i -= 2)
        {
            if (listener[i] == ListDataListener.class)
            {
                // Ist bei ComboBoxModel so: Selektionsänderung wird wie
                // folgt (mit Index -1) mitgeteilt
                if (event == null)
                    event = new ListDataEvent(
                            this,
                            ListDataEvent.CONTENTS_CHANGED,
                            -1, -1);
                
                ((ListDataListener) listener[i+1]).contentsChanged(event);
            } //if
        } //for
    }
    
    @Override
    public void addListDataListener( ListDataListener l )
    {
        listenerList.add(ListDataListener.class, l);
    }

    @Override
    public void removeListDataListener( ListDataListener l )
    {
        listenerList.remove(ListDataListener.class, l);
    }
   
    @Override
    public Object getSelectedItem()
    {
        return selected;
    }

    @Override
    public void setSelectedItem( Object anItem )
    {
        selected = anItem.toString();
        this.fireSelectionChange();
    }

    @Override
    public Object getElementAt( int index )
    {
        return cbData.get(index);
    }

    @Override
    public int getSize()
    {
        return cbData.size();
    }
}
```

Beim Verfassener eigener Modelle ist die Handhabung der Listener dann eine weitere Herausforderung. Hier muss zB bei setSelectedItem(Object) den Listenern mitgeteilt werden, dass sich der Wert des Modells geändert hat (hab ich aus DefaultComboBoxModel).

Tjo. Mit dieser Klasse kannst du dann über die DB irgendeine Liste mit Strings füllen und diese dem Konstruktor übergeben. Einer JComboBox kannst du dann direkt dieses Modell geben.


----------



## Chriss_07 (28. Mai 2010)

Hallo KrokoDiehl,
ich habe das ComboBoxModel nicht implementiert bekommen und heute klappte es auf Anhieb mit dem _Vector_. Nicht das was ich wollte, da ich nun eine Sortierung einbinden muss, die dafür aus dem Objekt wieder ein Array macht. Naja die Sortierung ist das *Eine*, die Datensätze stehen jetzt in der ComboBox aber 
	
	
	
	





```
[Ort1]
[Ort2]
```
 in den eckigen Klammern und ich weiß nicht wieso. Hast du da einen Rat?

```
public static Vector findAllOrte() throws Exception {
		
		ResultSet rs;
		Statement stmnt;
 		Vector results = new Vector();
 		
 		try {
 			openConnection();
			stmnt = conn.createStatement();
			String sql = "SELECT ort FROM combo";
			System.out.println(sql);
			rs = stmnt.executeQuery(sql);
 			 
 			while (rs.next()) {
 				Vector ort = new Vector();
// 				Collections.sort(null);
 				ort.add(rs.getString("ort"));
// 				Arrays.sort();
 				results.add(ort);
 				
 			}
 
 		} catch (SQLException e) {
 			e.printStackTrace();
 		}
 		disconnet();
 		return results;
```


```
DefaultComboBoxModel Model= new DefaultComboBoxModel();
		fromCB = new JComboBox();
		
		
		Vector results = DBconnectdb.findAllOrte();

		JComboBox fromCB = new JComboBox(results);
		fromCB.setBounds(15, 50, 200, 20);
		add(fromCB);
```

Gruß Chriss


----------



## Chriss_07 (31. Mai 2010)

Leider bekomme ich die Objekte aus dem Vector nicht sauber in die ComboBox, daher würde ich gerne den Vorschlag mit dem Model nochmal aufgreifen.

Wenn ich die Datenbankabfrage in ein Array übergebe

```
public final static ArrayList<String> cbData = new ArrayList<String>();
```
Soll dieses vom ComboBoxModel 
	
	
	
	





```
MyCBModel.java
```
verwaltet werden und dann von der ComboBox 
	
	
	
	





```
NewJFrame.java
```
 instanziert werden.
Also muss ich doch eine Referenz in MyCBModel auf das Array in der Datenbankabfrage schreiben?

```
public MyCBModel(List<String> cbData)
    {
        super();
        DBconnectdb model       = new DBconnectdb(arrayList);
        listenerList = new EventListenerList();
    }
```
Und eine weitere auf das Model.

```
JComboBox from2CB = new JComboBox(Model1);
		Collection<Object> col = System.getProperties().values();
		ArrayList<Object> arrayList = new ArrayList<Object>(col);
		MyCBModel cbData = new MyCBModel(arrayList);
```

Vielleicht kannst du mir da weiterhelfen, wie instanziere ich das Array bis zur ComboBox?
MfG Chriss


----------



## Chriss_07 (31. Mai 2010)

Ne Ok, das war ein Denkfehler von mir:noe:
Ich muss das Array ja direkt der ComboBox übergeben, das Model verwaltet diese ja nur.

```
MyCBModel Model1= new MyCBModel(DBconnectdb.cbData);
```


----------

