PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SWT Splashscreen Thread problem



Demo
09-03-2005, 13:47
Hi,

ich versuch mich grad an einem SplashScreen, bei dem waehrend der Anzeige Verzeichnispruefungen vorkgenommen werden. Anschliessend soll ich das Hauptfenster oeffnen, es wird als eine neue Instanz der Haupotfensterklasse erzeugt.

Das ganze mit SWT und Java. Das funktioniert alles prima, nur beim punkt, an dem die Hauptklasse erzeugt wird bekomme ich :



Exception in thread "main" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:2827)
at org.eclipse.swt.SWT.error(SWT.java:2752)
at org.eclipse.swt.SWT.error(SWT.java:2723)
at org.eclipse.swt.widgets.Display.checkDisplay(Displ ay.java:594)
at org.eclipse.swt.widgets.Display.create(Display.jav a:705)
at org.eclipse.swt.graphics.Device.<init>(Device.java:123)
at org.eclipse.swt.widgets.Display.<init>(Display.java:412)
at org.eclipse.swt.widgets.Display.<init>(Display.java:408)
at org.MainWindow.startHere(MainWindow.java:130)
at org.Splash$1.run(Splash.java:106)
at org.eclipse.swt.widgets.Display.timerProc(Display. java:3084)
at org.eclipse.swt.internal.gtk.OS._g_main_context_it eration(Native Method)
at org.eclipse.swt.internal.gtk.OS.g_main_context_ite ration(OS.java:1095)
at org.eclipse.swt.widgets.Display.readAndDispatch(Di splay.java:2395)
at org.Splash.<init>(Splash.java:111)
at SWTHydra.main(SWTHydra.java:22)

hiermal die Klasse:


/*
* Created on 09.03.2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org;
import java.io.File;

import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
* @author demo
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class Splash {
private Display d;
private Shell splash;
private Device device = null;
boolean done=false;
public Splash(){
d = new Display();
splash = new Shell(d,SWT.NONE);
RGB rgb = new RGB(203,221,249);
Color backColor = new Color(device,rgb);
GridLayout layout = new GridLayout(2,false);
GridData picData = new GridData(SWT.FILL,SWT.FILL,true,false,2,0);
GridData barData = new GridData(SWT.FILL,SWT.FILL,true,false,2,0);
GridData leftLabelData = new GridData(SWT.FILL);
GridData rightLabelData = new GridData(SWT.FILL);

splash.setLayout(layout);
final Image SplashImg = splashImage();
Label splashLabel = new Label(splash,SWT.NONE);
splashLabel.setImage(SplashImg);
splashLabel.setLayoutData(picData);

final ProgressBar bar = new ProgressBar(splash,SWT.SMOOTH);
bar.setLayoutData(barData);

final Label leftLabel = new Label(splash,SWT.NONE);
leftLabel.setLayoutData(leftLabelData);
leftLabel.setBackground(backColor);
leftLabel.setText("Suche Arbeitsverzeichnis...");
final Label rightLabel = new Label(splash,SWT.NONE);
rightLabel.setBackground(backColor);
rightLabel.setText(getOs());

splash.pack();
splash.open();

d.timerExec(1000,new Runnable(){
public void run(){
int value=bar.getSelection();
int max = 0;

while(max!=100){
String userDir;

userDir = System.getProperty("user.home","not specified");
System.out.println(userDir);

String path = userDir + "/swthydra";

File dataDir = new File(path);
if(dataDir.exists()){
System.out.println(path + "existiert");
leftLabel.setText("Arbeitsverzeichnis gefunden");
bar.setSelection(value+100);
max=bar.getSelection();
System.out.println(value);
d.timerExec(1000,this);
try{
Thread.sleep(1000);
}catch(Throwable e){}
}else{
System.out.println(path + "existiert nicht");
leftLabel.setText("Arbeitsverzeichnis nicht gefunden");
bar.setSelection(value+30);
System.out.println(value);
System.out.println("erzeuge Arbeitsverzeichnis");
leftLabel.setText("erstelle Arbeitsverzeichnis");
bar.setSelection(value+40);
max=bar.getSelection();
System.out.println(value);
if(dataDir.mkdir()){
System.out.println("Verzeichnis erstellt");
leftLabel.setText("Arbeitsverzeichnis erstellt");
bar.setSelection(value+30);
max=bar.getSelection();
}else{
System.out.println("Error");
}
}
}//ende while
splash.dispose();


done=true;
MainWindow myWin = new MainWindow();
myWin.startHere("hydra");
}
});

while(!splash.isDisposed()){
if(d.readAndDispatch()) d.sleep();
}
d.dispose();
SplashImg.dispose();
//device.dispose();
}


private static String getOs(){
String arch = System.getProperty("os.arch");
String os = System.getProperty("os.name");
String version = System.getProperty("os.version");

String all = arch + " / " + os + " / " + version;
return all;
}//end get Os

private Image splashImage(){
Image img = null;
String resourceSplash = "gui/pixmaps/splash.png";
img = new Image(d,getClass().getResourceAsStream(resourceSpl ash));
return img;

}//end SplashImage
private void senseless(){
System.out.println("senseless");
}//end senseless

}
ich weiss jetzt zumindest das es wohl nicht so einfach ist, andere Objekte aus dem User Interface Thread herruas zu erstellen.

Hat einer von euch Javanern ne Idee, wie man das loesen koennte ?

Gruss,
Demo

peschmae
09-03-2005, 18:53
Ich verstehe die Sache noch nicht ganz - wie das funktioniert und wer was tut aber generell darfst du nur in dem Thread, der die Nachrichtenverarbeitungsschleife von Swt erstellt einfach so mit GUI-Sachen hantieren.

Willst du das aus einem anderen Thread machen - hier der Fall - dann musst du den Code, den du ausführen willst dem Haupt-Thread in Form eines Runnable-Objekts übergeben. Dazu dient dir die Methode, d->syncExec() oder
d->asyncExec(new Runnable() {
void run() {
//hier Fenster erzeugen
}
}
);

Oder so ähnlich, eventuell stimmt der Syntax nicht ganz, hab schon ne Weile nicht mehr SWT benutzt.

MfG Peschmä

Demo
09-03-2005, 19:20
ich versuchs mal zu erklaeren.

Bei Programmstart erfolgt der SplashScreen, waehrend der Screen auf dem Bildschirm sichtbar ist werden bestimmte Einstellungen geladen und vorgenommen. Sind diese abgschlossen, soll sich das Hauptfenster oeffnen. Das Hauptfenster befindet sich aber in einer anderen Klasse, sprich nach Abschluss des SplashScreens muss ein Objekt dieser Klasse erzeugt werden. Ich steh momentan halt auf dem Schlauch, wie ich das am besten regeln kann, die Problematik, die Du mir in deinem ersten Satz geschildert hast, hab ich erkannt - aber da hoerts dann schon auf ...

peschmae
11-03-2005, 21:34
Dann hab ich das richtig Verstanden. Einfach den Code von mir und beim // die beiden Fenstererzeugzeilen - also

MainWindow myWin = new MainWindow();
myWin.startHere("hydra");

hin und dann sollte das gehen.

MfG Peschmä