Repaint() 无法使用 运行() 函数
Repaint() is not workning out of run() function
我正在尝试用 java 制作一个简单的小程序来显示两个计数器。
为了简化代码,我创建了一个名为 "suma" 的函数,它在 运行() 中被调用了 2 次。控制台中的计数器有效,但小程序中的计数器没有增加。我认为问题出在 repaint() 中,因为当我尝试直接在 运行 中执行 "suma" 的内容时,代码有效。
问题是:为什么 repaint() 在 运行() 之外不起作用?
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
}
}
这是因为当您向方法提供像 long
这样的基本类型时,您传递的是 它的值 而不是它的引用,这样当您递增 c
在你的方法 suma
你实际上并没有修改变量的值,你只是增加提供的值,使用 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()
.
您的代码将是:
...
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();
...
}
有关 pass-by-reference/pass-by-value 的更多详细信息
我正在尝试用 java 制作一个简单的小程序来显示两个计数器。 为了简化代码,我创建了一个名为 "suma" 的函数,它在 运行() 中被调用了 2 次。控制台中的计数器有效,但小程序中的计数器没有增加。我认为问题出在 repaint() 中,因为当我尝试直接在 运行 中执行 "suma" 的内容时,代码有效。 问题是:为什么 repaint() 在 运行() 之外不起作用?
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
}
}
这是因为当您向方法提供像 long
这样的基本类型时,您传递的是 它的值 而不是它的引用,这样当您递增 c
在你的方法 suma
你实际上并没有修改变量的值,你只是增加提供的值,使用 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()
.
您的代码将是:
...
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();
...
}
有关 pass-by-reference/pass-by-value 的更多详细信息