此练习没有直接采用继承Thread类或者继承Runnable的接口来实现多线程,而是使用了匿名内部类。
要导入的类:
1importjavax.swing.*;2importjava.awt.*;
1.定义SowPanel类,继承JPanel类,这个类有两个整型数组成员,用来保存雪花起始位置。在构造函数中为数组赋初值;重写父类的paint()方法;定义一个启动多线程的startSnow()方法。
1classSnowPanelextendsJPanel2{3//定义整型数组,存储雪花坐标4PRivateint[] x=newint[300];5privateint[] y=newint[300];67publicSnowPanel()8{9//设置背景为黑色10setBackground(Color.black);11//用随机数初始化雪花坐标12for(inti=0;i<x.length;i++)13{14x[i]=(int)(Math.random()*800);15y[i]=(int)(Math.random()*600);16}17}1819publicvoidpaint(Graphics g)20{21//继承父类画的方法22super.paint(g);23//设置颜色为白色24g.setColor(Color.white);25//利用循环画出多个雪花26for(inti=0;i<x.length;i++)27{28g.drawString("*",x[i],y[i]);29}30}31//定义一个方法启动多线程,并使用匿名内部类32publicvoidstartSnow()33{34newThread()35{36publicvoidrun()37{38while(true)39{40for(inti=0;i<y.length;i++)41{42//坐标下移43y[i]++;44//检查是否越界45if(y[i]==600)46y[i]=0;47//重绘48repaint();49}5051try52{53Thread.sleep(10);54}55catch(InterruptedException e)56{57e.printStackTrace();58}59}60}61}.start();62}63}
2.定义ShowFrame类,继承Jframe 类。在构造方法中设置窗口的显示属性,并创建ShowPanel对象,添加到窗口中。
1publicclassSnowFrameextendsJFrame2{3publicSnowFrame()4{5setTitle("满天雪花");6//设置窗体显示坐标和大小7setBounds(100,100,800,600);8//设置用户在此窗体上发起close时默认的操作9this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);10//设置此窗体不可被调整大小11setResizable(false);12SnowPanel p=newSnowPanel();13//调用能够启动线程的方法14p.startSnow();15//把SnowPanel对象添加到此窗体上16this.add(p);17this.setVisible(true);18}19publicstaticvoidmain(String[] args)20{newSnowFrame();}21}
3.运行效果图片(此为静态图):
疑问:发现其他的不改变,继承Frame、Panel和继承JFrame、Jpanel的运行效果是不同的,前者显示的下雪场景总是有闪烁的感觉;后者则没有闪烁,个人感觉后者效果更好些。