4

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.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Anuradha
  • 107
  • 1
  • 2
  • 11
  • `// TODO Auto-generated catch b` Please remove noise like this from posted code. In fact, logically it should be removed as soon as you do something in that method. As an aside, what you did inside the method is a +1. :) – Andrew Thompson Apr 10 '12 at 08:42
  • 2
    sleeping on the EDT is the wrong-thingy, always .. This looks like homework, is it :-) – kleopatra Apr 10 '12 at 09:02
  • @kleopatra I dont think so..I need it for making an application user friendly instead of using a message box.My view doesn't worked.Thats why i posted here......!!! – Anuradha Apr 10 '12 at 09:48
  • 1
    nothing friendly in forcing a user into unnecessary waiting ;-) – kleopatra Apr 10 '12 at 09:51
  • @kleopatra As compared with the usage of message box this is more better..and the user is not supposed to wait for so many seconds;that will adjust with the delay time... – Anuradha Apr 10 '12 at 09:56
  • @AndrewThompson You are right.. – Anuradha Apr 10 '12 at 10:00
  • *"You are right.."* I'm right about many things. ;) Care to narrow it down? – Andrew Thompson Apr 10 '12 at 10:03
  • 1
    Is your example closer to: **a)** User clicks the button and cannot do anything else while the action is running and should see some visual cue about the progress? **b)** User clicks the button (which becomes disabled till the action is completed) and continues doing things while the action runs in the background and eventually notifies the user of the completion? – Anonymous Apr 10 '12 at 11:33
  • @Anonymous exactly closer to a :) – Anuradha Apr 11 '12 at 05:43

3 Answers3

7

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();
    }
});
Community
  • 1
  • 1
Anonymous
  • 18,162
  • 2
  • 41
  • 64
  • final int delay = 10000; //milliseconds final ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { //...Perform a task... btnNewButton_5.setText("Saving....."); } }; final Timer t = new Timer(delay, taskPerformer); t.setRepeats(false); t.start();But this also doesn't works.It sets that text only after the delay time. – Anuradha Apr 10 '12 at 07:57
  • 1
    @Anuradha please don't add code in a comment (it's unreadable, as you see :-), instead edit your question. Anyway, if this doesn't work, something is wrong with your code elsewhere - time for an SSCCE – kleopatra Apr 10 '12 at 09:07
  • 2
    *"The best option to answer **your specific question**.."* The best option is to point out that it is a wrong-thinking approach. You might have noticed that (is my opinion) from my answer. ;) – Andrew Thompson Apr 10 '12 at 09:07
  • @AndrewThompson: Sometimes it has to be done in a certain way and there is no other way around (apart from changing one's job). – Anonymous Apr 10 '12 at 09:47
  • @Anonymous I understand that, but I'd prefer to hear it from the OP before presuming it. I will generally offer the alternative & wait to hear them say 'no good, coding to spec.' (before I chide them for not adding that information in the first place). Different folks, different approaches. ;) – Andrew Thompson Apr 10 '12 at 09:50
7

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.
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • +1 I agree that `JProgressBar` is a way to go. The op's question is a bit strange (either _homework_ or weird requirements) - the need to wait 10s... But to answer his question about waiting `Timer` does the job. – Anonymous Apr 10 '12 at 09:08
  • Good point. kleopatra has asked for clarification, I'll be interested to see the OP's reply. – Andrew Thompson Apr 10 '12 at 09:10
  • @Anonymous Thanks for your help;I faced this as part of my project work and this is not weird requirements for me... – Anuradha Apr 10 '12 at 09:53
2

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.

Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • 2
    The text should be updated on the EDT. The Swing timer takes care of this, but your link refers to the java.util.Timer, in which case you have to manually perform the call on the EDT (e.g. using `SwingUtilities.invokeAndWait`) – Robin Apr 10 '12 at 09:36