Indeterminate Progress bar wont show - java

I have an application that copies files (via ADB) to an android tablet. It takes some time so I want to display a popup with an indeterminate progress bar on it. When the copy task is complete then I want to be able to stop the progress bar and let the user close the dialog.
At the moment I have not added the extra dialog box and am just trying to get the progress bar working. The problem I have is that the progress bar is not showing at the start of the task, but I dont know why. The progressbar shows when the dialog box saying sync complete appears. The code is:
progress = new JProgressBar(0, 100);
progress.setForeground(new Color(255, 99, 71));
progress.setIndeterminate(true);
progress.setValue(0);
progress.setPreferredSize( new Dimension( 300, 20 ) );
progress.setBounds( 278, 12, 260, 20 );
progress.setVisible(false);
progress.setString("Sync in progress");
progress.setStringPainted(true);
contentPane.add(progress);
pushtotab = new JButton("");
pushtotab.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (buildpathset==1){
try{
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
progress.setVisible(true);
wiredsync();
}finally{
JOptionPane.showMessageDialog(null, "sync complete. ",null, buildpathset);
setCursor(Cursor.getDefaultCursor());
progress.setVisible(false);
}}else{
//warning in here later - TO Do
}
}
});
public void wiredsync(){
try {
Process process = Runtime.getRuntime().exec("adb" + " push "+ buildpath + " " + adbtabletsync);
InputStreamReader reader = new InputStreamReader(process.getInputStream());
Scanner scanner = new Scanner(reader);
scanner.close();
int exitCode = process.waitFor();
System.out.println("Process returned: " + exitCode);
} catch(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//end
Thanks for the help,
Andy

pooyan has the right idea -- do the long running process in a background thread -- but gives the wrong library example, since your program is a Swing program and not an Android program. The canonical answer to this for Swing is to do your long-running task in the doInBackground() method of a SwingWorker.
Please hold while I find a better example...
Something like so:
if (buildpathset == 1) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
progress.setVisible(true);
// create my SwingWorker object
final SwingWorker<Void, Void> myWorker = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
// here is my long running task, calling in background
// thread
wiredsync();
return null;
};
};
// this allows me to be notified when the SwingWorker has
// finished
myWorker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pcEvt) {
// if the SwingWorker is done
if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
// notify the user
JOptionPane.showMessageDialog(null, "sync complete. ",
null, buildpathset);
setCursor(Cursor.getDefaultCursor());
progress.setVisible(false);
try {
// one way to catch any errors that occur in
// SwingWorker
myWorker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
});
// run my SwingWorker
myWorker.execute();
} else {
// warning in here later - TO Do
}
For more on this, please check out: Lesson: Concurrency in Swing

i think your problem is that you don't use thread . I mean after you turn visibility of your progress bar to true , you should define your long task in a thread. I'm Not familiar with Swing But
take Look there for Swing (sorry if it's no use full):
http://www.java-tips.org/java-se-tips/javax.swing/how-to-handle-long-running-tasks-in-a-swing-applic.html
and there for android :http://www.mkyong.com/android/android-progress-bar-example/

Related

Update Progress Bar Maximum after Task is Started

I am looking for an approach for updating the maximum value of a progress bar. I would like to use a determine progress bar if that is the correct way to accomplish this. Which I have setup below
final JDialog dialog = new JDialog(frame, "Progress Dialog", true);
progressBar = new JProgressBar(0, 500);
progressBar.setIndeterminate(false);
dialog.add(BorderLayout.CENTER, progressBar);
dialog.add(BorderLayout.NORTH, new JLabel("Progress..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.setSize(300, 75);
dialog.setLocationRelativeTo(frame);
At this time I do not know what the maximum for the progress bar will be. In the block below runner is an subclass of a SwingWorker. It is not until after that process starts that I know what the maximum will be for the progress bar.
// run the report in its own thread
try {
runner = ReportFactory.create(reportName, startDate, endDate);
runner.addPropertyChangeListener(progressListener);
runner.execute();
} catch (Exception e1) {
logger.error(e);
System.exit(1);
}
I have tried this with and without the invoke later.
private class ProgressListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (runner.getProgress() == 0) {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
progressBar.setMaximum(runner.getMaximumProgressSize());
// }
// });
}
progressBar.setValue(runner.getProgress());
}
}
To me, invokeLater will not work, because the task has not finished working. I have spent the better part of a day trying to get this progress bar to work. Any help or a change in direction would be greatly appreciated!
The comment above worked great!

JavaFX and multithreading - GIF does not start

I try to implement a GUI button so that when it is pressed, it performs two actions - the execution of the main code (2-3 seconds) and the display of the gif-preloader.
I used Task for this purpose, initializing and running it in the setOnAction method. Task itself, in turn, uses the showGif () method to launch the image.
Separately, they work correctly - showGif () opens GIF, Task displays a counter working in parallel with the main code in the console.
But when I put showGif () in the Task, the method does not work. It reaches the line "pane.setCenter (hb);" and stops. I thought that he didn’t have enough time to launch GIF and added a 5-second delay to the main code - that didn’t help either.
What I do wrong?
Besides Task, I also tried Platform.runLater(new Runnable) - the result is the same.
The button action:
btn_find.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
isStarted = true;
task = new Task<Object>() {
#Override protected Object call() throws Exception {
showGif();
return null;
}
};
new Thread(task).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}...
The Gif method:
protected static void showGif() {
System.out.println("opening GIF...");
File file = new File("/Users/user/Desktop/cat-preloader.gif");
String localUrl = null;
try {
localUrl = file.toURI().toURL().toString();
} catch (Exception e) {
e.printStackTrace();
}
Image image = new Image(localUrl, 200,200, false, true);
ImageView imageView = new ImageView(image);
hb = new HBox();
hb.setStyle("-fx-background-color: lightgrey");
hb.setOpacity(0.7);
hb.getChildren().add(imageView);
HBox.setMargin(imageView, new Insets(300, 100, 60, 200));
BorderPane.setMargin(hb, new Insets(0, 0,600, 0));
System.out.println("setting the pane");
// here thread execution stops
pane.setCenter(hb);
System.out.println("GIF started");
}

