0

i'm programming a thermometer whit JFreeChart, but i don't want to see it showing just one value... i need to put a final value into a JTextField (then press a button) and see how the mercury goes from 0º to than final value, i want to see how the mercury goes up.

I've made a FOR (from 0 to the final value) whith a Thread.sleep(500), and then update the dataset value with the index in the FOR, but it doesn't show me the transition, it completes the FOR and finally returns the thermometer showing the final value. I tried to refresh the chart but it didn't work.

The code in my button

final JButton btnAccept = new JButton("Accept");
    btnAceptar.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            for(int i = 0; i <= 40; i++) {
                    try {
                        Thread.sleep(500);
                    } 
                    catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                    }
                    dataset.setValue(i);
                }
        }
    });
    panel.add(btnAceptar);
adriancho5692
  • 671
  • 6
  • 8
  • _Don't_ sleep on the EDT; _do_ see [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/), for [example](http://stackoverflow.com/a/16875565/230513). – trashgod Aug 15 '13 at 00:11

1 Answers1

1

Swing is a single threaded framework. That is, all interactions and modifications to the UI are expected to be executed from within the content of the Event Dispatching Thread.

Any action which blocks this thread, will prevent the EDT from begin able to process repaint requests and processing new events (amongst other things).

The problem you have here is the fact that the actionPerformed event is fired from within the context of the EDT. Your for-next loop is now blocking the EDT, preventing from processing any paint requests...

You Could...

Use a javax.swing.Timer to trigger events at regular intervals and update the dataset value until it reaches your desired target and then stop the timer.

For example...

final JButton btnAccept = new JButton("Accept");
btnAceptar.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        dataset.setValue(0);
        Timer timer = new Timer(500, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                int current = dataset.getValue();
                if (current < 40) {
                    current++;
                    dataset.setValue(current);
                } else {
                    ((Timer)evt.getSource()).stop();
                }
            }
        });
        timer.start();
    }
});
panel.add(btnAceptar);

You Could...

Use a SwingWorker that uses a for-next loop in it's doInBackground method, publishing the new value, which will be made available to it's process method, which is executed within the context of the EDT...

For example...

final JButton btnAccept = new JButton("Accept");
btnAceptar.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        SwingWorker worker = new SwingWorker<Object, Integer> {
            protected Object doInBackground() {
                for(int i = 0; i <= 40; i++) {
                    try {
                        Thread.sleep(500);
                    } 
                    catch(InterruptedException ex) {
                        break;
                    }
                    publish(i);
                }
            }                

            protected void process(List<Integer> chunks) {
                // Only care about the last update...
                dataset.setValue(chunks.get(chunks.size() - 1));
            }
        }
    }
});
panel.add(btnAceptar);

You Could...

Roll your own Thread, which would use a for-next loop in the run method, but you'd have to use SwingUtilities.invokeLater to update the dataset within the context of the EDT, which is messy and troublesome, especially with the other two options...

Take a look through Concurrency in Swing for more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366