1、缺少对象,gg传入ball中时为空
在init中加一句:
gg=getGraphics();2、线程只执行了一次,所以只会画一个圆,应该在run中加上while(true)完整程序如下:
import java.applet.Applet;
import javax.swing.JApplet;
import java.awt.*;class ball implements Runnable{
int x,y;//position
int r;//size
int delay;
Graphics gg;
public ball(int a,int b,int c,int d,Graphics f)
{
x=a;
y=b;
r=c;
delay=d;
gg=f;
}
public void run()
{
while(true) /////////////////////////////////
try
{
Thread.sleep(delay);
if(r>=150) r=10;
r+=5;
this.paint(gg);
}catch(InterruptedException e){e.printStackTrace();}
}
public void paint(Graphics g)
{
g.drawOval(x+r,y+r,50+r,50+r);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);
}
}
public class th extends Applet{
Thread [] th;
int delay;
int number;
Graphics gg;
int []length_move;
Color []colors;
int [][]positions;
public void init()
{
gg=this.getGraphics(); /////////////////////
this.setBackground(Color.black);
super.setSize(500,500);
if(getParameter("delay")==null)
{
delay = 1000;
}
else
{
delay = Integer.parseInt(getParameter("delay"));
}
if(getParameter("number")==null)
{
number=5;
}
else
{
number = Integer.parseInt(getParameter("number"));
}
th=new Thread[number];
int i;
for(i=0;i<number;i++)
{
th[i]=null;
}
length_move=new int[number];
for(i=0;i<number;i++) length_move[i]=i*5;
colors=new Color[number];
for(i=0;i<number;i++)
{
switch(i%10)
{case 1: colors[i]=Color.red;break;
case 2: colors[i]=Color.blue;break;
case 3: colors[i]=Color.MAGENTA;break;
case 4: colors[i]=Color.yellow;break;
default: colors[i]=Color.green;
}
}
positions=new int[number][2];
int j=0;
for(i=0;i<number;i++)
for(j=0;j<2;j++)
{
positions[i][j]=100*i;
}
}
public void start()
{
for(int i=0;i<number;i++)
{
if(th[i]==null)
th[i]=new Thread(new ball(positions[i][0],positions[i][1],length_move[i],delay,gg));
th[i].start();
}
}
public void paint(Graphics g)
{
super.paint(g);
gg=g;
}
}3、好像画的时候应该清屏,不知道你程序本意如何。
在init中加一句:
gg=getGraphics();2、线程只执行了一次,所以只会画一个圆,应该在run中加上while(true)完整程序如下:
import java.applet.Applet;
import javax.swing.JApplet;
import java.awt.*;class ball implements Runnable{
int x,y;//position
int r;//size
int delay;
Graphics gg;
public ball(int a,int b,int c,int d,Graphics f)
{
x=a;
y=b;
r=c;
delay=d;
gg=f;
}
public void run()
{
while(true) /////////////////////////////////
try
{
Thread.sleep(delay);
if(r>=150) r=10;
r+=5;
this.paint(gg);
}catch(InterruptedException e){e.printStackTrace();}
}
public void paint(Graphics g)
{
g.drawOval(x+r,y+r,50+r,50+r);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);
}
}
public class th extends Applet{
Thread [] th;
int delay;
int number;
Graphics gg;
int []length_move;
Color []colors;
int [][]positions;
public void init()
{
gg=this.getGraphics(); /////////////////////
this.setBackground(Color.black);
super.setSize(500,500);
if(getParameter("delay")==null)
{
delay = 1000;
}
else
{
delay = Integer.parseInt(getParameter("delay"));
}
if(getParameter("number")==null)
{
number=5;
}
else
{
number = Integer.parseInt(getParameter("number"));
}
th=new Thread[number];
int i;
for(i=0;i<number;i++)
{
th[i]=null;
}
length_move=new int[number];
for(i=0;i<number;i++) length_move[i]=i*5;
colors=new Color[number];
for(i=0;i<number;i++)
{
switch(i%10)
{case 1: colors[i]=Color.red;break;
case 2: colors[i]=Color.blue;break;
case 3: colors[i]=Color.MAGENTA;break;
case 4: colors[i]=Color.yellow;break;
default: colors[i]=Color.green;
}
}
positions=new int[number][2];
int j=0;
for(i=0;i<number;i++)
for(j=0;j<2;j++)
{
positions[i][j]=100*i;
}
}
public void start()
{
for(int i=0;i<number;i++)
{
if(th[i]==null)
th[i]=new Thread(new ball(positions[i][0],positions[i][1],length_move[i],delay,gg));
th[i].start();
}
}
public void paint(Graphics g)
{
super.paint(g);
gg=g;
}
}3、好像画的时候应该清屏,不知道你程序本意如何。
赫赫,交大第一英才来帮你解决问题唉,帮你改程序改得留鼻血。
上面的那位大侠的改动为什么不行?
因为Applet是由多个线程来完成的。在Java中,任何一个Applet的 paint()和update()方法都是由绘图与事件处理线 程调用的,而Applet 主要的里程碑方法——init(),start(),stop()和destory() ——是由执行该Applet的应用调用的。
Applet的repaint()方法总是异步工作,你调用repaint()时,实际上是将重绘请求放入绘图与事件处理线程,绘图与事件处理线程,相当于invokeLater()的作用。
所以重绘的动作写在其它类,就象你所写的:
ball类里的代码:
g.drawOval(x+r,y+r,50+r,50+r);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);
不可能由绘图与事件处理线程调用。
所以应该把它写在Applet的paint()里面。然后其它类调用repaint()以请求重绘。
完整的代码是这样写的:package paintovi041123;import java.applet.Applet;
import javax.swing.JApplet;
import java.awt.*;class ball
implements Runnable {
int x, y; //position
int r; //size
int delay;
Graphics gg;
MyA app;
Color color;
public ball(int a, int b, int c, int d, Graphics f, MyA the_app,
Color the_color) { x = a;
y = b;
r = c;
delay = d;
gg = f;
color = the_color;
app = the_app;
} public void run() {
try {
while (true) {
Thread.sleep(20);
if (r >= 150) {
r = 10;
Thread.sleep(delay);
}
r += 5;
this.paint(gg);
}
}
catch (InterruptedException e) {}
} public void paint(Graphics g) {
app.x = x;
app.y = y;
app.r = r;
app.appColor = this.color;
app.repaint(); }}public class MyA
extends Applet {
Thread[] th;
int delay;
int number;
Graphics gg;
int[] length_move;
Color[] colors;
int[][] positions;
public int x, y; //position
public int r; //size
int started = 0;
public Color appColor; public void init() {
this.setBackground(Color.black);
super.setSize(500, 500); if (getParameter("number") == null) {
number = 5;
}
else {
number = Integer.parseInt(getParameter("number"));
}
if (getParameter("delay") == null) {
delay = 300 * number;
}
else {
delay = Integer.parseInt(getParameter("delay"));
} th = new Thread[number];
int i;
for (i = 0; i < number; i++) {
th[i] = null;
}
length_move = new int[number];
for (i = 0; i < number; i++) {
length_move[i] = i * 5;
}
colors = new Color[number];
for (i = 0; i < number; i++) {
switch (i % 10) {
case 1:
colors[i] = Color.red;
break;
case 2:
colors[i] = Color.blue;
break;
case 3:
colors[i] = Color.MAGENTA;
break;
case 4:
colors[i] = Color.yellow;
break;
default:
colors[i] = Color.green;
}
}
positions = new int[number][2];
int j = 0;
for (i = 0; i < number; i++) {
for (j = 0; j < 2; j++) {
positions[i][j] = 30 * i;
}
} } public void start() {
for (int i = 0; i < number; i++) {
if (th[i] == null) {
th[i] = new Thread(new ball(positions[i][0], positions[i][1],
length_move[i], delay, gg, this,
this.colors[i]));
th[i].start();
try {
Thread.currentThread().sleep(300);
}
catch (InterruptedException ex1) {
ex1.printStackTrace();
}
}
}
} public void paint(Graphics g) {
if (started == 0) {
++started; }
g.setColor(this.appColor);
g.fillOval(x + r, y + r, 50 + r, 50 + r); }}
没几日就将java研究那么深入,值得学习。
有几事不明:
1、照阁下程序,ball类中根本不需要Graphics gg,去掉完全可以,是不是不符合英才优化原则。
2、本人不才程序中通过
gg=this.getGraphics();
获取applet的grahpics再传入ball类中,实际也是在applet上画图,有何不对了?为啥说不行?如果说没有清屏,那我承认没做。
3、人家要画6个圆,英才的程序满眼是圆,眼拙没看出是几个。
2、本人不才程序中通过
gg=this.getGraphics();
获取applet的grahpics再传入ball类中,实际也是在applet上画图,有何不对了?为啥说不行?如果说没有清屏,那我承认没做。
---------------------------------------------------------------------------------repaint()的机制不是直接在applet窗口上画图,它的内部运行可以描述成这样:
public void repaint()
{
绘图与事件处理线程.队列.Add("call for paint()");
}
绘图与事件处理线程是JVM定义的,专门负责重绘,也——只有它能够重绘——,当绘图与事件处理线程处理完队列中在"call for paint()"之前的所有请求之后,它就处理"call for paint()",这时它才调用paint()。
所以,
public void paint(Graphics g)
{
g.drawOval(x+r,y+r,50+r,50+r);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);
}
绕过了绘图与事件处理机制,看似合理但事实上不行。
这也是applet落后的地方,它会复杂化一些关于界面的逻辑。--------------------------------------------
(Graphics gg我是忘了注释掉了)
import javax.swing.JApplet;
import java.awt.*;class ball
implements Runnable {
int x, y; //position
int r; //size
int delay;
int index;
Graphics gg;
MyA app;
Color color;
public ball(int a, int b, int c, int d, Color theColor, MyA the_app,
int the_index) { x = a;
y = b;
r = c;
delay = d;
color = theColor;
app = the_app;
index = the_index;
} public void run() {
try {
while (true) {
Thread.sleep(delay);
if (r >= 150) {
r = 10;
}
r += 5;
this.paint(gg);
}
}
catch (InterruptedException e) {}
} public void paint(Graphics g) {
app.repaint();
}}public class MyA
extends Applet {
int delay;
int number;
int[] length_move;
int[][] positions;
ball[] ballvars;
//Thread[] th;
//Graphics gg;
//Color[] colors; public void init() {
this.setBackground(Color.black);
super.setSize(500, 500); if (getParameter("number") == null) {
number = 6;
}
else {
number = Integer.parseInt(getParameter("number"));
}
if (getParameter("delay") == null) {
delay = 25;
}
else {
delay = Integer.parseInt(getParameter("delay"));
} int i;
length_move = new int[number];
for (i = 0; i < number; i++) {
length_move[i] = i * 5;
} positions = new int[number][2];
int j = 0;
for (i = 0; i < number; i++) {
for (j = 0; j < 2; j++) {
positions[i][j] = 30 * i;
}
} this.ballvars = new ball[number];
Color the_color; for (int i1 = 0; i1 < number; i1++) {
switch (i1 % 10) {
case 1:
the_color = Color.red;
break;
case 2:
the_color = Color.blue;
break;
case 3:
the_color = Color.MAGENTA;
break;
case 4:
the_color = Color.yellow;
break;
case 5:
the_color = Color.orange;
break;
default:
the_color = Color.green;
break;
} if (this.ballvars[i1] == null) {
this.ballvars[i1] = new ball(positions[i1][0], positions[i1][1],
length_move[i1], delay, the_color, this,
i1);
}
} } public void start() { for (int i1 = 0; i1 < number; i1++) {
Thread thread = new Thread(this.ballvars[i1]);
thread.start();
}
} public void paint(Graphics g) { for (int i = 0; i < this.number; ++i) {
g.setColor(this.ballvars[i].color);
g.fillOval(this.ballvars[i].x + this.ballvars[i].r,
this.ballvars[i].y + this.ballvars[i].r,
50 + this.ballvars[i].r, 50 + this.ballvars[i].r);
} }}
另外还有什么问题都可以跟我讨论。
实际上ball中本没有paint(Graphics g)方法的(和applet不一样),相当于自定义了一个
所以是显示调用的,
this.paint(gg);关系如下:
(g)applet-->(gg)ball-->paint(gg)在ball中调用的paint(gg)
相当于调用
applet中的paint(g);如果将ball中的paint(Graphics g)方法换成什么DrawBall(Graphics g)可能就不容易混淆了
所以实际我的程序和你程序运行机制基本是一样的。不知道你运行过我的程序没有?
其中public void paint(Graphics g)
改写如下:(加了一个清屏)
public void paint(Graphics g)
{
g.setColor(Color.black);
g.fillOval(x+r-5,y+r-5,50+r-5,50+r-5);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);
}你的程序我也运行过了,是一个线程同时画6个圆
不知道楼主何意
我理解是一个线程管一个圆。
// <applet code=th width=200 height=100></applet>
import java.applet.Applet;
import javax.swing.JApplet;
import java.awt.*;class ball implements Runnable{
int x,y;//position
int r;//size
int delay;
Color cc,//所画圆的颜色,我见你后面的colors数组赋值的那么辛苦而没有用到,
//我想你本意应该是要用的,所以帮你加上
bColor;//背景颜色,清屏用的。
Graphics gg;
public ball(int a,int b,int c,Color color,Color BColor,int d,Graphics f)
{
x=a;
y=b;
r=c;
cc=color;
bColor = BColor;
delay=d;
gg=f;
}public void run()
{
while(true) /////////////////////////////////
try
{
this.paint(gg,bColor); //用背景色填充上次所画的圆,即清屏
if(r>=150) r=10;
r+=5;
this.paint(gg,cc);
Thread.sleep(delay); //放在这里才能看清所画的圆。
}catch(InterruptedException e){e.printStackTrace();}
}public void paint(Graphics g,Color pColor) //增加一个颜色的参数
{
// g.drawOval(x+r,y+r,50+r,50+r); 不需要
g.setColor(pColor);
g.fillOval(x+r,y+r,50+r,50+r);
}}
public class th extends Applet{
Thread [] th;
int delay;
int number;
Graphics gg;
int []length_move;
Color []colors;
Color bColor=Color.black; //背景颜色
int [][]positions;
public void init()
{
gg=this.getGraphics(); /////////////////////
this.setBackground(bColor);
super.setSize(500,500);
if(getParameter("delay")==null)
{
delay = 1000;
}
else
{
delay = Integer.parseInt(getParameter("delay"));
}
if(getParameter("number")==null)
{
number=5;
}
else
{
number = Integer.parseInt(getParameter("number"));
}
th=new Thread[number];
int i;
for(i=0;i<number;i++)
{
th[i]=null;
}
length_move=new int[number];
for(i=0;i<number;i++) length_move[i]=i*5;
colors=new Color[number];
for(i=0;i<number;i++)
{
switch(i%10)
{case 1: colors[i]=Color.red;break;
case 2: colors[i]=Color.blue;break;
case 3: colors[i]=Color.MAGENTA;break;
case 4: colors[i]=Color.yellow;break;
default: colors[i]=Color.green;
}
}
positions=new int[number][2];
int j=0;
for(i=0;i<number;i++)
for(j=0;j<2;j++)
{
positions[i][j]=100*i;
}}public void start()
{
for(int i=0;i<number;i++)
{
if(th[i]==null)
th[i]=new Thread(new ball(positions[i][0],positions[i][1],length_move[i],colors[i],bColor,delay,gg));
th[i].start();
}
}//public void paint(Graphics g) 没必要
//{
//super.paint(g);
//gg=g;
//}}
import javax.swing.JApplet;
import java.awt.*;class ball
implements Runnable {
int x, y;
int r;
int delay;
int index;
MyA app;
Color color;
public ball(int a, int b, int c, int d, Color theColor, MyA the_app,
int the_index) { x = a;
y = b;
r = c;
delay = d;
color = theColor;
app = the_app;
index = the_index;
} public void run() {
try {
while (true) {
Thread.sleep(delay);
if (r >= 150) {
color = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
r = 10;
}
r += 5;
app.repaint();
}
}
catch (InterruptedException e) {}
}
}public class th
extends Applet {
int delay;
int number;
int[] length_move;
int[][] positions;
ball[] ballvars; public void init() {
this.setBackground(Color.black);
super.setSize(500, 500); if (getParameter("number") == null) {
number = 6;
}
else {
number = Integer.parseInt(getParameter("number"));
}
if (getParameter("delay") == null) {
delay = 100;
}
else {
delay = Integer.parseInt(getParameter("delay"));
} int i;
length_move = new int[number];
for (i = 0; i < number; i++) {
length_move[i] = i * 5;
} positions = new int[number][2];
int j = 0;
for (i = 0; i < number; i++) {
for (j = 0; j < 2; j++) {
positions[i][j] = 30 * i;
}
} this.ballvars = new ball[number];
Color the_color;
for (int i1 = 0; i1 < number; i1++) {
the_color = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
if (this.ballvars[i1] == null) {
this.ballvars[i1] = new ball(positions[i1][0], positions[i1][1],
length_move[i1], delay, the_color, this,
i1);
}
} } public void start() { for (int i1 = 0; i1 < number; i1++) {
Thread thread = new Thread(this.ballvars[i1]);
thread.start();
}
} public void paint(Graphics g) { for (int i = 0; i < this.number; ++i) {
g.setColor(this.ballvars[i].color);
g.fillOval(this.ballvars[i].x + this.ballvars[i].r,
this.ballvars[i].y + this.ballvars[i].r,
this.ballvars[i].r, this.ballvars[i].r);
} }}
谢谢你们的回复,我是学java才10天啦,所以有一些结构不会是最优的。总之就是谢谢