Java - A modeless waiting dialog with dynamic text

I need to create a dialog (message) box with the following requirements:
It should be able to change it text during it visibility period by adding periodically 1 dot to the current text it displays.
It should be modeless to avoid blocking the work of the main process. It is only a notification message for the user that a work is being processed.
It should be displayed when the process starts and disappeared when it ends. I don't mind to call it explicitly becuase I don't know how much time the task will take in advance.
The dialog should be displayed several times, each time with a different base text.
I have tried to create a modeless dialog like this:
try{
String laf = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(laf); // tell the UIManager to change the look and feel
}
catch (Exception e)
{
System.out.println("Unable to change look and feel");
}
m_optionPane = new JOptionPane(a_sText, JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION, null, new Object[]{}, null);
m_dialog = new JDialog();
m_dialog.setSize(200, 50);
m_dialog.setTitle(a_sTitle);
m_dialog.setModal(false);
m_dialog.setContentPane(m_optionPane);
m_dialog.setLocationRelativeTo(null);
m_dialog.setAlwaysOnTop(true);
m_dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
m_dialog.pack();
public void showDialog(String a_sText, boolean a_bDynamic){
if(a_bDynamic){
m_runnable = new DynamicWait(m_optionPane, a_sText);
m_thread = new Thread(m_runnable);
m_thread.start();
}else{
m_optionPane.setMessage(a_sText);
}
m_dialog.setVisible(true);
}
public void hideDialog2(){
if (m_thread != null){
m_thread.interrupt();
m_runnable = null;
m_thread = null;
}
m_dialog.dispose();
}
and then use a thread to constantly add the dots..
public class DynamicWait implements Runnable {
public DynamicWait(JOptionPane a_optionPane, String a_sText){
Log4jWrapper.writeLog(LogLevelEnum.WARN, "DynamicWait - " + a_sText + " Thread ID " + Thread.currentThread().getId());
m_optionPane = a_optionPane;
m_sText = a_sText;
}
#Override
public void run() {
while(m_bRun){
try {
m_optionPane.setMessage(m_sText);
Thread.sleep(1000);
m_optionPane.setMessage(m_sText + ".");
Thread.sleep(1000);
m_optionPane.setMessage(m_sText + "..");
Thread.sleep(1000);
m_optionPane.setMessage(m_sText + "...");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log4jWrapper.writeLog(LogLevelEnum.WARN, e.getMessage());
}
}
}
public void stopRun(){
m_bRun = false;
}
Well, all in all, I couldn't get the proper results.
I'll appreciate your advise.
Thank you.

To set delay on a button click in java?

I have a save button in a JFrame ;on clicking save the 'save' text sets to 'saving....'; I need to set that text as 'saved' after a delay of 10 seconds.How is it possible in java?
Please help...
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
This is what i did...but this wont shows as 'saving' during that delayed time.
If you want to provide the user with visual feedback that something is going on (and maybe give some hint about the progress) then go for JProgressBar and SwingWorker (more details).
If on the other hand you want to have a situation, when user clicks the button and the task is supposed to run in the background (while the user does other things), then I would use the following approach:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false); // change text if you want
new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
// Do the calculations
// Wait if you want
Thread.sleep(1000);
// Dont touch the UI
return null;
}
#Override
protected void done() {
try {
get();
} catch (Exception ignore) {
} finally {
button.setEnabled(true); // restore the text if needed
}
}
}.execute();
}
});
Finally, the initial solution that was using the Swing specific timer:
final JButton button = new JButton("Save");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Take somehow care of multiple clicks
button.setText("Saving...");
final Timer t = new Timer(10000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
button.setText("Saved");
}
});
t.setRepeats(false);
t.start();
}
});
This question & first 3 answers are heading down the wrong track.
Use a JProgressBar to show something is happening. Set it to indeterminate if the length of the task is not known, but presumably you know how much needs to be saved and how much is currently saved.
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Use a SwingWorker for long running tasks. See Concurrency in Swing for more details.
The best is to use a timer and its method execute with a delay : http://developer.apple.com/library/mac/documentation/java/reference/javase6_api/api/java/util/Timer.html#schedule(java.util.TimerTask, long). Use a timertask to wrap your runnable and that's it.

