Tenho um JLabel com um evento para mostrar a data e hora atuzalizados de segundo em segundo. A data e hora que é mostrada é obtida de uma classe (extende Thread), que foi criada devido a requisitos. (não pode ser obtida a hora do micro).
Quando clico em um dos botões da barra de títulos (minimizar, restaurar ou fechar) e mantenho pressionado sem soltar o botão do mouse, a hora deixa de ser atualizada no JLabel, e durante o tempo que permaneço clicando em um dos botões o relógio atrasa. Estou desenvolvendo em Java faz pouco tempo, pesquisei e não consegui descobrir porque isso ocorre. Qualquer informação a respeito será bem vinda, obrigado.
Olha esse código
public class TimerTest extends JPanel {
JLabel label;
JButton startButton;
JButton stopButton;
DateFormat dateFormat;
Timer timer;
public TimerTest() {
this.dateFormat = new SimpleDateFormat("HH:mm:ss");
this.initialize();
}
protected void initialize() {
this.add(this.getLabel());
this.add(this.getStartButton());
this.add(this.getStopButton());
this.go();
}
public JLabel getLabel() {
if (this.label == null) {
this.label = new JLabel(getTime());
this.label.setPreferredSize(new Dimension(100, 22));
}
return this.label;
}
public JButton getStartButton() {
if (this.startButton == null) {
this.startButton = new JButton("Start");
this.startButton.setPreferredSize(new Dimension(75, 22));
this.startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!timer.isRunning()) {
timer.start();
}
}
});
}
return this.startButton;
}
public JButton getStopButton() {
if (this.stopButton == null) {
this.stopButton = new JButton("Stop");
this.stopButton.setPreferredSize(new Dimension(75, 22));
this.stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (timer.isRunning()) {
timer.stop();
}
}
});
}
return this.stopButton;
}
public void go() {
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.setText(getTime());
}
};
this.timer = new Timer(1000, action);
}
public String getTime() {
return this.dateFormat.format(Calendar.getInstance().getTime());
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TimerTest());
frame.setSize(300, 75);
frame.setVisible(true);
}
}
Obrigado Fábio, no seu código o problema não ocorre, mas a situação que em que ocorre o problema é um pouco diferente, mas consegui resolver, orbigado.
Para uma coisa tão simples, geralmente é mais fácil criar um Timer do Swing, ao invés de controlar a thread você mesmo. Dá uma olhada nesses exemplos, que mostram como resolver o problema com o javax.swing.Timer, java.util.Timer e com threads (página anterior):
http://www.guj.com.br/posts/list/15/52964.java#279092
Lembre-se que no caso de rodar numa thread separada, vc não poderá alterar o valor da label diretamente, assim:
Você terá que enviar uma mensagem para que a thread do Swing faça isso, assim:
EventQueue.invokeLater(new Runnable() {
public void run() {
label.setText(hora);
}
}
Caso contrário, poderá ter um comportamento bem estranho na sua aplicação… até pode ser o atraso que você estava falando. O javax.swing.Timer já dispara eventos na Thread do Swing, portanto, essa construção com EventQueue não é necessária.
Galera,
já dei uma olhada no forum e não achei. Fiz uma thread que carrega um arquivo texto. Queria poder interromper o carregamento a qualquer hora utilizando outra thread. Minha aplicação tem os botoes carregar arquivo e cancelar. como implemento o cancelar?
Veja:
http://www.guj.com.br/posts/list/52481.java#276136
E no mesmo tópico:
http://www.guj.com.br/posts/list/52481.java#276164
Ali mostra com o ThreadGroup. Como vc tem um thread só, não precisará usa-lo.
Valeu vini, vou testar em casa.