Progress indicator in Java - java

I am having a Jasper report where I am exporting it into PDF using the Java code. My java application is in Swing. I need the Java application to display 'Please wait' message while the work is report is properly exported.
I can remember I did this sometime back with just 4 lines of code, I can't remember what they are now. What I managed to do was display a small note in the screen which says "Please Wait" and which disappears as soon as the work is done. As far I can remember, it is a built in Swing functionality.

> You can use swing worker for that
SwingWorker sw = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
// TODO Auto-generated method stub
progressBar.setVisible(true);
status.setVisible(true);
progressBar.setIndeterminate(true);
progressBar.setBackground(getForeground());
//do some task & it will return something, like
int flag = logRunningThread();
return null;
}
#Override
public void done() {
progressBar.setIndeterminate(false);
progressBar.setBackground(getForeground());
progressBar.setVisible(false);
//After Success Message
System.out.println("Task Completed")
status.setVisible(false);
progressBar.setValue(100);
}
};
sw.execute();
Also take 2 variable
private JProgressBar progressBar;
private JLabel status;
& add them to panel & frame.

Related

Invalid Thread Access: SWT in AWT ActionListener

Trying to get rid of this SWTException: Invalid thread access. Generated from within a JButton ActionListener. Ultimate intent is to have button open a Browser window, navigates to a URL and then URL is brought back to opening dialog...
private static final Display display = Display.getDefault();
// Fired from JButton:
class ShowBrowserAction implements java.awt.event.ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// Place-holder UI Update...
display.asyncExec(new Runnable() {
public void run() {
System.out.println("Async task run");
}
});
// Blocking until UI element is done...
while (!display.isDisposed()) {
// Always gives a thread access error, but still calls async event:
if ( !display.readAndDispatch() )
display.sleep();
}
}
}
Thoughts?
You can only call SWT actions on the SWT UI thread. Calling them anywhere else is not supported.
Use syncExec rather than asyncExec if you want to wait for a UI runnable to complete.
You say it seems to work, but this will vary on different platforms. For example on macOS it will definitely fail completely.

Reentering Method with New Thread in Java with Swing GUI

I am a beginner with multithreading and GUI development in Java with Swing and Window Builder in Eclipse.
I am trying to get a jlabel that shows the status of the program to display text and quickly fade from red to black when a button is pressed and then to disappear in ten seconds.
I tried to combine suggestions for this from several answers on Stack Overflow using a new thread and a timed task (How to fade color from white to black?) and the code works correctly the first time the button is pressed. However, when the button is pressed again and the method is called again, it only briefly blinks red and the text disappears very quickly.
I believe that it is because when the button is pressed a second time the old thread is still running and both are trying to control the label. I obviously found several question on Stack Overflow on how to kill treads in Java (including How do you kill a thread in Java?), but none of them seemed to help in my situation. I am relatively inexperienced with multithreading and Swing GUIs, so I probably made some really dumb mistakes with my code.
Here it the method that is called by a event listener when a button is pressed (this method is in a separate "Program Main" controller class):
private static void setBriefLblStatus(String content) {
one = new Thread() {
public void run() {
setLblStatus(content);
fading = Color.RED;
TimerTask fadingTask = new TimerTask() {
#Override
public void run() {
if (fading.getRed() > 0) {
fading = new Color(fading.getRed() - 1, 0, 0);
setLblStatusColor(fading);
}
}
};
timer = new Timer();
timer.scheduleAtFixedRate(fadingTask, 7, 7);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setLblStatus("");
}
};
one.start();
}

How to use Timer and SwingWorker in an Eclipse Plugin?

I'm developing an Eclipse plugin that will contribute to the GUI with a view.
The view is updated with informations from a versioning system when the user selects a folder or a file in the workspace.
In order to avoid collecting data everytime the user goes through the project subfolders and files, I need to wait for 3 seconds in order to be sure that the file or folder is the one of interest.
I'm currently doing this using a Swing Timer.
This is ok for small amount of data, but for large amount of data the GUI blocks, waiting for the timer to execute the update function.
I know for this kind of task I can use SwingWorker but I can't figure out how to delay the task and to restart the delay when needed.
Can anyone give me a solution on how to correctly solve this problem ?
Here is my current code:
public void resetTimerIfNeeded()
{
if(timer.isRunning())
timer.restart();
else
timer.start();
}
public void timer()
{
selectionTimer = new Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
Display.getDefault().syncExec(new Runnable(){
#Override
public void run()
{
updateView();
selectionTimer.stop();
}
});
}
});
}
Since Eclipse uses SWT rather than Swing it is best to avoid using Swing code.
You can run code in the UI thread after a delay using UIJob, something like:
UIJob job = new UIJob("Job title") {
#Override
public IStatus runInUIThread(IProgressMonitor monitor) {
updateView();
return Status.OK_STATUS;
}
};
job.schedule(3000);
Alternatively you can use Display.timerExec:
Display.getDefault().timerExec(3000, new Runnable(){
#Override
public void run()
{
updateView();
}
});
Schedule it as a Job instead: https://eclipse.org/articles/Article-Concurrency/jobs-api.html . Use a UIJob if the entirety of what it's doing is interacting with the UI. The cancel/schedule and sleep/wakeUp methods will be of interest , see http://help.eclipse.org/luna/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/runtime/jobs/Job.html for the JavaDoc.

