Por que é repaint do meu Painel de não ser chamado?
-
03-07-2019 - |
Pergunta
Eu tenho um problema que eu simplesmente não consigo dar a volta envolvendo uma pequena animação. Para um projeto que estamos criando um aplicativo J9 para executar em um PDA (Dell Axim X51). O código problemático (mostrado abaixo) é quando um clique do rato é detectado para executar uma pequena animação em um painel aninhada. Se a animação é executado independentemente do clique do mouse, ele funciona bem e repaints perfeitamente. Quando o método é chamado quando um clique do mouse é reconhecida a repintar a cada animação intervalo nos ignoraram e apenas uma vez a animação é concluída será o painel ser redesenhada.
I pensar que poderia ter algo a ver com quando um clique do mouse é reconhecida a aplicação é sincronizada com a própria parar quaisquer chamadas de método internas para pintar ou que a operação de pintura não tem prioridade suficientemente alta sobre o clique do mouse.
Meu código:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class StatusLoader extends Panel implements Runnable{
int progress;
public static void main(String[] args) {
Frame f = new Frame();
StatusLoader mp = new StatusLoader();
mp.setBackground(Color.yellow);
f.add(mp);
f.setSize(300,300);
f.show();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
mp.start();
}
public void start(){
Thread t = new Thread(this);
t.run();
}
public void run(){
for (int i = 0; i < 10; i++) {
progress+=10;
this.repaint(0);
System.out.println(i);
try{
Thread.sleep(100);
}catch(InterruptedException ex){}
}
}
public void paint(Graphics g){
System.out.println("called repaint");
g.setColor(Color.red);
g.setFont(new Font("Sansserif",2,24));
FontMetrics fm = g.getFontMetrics();
int stringWidth = fm.stringWidth("Loading");
g.drawString("Loading", getWidth()/2-stringWidth/2, getHeight()/2);
g.setFont(new Font("Sansserif",2,12));
fm = g.getFontMetrics();
stringWidth = fm.stringWidth("Map ziles for the new zoom level");
g.drawString("Map tiles for the new zoom level", getWidth()/2-stringWidth/2, getHeight()/2+30);
g.drawRect(getWidth()/2-100, getHeight()/2+60, 200, 10);
g.setColor(Color.blue);
g.fillRect(getWidth()/2-100, getHeight()/2+60, progress*2, 10);
}
}
Solução
Em StatusLoader.start
, você usa Thread.run
vez de Thread.start
. Isso significa StatusLoader.run
é executado no segmento de eventos, que é uma coisa má Muito. Alterá-lo para t.start()
.