В чем здесь упущение / ошибка? - PullRequest
0 голосов
/ 29 сентября 2010

В следующем коде должна быть ошибка / упущение, но я не могу увидеть, где именно, потому что я никогда не использовал потоки. Может кто-нибудь найти, что мне не хватает?

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JDialog;
import javax.swing.JLabel;

public class JavaSwingTest extends JDialog {
    private JLabel m_countLabel;

    private Timer m_timer = new Timer();

    private class IncrementCountTask extends TimerTask {
        @Override
        public void run() {
            m_countLabel.setText(Long.toString(System.currentTimeMillis() 
/ 1000));
        }
    }

    private JavaSwingTest() {
        createUI();

        m_timer.schedule(new IncrementCountTask(), 1000, 1000);
    }

    private void createUI() {
        Button button1 = new Button("Action1");
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                doLongOperation();
            }

        });
        add(button1, BorderLayout.NORTH);

        m_countLabel = new JLabel(Long.toString(System.currentTimeMillis() 
/ 1000));
        add(m_countLabel, BorderLayout.CENTER);
    }

    /**
     * Simulates an operation that takes time to complete.
     */
    private void doLongOperation() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // ignored for this test
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new JavaSwingTest().setVisible(true);
    }
}

Ответы [ 3 ]

1 голос
/ 29 сентября 2010

Как уже говорили другие, setText() следует вызывать из потока рассылки событий Swing, поскольку он не является потокобезопасным. Самый простой способ исправить это - использовать javax.swing.Timer (который вызывает действие уже на EDT), а не java.util.Timer.

1 голос
/ 30 сентября 2010

Использование SwingWorker позволит вашему doLongOperation() выполняться без блокировки EDT, а также предлагает удобный способ периодического обновления графического интерфейса.Вот полный пример здесь .

1 голос
/ 29 сентября 2010

Swing, как и большинство инструментов UI, не является поточно-ориентированным.Ваш вызов setText () должен быть перенаправлен в поток событий.

Чтобы запустить работу графического интерфейса из потока таймера, используйте SwingUtilities .invokeLater () или invokeAndWait ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...