I'm trying to make a simple applet with java to show two counters. To simplify the code i created a function named "suma" which is called 2 times in run(). The counters in the console works, but in the applet aren't increased. I thing the problem is in repaint(), because when i try to execute the content of "suma" in run directly the code works. The question is: Why repaint() don't works out of run()?
import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
public class HiloContador extends Applet implements Runnable{
//Propiedades
private Thread h1;
private Thread h2;
long contador1=0;
long contador2=500;
private Button b1,b2;
public void start(){}
public void init(){
setBackground(Color.YELLOW);
//Botones
add(b1=new Button("Parar hilo 1"));
add(b2=new Button("Parar hilo 2"));
//Creación de nuevos hilos y su inicio
h1=new Thread(this);
h2=new Thread(this);
h1.start();
h2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
suma(h1,contador1);
suma(h2,contador2);
}//fin de run
public void paint(Graphics g){
g.drawString(Long.toString((long)contador1), 80, 100);
g.drawString(Long.toString((long)contador2), 80, 120);
}
public void suma(Thread h,long c){
Thread hiloActual=Thread.currentThread();
while(h==hiloActual){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(c);
c++;
repaint();
}//fin de while
}
}
This is because when you provide a primitive type like a long
to a method, you pass its value not its reference such that when you increment c
in your method suma
you don't actually modify the value of your variables, you just increment the provided value, use AtomicLong
instead of long
as parameter of your method since it will then be passed by reference as it is no more a primitive type but an object reference, then increment its internal value with incrementAndGet()
and get it with get()
.
Your code would then be:
...
AtomicLong contador1 = new AtomicLong();
AtomicLong contador2 = new AtomicLong(500);
...
public void paint(Graphics g){
g.drawString(Long.toString(contador1.get()), 80, 100);
g.drawString(Long.toString(contador2.get()), 80, 120);
}
public void suma(Thread h, AtomicLong c){
...
System.out.println(c);
c.incrementAndGet();
repaint();
...
}
More details about pass-by-reference/pass-by-value