初学多线程练习3--移动的文本

12/12/2015来源:Java教程人气:566

Flash中的逐帧动画可以实现文本移动显示的效果,java程序也可以实现类似效果哦。

1.Ticker类继承Canvas,实现Runnable接口。用Canvas中的paint方法控制字符串的移动位置。

2.TickerFrame 类继承Frame,实现ActionListener窗口,添加两个按钮来控制文本的移动和停止。

核心部分:

字符串快要离开显示区域是,需要复位减少的x坐标值。由于那时的x坐标值和文本宽度相等,这就意味着需要确定字符串的宽度。而字符串宽度依赖于选定的字体、字号和外观。这里使用了FontMetrics类,用它能获得关于特定字体信息、度量一个字符串在特定字体情况下的尺寸。但此类是抽象类,不能被实例化,所以还应该使用一个getFontMetrics方法来获得FontMetrics对象的引用。

代码如下:

  1 import java.awt.*;
  2 import java.awt.event.*;
  3 class Ticker extends Canvas implements Runnable
  4 {
  5     //定义字符串位置坐标
  6     PRivate int x,y;
  7     //定义整型变量用来存储字符串的高度,宽度
  8     private int height,width;
  9     private Thread runner=null;
 10     //定义字符串
 11     private String text=null;
 12     //FontMetrics类可以测出具有特定字体的字符大小,但是是抽象类,不能直接被实例化,
 13     
 14     private FontMetrics metrics =null;
 15     private Font font=new Font("Monospaced",Font.BOLD,50);
 16 
 17     public Ticker(String _text)
 18     {
 19         text=_text;
 20         //使用getFontMetrics方法,返回一个FontMetrics对象的引用
 21         metrics=getFontMetrics(font);
 22         //高度等于这种字体的高度
 23         height=metrics.getHeight();
 24         //宽度等于字符串的宽
 25         width=metrics.stringWidth(text);
 26 
 27         x=getSize().width;
 28         y=height;
 29         
 30         //Ticker的尺寸至少应该和文本一般大
 31         setSize(width,height+2);
 32 
 33     }
 34     //自定义线程启动的方法
 35     public void start()
 36     {
 37         if(runner==null)
 38         {
 39             runner=new Thread(this);
 40             runner.start();
 41         }
 42     }
 43     //自定义停止线程的方法
 44     public void stop()
 45     {runner=null;}
 46 
 47     //实现run方法
 48     public void run()
 49     {
 50         Thread currentThread =Thread.currentThread();
 51         while(runner==currentThread)
 52         {
 53             //自定义方法,使字符串向左移动坐标改变
 54             computeCoordinates();
 55             //重绘
 56             repaint();
 57             try
 58             {
 59                 runner.sleep(30);
 60             }
 61             catch (InterruptedException ie)
 62             {
 63                 System.err.println("Error:"+ie);
 64             }
 65         }
 66     }
 67     //重写父类的paint()方法
 68     public void paint(Graphics g)
 69     {
 70         g.setColor(Color.blue);
 71         g.setFont(font);
 72         g.drawString(text,x,y);
 73     }
 74 
 75     private void computeCoordinates()
 76     {
 77         //当所有文本移到窗口外时,复位
 78         if(x<-width)
 79             x=getSize().width;
 80         else
 81             //坐标减小,已达到字符串向左移动的效果
 82             x-=2;
 83 
 84     }
 85 
 86 }
 87 public class TickerFrame extends Frame implements ActionListener
 88 {
//定义两个按钮
89 private Button start=new Button("Start"); 90 private Button stop=new Button("Stop");
//创建Ticker类对象
91 Ticker ticker=new Ticker("实践中学习!");
//在构造方法中初始化窗口
92 public TickerFrame() 93 { 94 super("移动的文本"); 95 setLayout(new BorderLayout()); 96 add("Center",ticker);
//新建一个容器
97 Panel p=new Panel();
//设置为流式布局
98 p.setLayout(new FlowLayout());
//把按钮添加到容器中,并为按钮注册监听器
99 p.add(start); start.addActionListener(this); 100 p.add(stop); stop.addActionListener(this); 101 add("South",p);
//用匿名内部类,为窗口注册监听器。
102 addWindowListener(new WindowAdapter() 103 { 104 public void windowClosing(WindowEvent we) 105 { 106 System.exit(0); 107 } 108 }); 109 pack();
//使窗口可见
110 setVisible(true); 111 }
//实现接口的抽象方法,处理单击按钮的事件
112 public void actionPerformed(ActionEvent ae) 113 { 114 if(ae.getSource()==start) 115 ticker.start(); 116 else 117 if(ae.getSource()==stop) 118 ticker.stop(); 119 120 } 121 public static void main(String[] args) 122 {new TickerFrame();} 123 }

运行:

单击“Start”按钮,文本就会向左移动,单击“Stop”按钮,则移动停止;当所有文本移到窗口之外时,文本复位,再次向左移动。