package com.qdmmy6.choujiang;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ChouJiangFrame extends JFrame implements Runnable {
// 手机号码
private String[] tel;
// 用来装载不同的手机号载体
private JLabel text = new JLabel();
// 启动和停止按钮
private JButton startAndStopButton = new JButton("启 动");
// private JButton stopButton = new JButton("停 止");
// label面板
private JPanel centerPanel = new JPanel();
// 按钮面板
private JPanel buttonPanel = new JPanel();
// 手机号滚动线程
private Thread th;
// 手机数组下标
private int suffix;
// 参加抽奖的手机号个数
private int sum;
// 未启动状态
public static final int NEW_THREAD = 0;
// 暂停状态
public static final int PAUSE_THREAD = 1;
// 启动状态
public static final int START_THREAD = 2;
// 线程的状态
private int state = NEW_THREAD;
public ChouJiangFrame(String[] tel) {
this.init();
this.tel = tel;
sum = tel.length;
startAndStopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
execute();
}
});
}
// 设计GUI
public void init() {
this.setSize(300, 200);
this.getContentPane().add(centerPanel, BorderLayout.CENTER);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
centerPanel.add(text);
// 初始让label不装载任何号码
text.setText("XXXXXXXXXXX");
text.setFont(new Font("宋体", Font.BOLD, 32));
buttonPanel.add(startAndStopButton);
}
/*
* NEW_THREAD如果线程还没有启动过:启动线程并设置状态为(启动)START_THREAD。
*
* START_THREAD如果线程已启动:设置状态为PAUSE_THREAD,这时run方法会执行wait()
*并调用lottery()方法把已中奖号码抽出,已防一同号码中奖多次
*
* PAUSE_THREAD如果线程已暂停:设置状态为START_THREAD并调用notifyAll()方法这
*时run方法会被唤醒。
**/
public void execute() {
if(this.state == NEW_THREAD) {
th = new Thread(this);
this.startAndStopButton.setText("暂 停");
th.start();
state = START_THREAD;
} else if(this.state == PAUSE_THREAD) {
synchronized (this) {
state = START_THREAD;
this.startAndStopButton.setText("暂 停");
this.notifyAll();
}
} else if(this.state == START_THREAD) {
state = PAUSE_THREAD;
this.startAndStopButton.setText("启 动");
this.lottery();
}
}
/*
*本方法只在暂停时调用。
* 在sum个数中取随机数做下标,当run方法wait时,产生中奖号码,把中奖号码和最
*后一个下标的数交换,然后再在sum减1中取随机下标,这样中奖的号码就不会在出现了。
*当sum小于1时,说明就只剩下第后一个数了,也就不用在抽奖了,不然sum--会出现负
*数下标。
**/
public void lottery() {
if(sum >= 1) {
System.out.println(tel[suffix]);
sum--;
String temp;
temp = tel[sum];
tel[sum] = tel[suffix];
tel[suffix] = temp;
}
}
/*
* 取随机下标号码做label的文本,这时文本会不停的变化,如果发现状态为
*PAUSE_THREAD,马上使线程wait,一直到notifyAll之后在变化文本。不过每次
*notifyAll之后都会调用lottery方法,而lottery方法会把sum的值减1。
**/
public void run() {
try {
while(true) {
this.suffix = (int)(Math.random() * sum);
this.text.setText(tel[suffix]);
Thread.sleep(50);
synchronized (this) {
if (state == PAUSE_THREAD) {
this.wait();
}
}
}
} catch(InterruptedException e) {
}
}
}
|