¿Por qué no se llama el repintado de mi panel?
-
03-07-2019 - |
Pregunta
Tengo un problema que parece que no puedo solucionar con una pequeña animación. Para un proyecto, estamos diseñando una aplicación J9 para ejecutar en una PDA (DELL Axim X51). El código problemático (que se muestra a continuación) es cuando se detecta un clic del mouse para ejecutar una pequeña animación en un panel anidado. Si la animación se ejecuta independientemente del clic del ratón, funciona bien y se vuelve a pintar perfectamente. Cuando se llama al método cuando se reconoce un clic del mouse, se repinta el repintado en cada intervalo de animación y solo una vez que se completa la animación, se repintará el panel.
Creo que podría tener algo que ver con cuando se reconoce el clic del mouse, la aplicación se sincroniza consigo misma, y ??detiene las llamadas a los métodos internos para pintar O que la operación de pintura no tenga la suficiente prioridad sobre el clic del ratón.
Mi 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);
}
}
Solución
En StatusLoader.start
, usa Thread.run
en lugar de Thread.start
. Eso significa que StatusLoader.run
se ejecuta en el hilo de eventos, que es una cosa muy mala. Cámbielo por t.start ()
.