Splash Screen Waiting Until Thread Finishes

Splash Screen waiting until thread finishes

Following across 2 threads is a bit confusing, but I'm going to take a stab and say this...

I don't fully understand your design here, but if the issue is that when you launch a second application the splash screen form turns white... It's most likely due to the fact that splash screen is busy executing all of that code in GetFromServer(). So busy that it has no time to re-paint itself.

To remedy this problem I would suggest that you use the BackGroundWorker component to execute the GetFromServer method. This will run that method in a separate thread and leave the form's thread free to re-paint itself.

GUI has to wait until splashscreen finishes executing

Change your way of thinking

Initialise and show the splash screen, when it's finished, initialise and show the Gui

This will require to have some way to tell who ever initialised the splash screen that it has completed, to do this, you can use a PropertyChangeListener...

public class InitSplashScreen {
//...
public void initUI(PropertyChangeListener listener) throws MalformedURLException {
showSplashScreen();
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
//...
};
worker.addPropertyChangeListener(listener);
worker.execute();
}

Then you listen for the state change property and check the state of the work...

public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
InitSplashScreen splashScreen = new InitSplashScreen();
try {
splashScreen.initUI(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if ("state".equalsIgnoreCase(name)) {
SwingWorker worker = (SwingWorker) evt.getSource();
if (worker.getState().equals(SwingWorker.StateValue.DONE)) {
Gui ui = new Gui();
}
}
}
});
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
});
}

But remember, you need to remove the splash screen from the Gui code.

You can also use this to "get" any information from the SwingWorker that the Gui might need and pass it as a parameter to the constructor or via setters depending on your needs

Also, to me, this...

Thread thread = new Thread(new InitProcess());
thread.start();

Looks like a strange thing to do within a SwingWoker. You could simply leave the JProgressBar in indeterminate mode if you don't know how much work is required

How to make Thread wait for a permission check in Splash Screen?

Move your code (to start the activity) from separate Thread to onRequestPermissionsResult method (where the permission is being granted), as follows

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == PERMISSION_COARSE_LOCATION){
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"GREAT",Toast.LENGTH_SHORT).show();
permissionGranted = true;

// Code to start activity
startActivity(new Intent(SplashScreen.this,TutorialPages.class));
finish();

}else{
Toast.makeText(this, "Permission Needed To Run The App", Toast.LENGTH_LONG).show();
permissionGranted = false;
}
}
}

UI Thread is Blocked when showing Splash Screen

A splashscreen is simply an image to 'amuse' the user while your app is loading. Use the app_load method to execute code on startup:

Like so: (in app.xaml and app.xaml.cs)

    <Application /some references to stuff/ Startup="Application_Startup" >

private void Application_Startup(object sender, StartupEventArgs e)
{
// your startupcode
}

Also, I think the BackGroundworker class is better for things like this, if you don't want to bother the UI.

SplashScreen.Close(Timespan.FromMilliseconds(int)) : Is there an Event dispatched at Timespan Complete?

I never did find an event to listen for upon completion of the TimeSpan. Also, after deciding to Not stop the threads, I chose to use DispatcherTimers instead.

(I have thinned and contained the logic into this one class for reference purposes)

using System;
using System.Windows;
using System.Windows.Threading;


namespace StartupSplash2
{

public partial class MainWindow : Window
{
private DispatcherTimer visibleTimer;
private DispatcherTimer fadeoutTimer;
private SplashScreen splash;
private int visibleTime = (4000); //milliseconds of splash visible time
private int fadeoutTime = (1500); //milliseconds of splash fadeout time

public MainWindow()
{
//hide this MainWindow window until splash completes
this.Visibility = Visibility.Hidden;
InitializeComponent();
splashIn(); //start the splash
}

private void splashIn()
{
splash = new SplashScreen("Resources/SplashScreen.png"); //ensure image property is set to Resource and not screen saver
visibleTimer = new DispatcherTimer(); //timer controlling how long splash is visible
visibleTimer.Interval = TimeSpan.FromMilliseconds(visibleTime);
visibleTimer.Tick += showTimer_Tick; //when timer time is reached, call 'showTimer_Tick" to begin fadeout
splash.Show(false, true); //display splash
visibleTimer.Start();
}

private void showTimer_Tick(object sender, EventArgs e)
{
visibleTimer.Stop();
visibleTimer = null; //clear the unused timer
fadeoutTimer = new DispatcherTimer();
fadeoutTimer.Interval = TimeSpan.FromMilliseconds(fadeoutTime); //a timer that runs while splash fades out and controlls when main window is displayed
fadeoutTimer.Tick += fadeTimer_Tick; //when fadeout timer is reached, call 'fadeTimer_Tick' to show main window
splash.Close(TimeSpan.FromMilliseconds(fadeoutTime)); //begin splash fadeout to close
fadeoutTimer.Start();
}

private void fadeTimer_Tick(object sender, EventArgs e)
{
fadeoutTimer.Stop();
fadeoutTimer = null; //clear the unused timer
splash = null; //clear the splash var
MainWindowReady(); //call method to display main window
}

public void MainWindowReady()
{
this.Visibility = Visibility.Visible;
//Here is the start of the Main Window Code
this.Content = "Ok, the app is ready to roll";
}

}
}


Related Topics



Leave a reply



Submit