Today I thought it would make my application look much more professional if the login-dialog is part of the splash-screen. The new extension point added in eclipse makes this possible and even provided an template implementation I could use without problem.
The process is straight forward:
- Create a Product Configuration (or use your existing one)
- Switch to the Splash-Tab
- Select in the Customization-Section the Interactive-Template
- Switch to the Overview and “Launch an Eclipse application”
You are done. That was easy, wasn’t it? To make this work you wouldn’t need any help. The tricky thing I faced starts now. In my case I’m authentificating using a database-server and to not block the UI im doing this in a seperate thread and showing a ProgressBar in the mean while.
When the application starts up the splash should look like this:

And while Logging into Database:

So the first action is to add the “Check Login”-Label and the Progress bar like this:
private Label progressLabel;
private ProgressBar progressBar;
/** many lines of code */
private void createProgressInfo() {
progressLabel = new Label(fCompositeLogin,SWT.NONE);
progressLabel.setText("Überprüfung läuft");
GridData data = new GridData();
data.horizontalIndent = F_LABEL_HORIZONTAL_INDENT - 50;
progressLabel.setLayoutData(data);
progressLabel.setVisible(false);
progressBar = new ProgressBar(fCompositeLogin,SWT.NONE|SWT.INDETERMINATE);
data = new GridData(SWT.NONE, SWT.NONE, false, false);
data.widthHint = F_TEXT_WIDTH_HINT;
data.horizontalSpan = 2;
progressBar.setLayoutData(data);
progressBar.setVisible(false);
}
private void toggelCheckProgress(boolean state) {
progressLabel.setVisible(state);
progressBar.setVisible(state);
fCompositeLogin.layout();
}
We initially set the those two widgets invisible and show them later when we start the authentification. To make this easy we add helper method to turn the visibility on and off.
The next part is to modify the handleButtonOKWidgetSelected()-method like this:
private volatile int loginStatus = -1;
/** many lines of code */
private void handleButtonOKWidgetSelected() {
final String username = fTextUsername.getText();
final String password = fTextPassword.getText();
toggelCheckProgress(true);
Thread t = new Thread() {
public void run() {
if( login(username,password) ) {
loginStatus = 1;
} else {
loginStatus = 2;
}
}
}
t.start();
}
The content of the method is straight forward. It starts a thread and executes a potentially long running task in our case login(String,String). Our task is now to sync back to the gui-thread and:
- Proceed with start up (hiding the login details from the splash-screen)
- Display Login-Failure to the user
Normally you do this using Display#(a)syncExec() but that’s not available in the splash-screen. The work-around I used as you see above is setting a special variable named loginStatus. The trick is now that you add checks for this variable to the Event-Loop method which looks like this afterwards:
private void doEventLoop() {
Shell splash = getSplash();
while (fAuthenticated == false) {
if (splash.getDisplay().readAndDispatch() == false) {
if( loginStatus == 1 ) {
loginSuccess();
} else if( loginStatus == 2 ) {
loginFailure();
}
splash.getDisplay().sleep();
}
}
}
Your are nearly done now the only two methods missing are:
private void loginSuccess() {
toggelCheckProgress(false);
fCompositeLogin.setVisible(false);
fAuthenticated = true;
loginStatus = -1;
}
private void loginFailure() {
toggelCheckProgress(false);
loginStatus = -1;
MessageDialog.openError(getSplash(),"Authentification failed","Your username or password was wrong");
}
Well that’s all. You are done and have a splash screen who is authenticating without blocking the UI-thread without Display#(a)syncExec. I need to thank Kim for pointing me to this solution and she promised that there will be added API in 3.4 to make this more easier.