how to using swingworker to a jprogressbar <update> [duplicate]

This question already has answers here:
Can a progress bar be used in a class outside main?
(3 answers)
Closed 8 years ago.
I have a swingworker that will be representing a jProgressbar. This is the code
private Swingworker timeOfProccess;
class Swingworker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
jProgressBar1.setStringPainted(true);
int progress = 0;
setProgress(0);
while (progress <= 100) {
jProgressBar1.setValue(progress);
Thread.sleep(5);
progress++;
}
mainProccess();
return null;
}
#Override
protected void done() {
jProgressBar1.setValue(100);
JOptionPane.showMessageDialog(null, "Proses Selesai");
jProgressBar1.setValue(0);
jProgressBar1.setStringPainted(false);
}
}
private void btnExecuteActionPerformed(java.awt.event.ActionEvent evt) {
timeOfProccess = new Swingworker();
timeOfProccess.execute();}
I dont know, why the progressbar running is uncontrolled. it is so fast to 100% even the process still working. But void done is success to pop-up the JoptionPane after main process end. where is I am lost in my code. thanks..
Visit How to Use Progress Bars where You will find good examples on progress bar along with detail description.
Don't use Thread.sleep() that sometime hangs the whole swing application instead try with Swing Timer that is most suitable for swing application.
Read more How to Use Swing Timers
sample code:
// delay for 1500 mill-seconds
Timer timer = new javax.swing.Timer(1500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// call for your next task
}
});
timer.setRepeats(true); // you can turn off the repetition
timer.start();
How to get the progressbar showing the number 1 - 100 %.
Use JProgressBar#setStringPainted() method to show the percent done status.

GUI not updating the image on every click because new image of graph take time in generating every new image, so GUI show the previous image

i am having problem in displaying the current on the GUI, i am using Swing Worker which is not working according to my requirements. kindly someone help me to update image on every click while image generation take time because image is generated through graph viz. i am struck in my project ...enter code here
private static void show1(){
SwingWorker<Void,Void> worker1= new SwingWorker<Void,Void>(){
#Override
protected Void doInBackground() throws Exception {
Thread.sleep(100);
gp.GraphPanel();// here in graph panel image is not updated
return null;
}
protected void done() {
}
};
worker1.execute();
}
// show1 is called inside action listener
public static JScrollPane GraphPanel()
{ // some code here
ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
label.setIcon( imgIcon);
pane2.add(label);
JScrollPane grphPane= new JScrollPane(pane2);
return grphPane;
}
Aqua's answer is the correct means by which you should use SwingWorker, but, you're doing nothing with the resulting the instance JScrollPane you're creating in the GraphPane method
This method creates a new instance of GraphPane...
public static JScrollPane GraphPanel()
{ // some code here
ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
label.setIcon( imgIcon);
pane2.add(label);
JScrollPane grphPane= new JScrollPane(pane2);
return grphPane;
}
But calling it like...
gp.GraphPanel();
Does nothing with it, you should be adding the result of this method to your UI...
Based on your code example, label seems to be an instance variable, if it's already on the screen, you should simply set its icon property and let the UI update it self
public void updateGraph()
{ // some code here
ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
label.setIcon( imgIcon);
}
Also, avoid static where possible, it's a good indication that your design needs work
You should access Swing components only from Event Dispatch Thread. You on the other hand attempt to build and access JScrollPane from doInBackground. SwingWorker's doInBackground is executed on auxiliary worker thread. This is where the background task should happen. If the image preparation takes time, you can execute this action in doInBackground. Then, override done() method where you can add the resulting image to UI. done() is executed on Event Dispatch Thread. See Concurrency in Swing for more details.
Here is a simple example:
class Worker extends SwingWorker<Image, Void> {
#Override
protected Image doInBackground() throws Exception {
Image image = ImageIO.read(new File("some path"));
//TODO process the image
return image;
}
#Override
protected void done() {
try {
Image image = get();
//TODO use the image
//ImageIcon imgIcon = new ImageIcon(image);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Categories