I am writing a program in Java and I want to add a loading page where it displays a progress bar and a label saying what is loading and the bar showing how far it is to completing, I have everything set up so it should work but it doesn't, I do not know what is wrong (I am new to java so please have mercy)
I have tried having a boolean that is set to false by default and is set to true only after "after-all-set-code" has been executed (I am using netbeans to create the GUI) and when I call the function to update the text/progress bar, if the boolean is still set to false it will wait a second and retry till the "all-set-code" changes it to true, but that doesn't seem to work.
This is inside my main
class
public class Xtra {
public static loadingPage LP = new loadingPage();
public static void main(String[] args) {
// Show loading page
LP.main(args);
// Set loading
LP.setLoading(0, "Fetching Config...");
// Get Config
// Durring the "getConfig" function it calls the function "LP.setLoading()" multiple times to update the loading bar & text
Xtra.getConfig();
// Set loading
LP.setLoading(0, "Loading user data...");
}
}
This is my setLoading()
class inside of loadingPage
:
public void setLoading(int per, String txt) {
if ("".equals(txt)) {
setLoadingValue(per);
} else {
setLoadingText(txt);
setLoadingValue(per);
}
}
This is my setLoadingValue()
function:
public void setLoadingValue(int x) {
// This will turn true when the after-all-set code runs
while (!loadingBarLoaded) {
// Try to wait a second,
// Do this so it doesn't take up too much CPU
try {
// Wait a second
TimeUnit.SECONDS.sleep(1);
// Print to console
System.out.println("Loading value not loaded,\nWaiting another second");
// If there is an error waiting
} catch (InterruptedException ex) {
// Alert user
System.out.println("You cannot sleep now, monsters are nearby");
}
}
// After loaded boolean turns true
// Alert user of change
System.out.println("Setting loading value to " + x + "%");
// Change value
loadingBar.setValue(x);
}
This is my setLoadingText()
function:
public void setLoadingText(String txt) {
// This will turn true when the after-all-set code runs
while (!loadingTextLoaded) {
// Try to wait a second,
// Do this so it doesn't take up too much CPU
try {
// Wait a second
TimeUnit.SECONDS.sleep(1);
// Print to console
System.out.println("Loading text not loaded,\nWaiting another second");
// If there is an error waiting
} catch (InterruptedException ex) {
// Alert user
System.out.println("You cannot sleep now, monsters are nearby");
}
}
// After loaded boolean turns true
// Alert user of change
System.out.println("Setting loading text to \"" + txt + "\"");
// Change value
loadingText.setText(txt);
}
and my after-all-set-code
is loadingTextLoaded = true
& loadingBarLoaded = true
depening on what is finished
It's supposed to update the text and the value of the progress bar but it isn't, it is outputting the Settings loading text to "..."
to the console & the Setting loading value to ...%
to the console as well, but not changing the actual value or text of the components.
What am I doing wrong?
Minimalistic problem: (Main file)
// Inside main function
// Show loading page
LP.main(args);
LP.loadingBar.setValue(50);
LP.loadingText.setText("Hello");
// nothing changes. (Both are public so I can call them from different files
This is what the loadingBar
& loadingText
vars and declared like
public javax.swing.JProgressBar loadingBar;
public javax.swing.JLabel loadingText;
loadingBarLoaded
& loadingTextLoaded
is declared like this
public boolean loadingTextLoaded = false;
public boolean loadingBarLoaded = false;
loadingTextLoaded
& loadingBarLoaded
and changed to true after all the generated code puts them into place inside the window after the all-set-code
is ran (I am using NetBeans GUI builder so the code is generated)
Inside the loadingPage.java this is how it is laid out.
The main window and there is a panel covering the entire main window and it has three things inside of it, a label at the top that sits in the middle, it has the application name "Xtra" and below it the loadingText
subtitle that small and says what is currently loading, below that, a progress bar loadingBar
.
Here is a screen shot of the layout
Sorry if I am not following the unwritten coding rules, I only started with java like a week ago.
Learn about threading in swing. You have to use a SwingWorker and do the loading in the doInBackground() method and return progress there.
import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class Main {
private JProgressBar prog;
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(()-> new Main().initGUI());
}
private void initGUI(){
JDialog dialog = new JDialog();
dialog.setTitle("Progress");
prog = new JProgressBar();
prog.setMaximum(100);
dialog.add(prog);
dialog.pack();
dialog.setVisible(true);
BackgroundWorker bw =new BackgroundWorker();
bw.execute();
}
private class BackgroundWorker extends SwingWorker<String, Integer>{
@Override
protected String doInBackground() throws Exception {
try{Thread.sleep(1000);}catch(Exception e){}
publish(10);
try{Thread.sleep(1000);}catch(Exception e){}
publish(20);
try{Thread.sleep(1000);}catch(Exception e){}
publish(30);
try{Thread.sleep(1000);}catch(Exception e){}
publish(70);
try{Thread.sleep(1000);}catch(Exception e){}
publish(100);
return "finished";
}
@Override
protected void process(List<Integer> chunks) {
prog.setValue(chunks.get(chunks.size()-1));
}
}
}
Important is, that you don't access any Swing Component from the doInBackground() method, as this method is not called from the Swing Event Dispatch Thread.
I fixed it, when the GUI builder created the page it used this code
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new loadingPage().setVisible(true);
}
});
I changed it to:
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
LP.setVisible(true);
}
});
and at the begining of the file I put this: public static loadingPage LP = new loadingPage();
and it seemed to work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.