设计滚动字演示线程状态及改变方法

本例演示线程对象的生命周期从创建到终止的过程,使用new、start()、sleep()、interrupt()等方法改变线程的状态。 本例综合运用内部类、图形化用户界面、线程等多方面技术实现设计。



package com.jbx.thread;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class WelcomeJFrame extends JFrame
{

public WelcomeJFrame(String[] texts) //texts指定移动字符串,数组长度决定窗口中的面板数
{
super("滚动字");
this.setBounds(300, 240, 400, 300);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
if(texts==null || texts.length==0)
this.getContentPane().add(new RollbyJPanel("Welcome!"));//至少有一行字符串
else{
this.getContentPane().setLayout(new GridLayout(texts.length,1)); //网格布局,1行若干列
for(int i=0;i<texts.length;i++){
this.getContentPane().add(new RollbyJPanel(texts[i]));
}
}
this.setVisible(true);
}

public WelcomeJFrame()
{
this(null);
}

private class RollbyJPanel extends JPanel implements ActionListener,Runnable
{

JTextField text_word,text_sleep; //滚动字文本行,线程睡眠时间文本行
JButton button_start,button_interrupt; //启动按钮,中断按钮
JTextField text_state; //线程状态文本行
Thread thread_rollby; //线程对象
int sleeptime; //线程睡眠时间

RollbyJPanel(String text) //内部面板类构造方法
{
this.setLayout(new GridLayout(2,1));
char space[] = new char[100];
Arrays.fill(space, ' '); //将字符数组space填充满空格
text_word = new JTextField(text+new String(space)); //text后加空格字符串
this.add(text_word);

JPanel panel_sub = new JPanel(new FlowLayout(FlowLayout.LEFT));
this.add(panel_sub);
panel_sub.add(new JLabel("sleep"));
this.sleeptime=(int)(Math.random()*100);//产生随机数作为间隔时间
text_sleep = new JTextField(""+sleeptime,5);
panel_sub.add(text_sleep);
text_sleep.addActionListener(this);

button_start = new JButton("启动");
panel_sub.add(button_start);
button_start.addActionListener(this);
button_interrupt = new JButton("中断");
panel_sub.add(button_interrupt);
button_interrupt.addActionListener(this);

thread_rollby = new Thread(this); //创建线程对象,目标对象是当前对象
button_interrupt.setEnabled(false); //设置中断按钮为无效状态
panel_sub.add(new JLabel("state"));
text_state = new JTextField(""+thread_rollby.getState(),10);
text_state.setEditable(false);
panel_sub.add(text_state);
}

@Override
public void run() { //线程体,必须是公有方法

while(true)
try{
String str = text_word.getText();
str = str.substring(1) + str.substring(0,1);
text_word.setText(str);
thread_rollby.sleep(sleeptime); //线程睡眠,抛出中断异常
}catch(InterruptedException e){
break; //退出循环
}
} //run()方法结束,线程对象终止

@Override
public void actionPerformed(ActionEvent e) { //单击事件处理,必须是公有方法
if(e.getSource() == button_start){ //单击启动按钮时
thread_rollby = new Thread(this); //重新创建一个线程对象
thread_rollby.start();
text_state.setText(""+thread_rollby.getState()); //显示线程状态
button_start.setEnabled(false);
button_interrupt.setEnabled(true);
}
if(e.getSource() == button_interrupt){ //单击中断按钮时
thread_rollby.interrupt(); //设置当前线程对象中断标记
text_state.setText(""+thread_rollby.getState()); //显示线程状态
button_start.setEnabled(true);
button_interrupt.setEnabled(false);
}
if(e.getSource() == text_sleep){ //单击线程睡眠时间文本行时
try{
sleeptime = Integer.parseInt(text_sleep.getText());
}catch(NumberFormatException nfe){
JOptionPane.showMessageDialog(this, "\""+text_sleep.getText()+"\" 不能转换成整数,请重新输入!");
}
}
}
}

public static void main(String[] args) {
String[] texts ={"Welcome","Hello","Rollby","girl"};
new WelcomeJFrame(texts);
}
}




运行效果图:


[img]http://dl2.iteye.com/upload/attachment/0130/2691/e8a7737b-57d9-3e21-88f3-4800cc5084c0.png[/img]

框架窗口由多个面板组成,每个面板布局相同,上部文本行中的字符串向左移动,下部有多个组件,用于设置字符串移动速度、控制字符串是否移动和显示线程状态。
sleep右边的文本行,用于改变线程睡眠时间,以控制字符串的移动速度;
单击“启动”按钮,则启动线程,使字符串移动;
单击“中断”按钮,则中断线程运行。


jvisualVM命令监控线程状态图

[img]http://dl2.iteye.com/upload/attachment/0130/2693/e6089e68-b47b-3d7f-84eb-414150982481.png[/img]


程序说明:
(1)声明自定义面板类为私有内部类并实现多个接口
本例需要在一个窗口中添加若干同样风格的面板,添加的面板数不确定,且每个面板组成较复杂,因此将自定义的面板设计成内部类。根据外部类构造方法的texts数组长度,将若干个面板添加到是外部类的框架窗口中。
由于面板内部类RollbyJPanel 只有其外部类使用,所以RollbyJPanel类声明为私有成员;由于面板中的按钮和文本行组件需要响应单击事件,所以RollbyJPanel类声明实现ActionListener接口;由于每个面板都对应着一个线程对象,而RollbyJPanel类已继承JPanel类,无法再继承Thread类,所以RollbyJPanel类声明实现Runnable接口,其中声明一个线程对象作为成员变量,Runnable类对象是其线程成员变量的目标对象。
[color=red] 虽然RollbyJPanel类是私有的,但其中的run()和actionPerformed()方法必须是公有的,因为这两个方法在接口中声明公有。[/color]
(2)线程状态变化
面板内部类RollbyJPanel 中声明一个线程对象thread_rollby,通过该线程对象控制字符串是否移动以及移动速度。线程启动后执行线程run()方法,将字符串首字符连接到字符串最后,通过线程睡眠控制字符串显示一段时间,再次重新循环移位字符串,达到看起来像是字符串在移动的效果。
线程运行中,单击“中断”按钮,调用interrupt()方法为当前线程对象设置中断标记,该中断标记由sleep()方法获知并抛出InterruptedException异常。在异常处理语句中,使用break语句退出循环,使run()方法结束,则线程对象终止。再次单击“启动”按钮,则重新创建一个线程对象并启动。各面板的线程状态变化与其他面板的线程状态无关。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值