JPanel doesn't load in JFrame

I have a problem showing my progress bar when reading a file in Java.
All works as intended, user choose a file, the program must show the progress bar (but it loads an empty blank frame), process the file and then load the results on another window.
I can't get the program to show the content of the progress bar dialog.
A little help here would be really appreciated.
Here is the code of the 3 methods involved.
//this method reads the file
public void processFile(File arch) {
aFile = arch;
Thread threadForSearch = new Thread() {
#Override
public void run() {
try{
listaProveedoresTango = controladoraConsultas.traerProveedores();
listaProveedoresAFIP = new LinkedList();
BufferedReader data = new BufferedReader(new FileReader(aFile));
String s;
while ((s = data.readLine()) != null) {
//long task
}
data.close();
}catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
};
interfacesController.loadProgressBar();
threadForSearch.start();
try {
threadForSearch.join();
} catch (InterruptedException ex) {
Logger.getLogger(Controladora.class.getName()).log(Level.SEVERE, null, ex);
}
this.interfacesController.closeProgressBar();
this.interfacesController.loadResults(someStuff);
}
//load a progress bar
public void loadProgressBar(){
JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(175,20));
pb.setString("Processing Data");
pb.setStringPainted(true);
pb.setIndeterminate(true);
JLabel infoLabel = new JLabel("Reading File: ");
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent evt) {
exitSystem();
}
});
cancelButton.setVerticalAlignment(SwingConstants.CENTER);
JPanel center_panel = new JPanel();
center_panel.add(infoLabel);
center_panel.add(pb);
center_panel.add(cancelButton);
center_panel.setLayout(new BoxLayout(center_panel,BoxLayout.Y_AXIS));
dialog = new JDialog((JFrame)null, "Processing ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.setSize(100, 100);
dialog.setLocationRelativeTo(null);
dialog.pack();
dialog.setVisible(true);
}
//close the open progress bar
public void closeProgressBar(){
this.dialog.dispose();
}
Solved with SwingWorker, i post a summarized code:
public void processFile(File arch) {
aFile = arch;
final SwingWorker searchOnFile = new SwingWorker(){
#Override
protected Object doInBackground() throws Exception {
try{
BufferedReader data = new BufferedReader(new FileReader(aFile));
String s;
while ((s = data.readLine()) != null) {
//long task
}
data.close();
}catch (Exception e){ //Catch exception if any
System.err.println("Error: " + e.getMessage());
}
interfacesController.closeProgressBar();
interfacesController.loadResults(someStuff);
return null;
}
};
interfacesController.showProgressBar();
searchOnFile.execute();
}
interfacesController contains all the methods to work with GUIs, showProgressBar() is used to show the bar and closeProgressBar() do the opposite. Thank you guys!
Short of more useful code, I suggest using a SwingWorker.
An abstract class to perform lengthy GUI-interaction tasks in a background thread. Several background threads can be used to execute such tasks. ..
Given the nature of the task, you might also look at ProgressMonitorInputStream.
..creates a progress monitor to monitor the progress of reading the input stream. If it's taking a while, a ProgressDialog will be popped up to inform the user. If the user hits the Cancel button an InterruptedIOException will be thrown on the next read. All the right cleanup is done when the stream is closed.

Categories

Resources