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
Unsubscribe Anonymous Method in C#
What's the Strangest Corner Case You'Ve Seen in C# or .Net
Difference Between a Regular String and a Verbatim String
How to Wait For a Thread to Finish With .Net
Decimal Precision and Scale in Ef Code First
Translucent Circular Control With Text
Deserializing Json Data to C# Using Json.Net
How to Convert a C# String Value to an Escaped String Literal
Entity Framework 5 Updating a Record
How to Round a Number to Two Decimal Places in C#
Pass Extra Parameters to an Event Handler
Do You Need to Dispose of Objects and Set Them to Null
Compare Two List≪T≫ Objects For Equality, Ignoring Order
Why Doesn't C# Allow Static Methods to Implement an Interface