# JDialog anzeigen beim öffnen einer Datenbank



## Onkel Hatti (12. Aug 2008)

Moin Alle.

Ich brings nicht hin...

Folgendes. Ich habe einen Frame, in dem mein Programm abläuft. Zu Anfang möchte ich nach dem die GUI initialisiert wurde, eine Datenbank öffnen. Je nach Inhalt kann das dauern. Daher möchte ich einen Dialog ausgeben, der mir Bescheid gibt, daß die Datenbank gerade geöffnet wird.
Aber solange die Datenbank geöffnet wird, wird zwar der Dialogfensterrahmen angezeigt, aber nicht der Inhalt. Erst wenn die Datenbank geöffnet ist, dann wird der Dialoginhalt angezeigt.

Ich habs mit Threads versucht, mit SwingUitilities.invokeLater() und dem SwingWorker-Thread.
Ich brings nicht hin. Immer das Gleiche.

Kann mir jemand helfen?

Dankeschön
 Hatti

Das Hauptprogramm.


```
import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;

public class DBTest extends javax.swing.JFrame {

	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				DBTest inst = new DBTest();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public DBTest() {
		super();
		initGUI();
		openDB();
	}
	
	private void openDB()
	{
		WaitDialog wd=new WaitDialog(this);
		wd.setLocationRelativeTo(this);
		new Thread(wd).start();
		DataBase db=new DataBase("d:\\tmp\\testbase");
		db.createConnection();
		
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			pack();
			setSize(400, 300);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
```

Die Klasse der Datenbank:


```
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import javax.swing.JOptionPane;


public class DataBase{

	private String dbName;

	public DataBase(String db)
	{
		super();
		dbName=db;
	}

	public boolean createConnection()
	{
		if(!new File(dbName).exists())
		{
			return false;
		}
		try
		{
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
		}
		catch (Throwable c)
		{
			 return false;
		}
		try
		{
			String crProp="";
            Properties props = new Properties();
            props.put("user", "lookinfo");
            props.put("password", "lookinfo");
            Connection dbConn;

			dbConn = DriverManager.getConnection("jdbc:derby:"+dbName+crProp, props);
		}
		catch (SQLException s)
		{
			return false;
		}
		return true;
	}
}
```

und die Dialogklasse


```
mport java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class WaitDialog extends javax.swing.JDialog implements Runnable{
	private JLabel jLabel1;

	public WaitDialog(JFrame frame) {
		super(frame);
		initGUI();
	}
	
	private void initGUI() {
		try {
		        getContentPane().add(getJLabel1(), BorderLayout.CENTER);
			this.setSize(263, 158);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void run()
	{
	     this.setVisible(true);
	}
	
	private JLabel getJLabel1() {
		if(jLabel1 == null) {
			jLabel1 = new JLabel();
			jLabel1.setText("Datenbank wird geöffnet");
			jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
		}
		return jLabel1;
	}
}
```


----------



## Beni (12. Aug 2008)

SwingWorker, bzw. Threads, liest sich schonmal gut. Derzeit wird dein "dbCreateConnection" im EDT (Event Dispatcher Thread) ausgeführt, dieser EDT ist auch für das Neuzeichnen der GUI zuständig. Der ist also blockiert, und deshalb siehst du nichts.

Was du machen musst, ist "dbCreateConnection" in dem anderen Thread (oder noch besser, dem SwingWorker) laufen zu lassen. Es nützt hingegen nichts, den WaitDialog auszulagern, der wird nämlich trotz allem von EDT gezeichnet.


----------



## Onkel Hatti (12. Aug 2008)

Ahh, fast verstanden, glaube ich.
Der EDT ist für die gesamte Swing-GUI zuständig, und davon gibt es nur einen. Auch wenn ein GUIteil in einem anderen Thread arbeitet. Ich muss also den EDT quasi frei halten von zeitraubenden Aufgaben, die die Swing-GUI stören könnten, d.h. ich muss die "Nicht-GUI" Aufgaben in einen Thread auslagern und ggf. dem EDT Dinge über SwingUtilities.invokeLater mitteilen, damit sie in der GUI gezeichnet werden.

Hab ich das so richtig kapiert?

Danke schon mal.
 Hatti


----------



## Beni (12. Aug 2008)

Jop, da liegst du richtig.

Auf die GUI sollte man nur aus dem EDT aus zugreiffen, sonst kann es zu üblen Nebeneffekten kommen. Also du kannst aus der GUI aus einen zusätzlichen Thread starten, aber du musst dann _immer_ (bis auf ganz wenige Ausnahmen die zu suchen es sich nicht lohnt) mit invokeLater oder invokeAndWait auf die GUI zugreiffen.


----------



## Onkel Hatti (13. Aug 2008)

Super, Danke!

Hatti


----------

