📄 freehandframe.java~5~
字号:
package chapter11;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class FreeHandFrame extends JFrame
{
JPanel infoPnl = new JPanel();
JLabel totalLbl_1 = new JLabel("总数");
JLabel totalLbl_2 = new JLabel();//计算总共下落的字母数标签
JLabel rightLbl_1 = new JLabel("正确数");
JLabel rightLbl_2 = new JLabel("");//计算正确击中的字母数标签
JLabel errorLbl_1 = new JLabel("失败数");
JLabel errorLbl_2 = new JLabel("");//计算未击中的字母数标签
JLabel startLbl = new JLabel("按F2开始");
JLabel stopLbl = new JLabel("按F3结束");
Canvas canvas = new Canvas();//画板
static int STEP_LEN = 2 ;//每次下落的步长
static int STEP_TIMEOUT = 50;//每移动一个像素的间隔时间,以毫秒为单位
static int DROP_THREAD_COUNT = 10;//下落字体线程数
int colWidth;//每栏的宽度
int totalCount = 0;
int rightCount = 0;
int errorCount = 0;
char pressKeyChar ;//记录按下的按键
boolean isStart = false;//是否开始游戏
Stack dealThreadColStack = new Stack();//记录死亡线程所在的位置
static String ALPHABET="abcdefghijklmnopqrstuvwxyz";//字母表
Random random = new Random();//随机数
public FreeHandFrame()
{
jinit();
this.addKeyListener(new MyKeyListener());
}
/**
* <b>功能说明:</b><br>
* 为页面添加组件
*/
private void jinit()
{
infoPnl.setBackground(Color.cyan);
infoPnl.setLayout(new GridLayout(8,1));
infoPnl.add(startLbl);
infoPnl.add(stopLbl);
infoPnl.add(totalLbl_1);
infoPnl.add(totalLbl_2);
infoPnl.add(rightLbl_1);
infoPnl.add(rightLbl_2);
infoPnl.add(errorLbl_1);
infoPnl.add(errorLbl_2);
getContentPane().add(infoPnl,BorderLayout.EAST);
canvas.setBackground(Color.yellow);
getContentPane().add(canvas,BorderLayout.CENTER);
}
/**
* <b>功能说明:</b><br>
* 返回一个随机字符
* @return 随机字符
*/
private char getRandomChar()
{
int temp = random.nextInt(26);
return ALPHABET.charAt(temp);
}
/**
* <b>功能说明:</b><br>
* 将统计结果画到界面上
*/
private void drawResult()
{
totalLbl_2.setText(""+totalCount);
rightLbl_2.setText(""+rightCount);
errorLbl_2.setText(""+errorCount);
}
public static void main(String[] args)
{
FreeHandFrame frm = new FreeHandFrame();
frm.setSize(400,400);
frm.show();
}
/**下落字体线程*/
//////////////////////////////////////////////////////////////////////////////
public class DropChar extends Thread
{
char c ;//对应的字线
int colIndex;//在哪列下落
int x,y;//行列的坐标
public DropChar(char c,int colIndex)
{
this.c = c;
this.colIndex = colIndex;
this.x = (colIndex-1) * colWidth +colWidth/2;//所在的横坐标
}
public void run()
{
draw(1);
while(c != pressKeyChar && y < 400 && isStart)
{
move();
try
{
Thread.sleep(STEP_TIMEOUT);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
pressKeyChar = ' ';
draw(2);
if(isStart)
{
totalCount++;//统计总数
if(y < 400) rightCount++;//打中
else errorCount++;//打不中
}
drawResult();
synchronized (canvas)
{
dealThreadColStack.push(new Integer(colIndex));//记录哪一列线程死亡
canvas.notify();//通知总控线程创建一个新的下落线程
}
}
/**向下移动一个像素*/
private void move()
{
draw(2);
y += STEP_LEN;
draw(1);
}
/**
* <b>功能说明:</b><br>
* 画字母
* @param actionType 1:画字母 2: 清除字母
*/
private void draw(int actionType)
{
synchronized (canvas)//必须对资源canvas进行同步,否则会产生线程不安全
{
Graphics g = canvas.getGraphics();
if(actionType == 2) g.setXORMode(canvas.getBackground());//清除
g.setFont(new Font("Times New Roman",Font.PLAIN,12));
g.drawString(""+c,x,y);
}
}
}
//////////////////////////////////////////////////////////////////////////////
/**创建下落字体线程的主线程*/
//////////////////////////////////////////////////////////////////////////////
public class GenerateDropThread extends Thread
{
public void run()
{
for (int i = 0; i < DROP_THREAD_COUNT; i++) //产生下落线程
{
DropChar dropCharThread = new DropChar(getRandomChar(),i+1);
dropCharThread.start();
try
{
Thread.sleep(500);
}
catch (InterruptedException ex1) {
}
}
while(isStart)
{
synchronized (canvas)
{
try
{
canvas.wait();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
while(!dealThreadColStack.empty())//在死亡线程的栏上产生新下落线程
{
int colInt = ((Integer)dealThreadColStack.pop()).intValue();
DropChar dropCharThread = new DropChar(getRandomChar(),colInt);
dropCharThread.start();
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
/**响应键盘的监听器*/
class MyKeyListener extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_F2)
{
isStart = true;//开始
colWidth = canvas.getWidth()/ DROP_THREAD_COUNT;
GenerateDropThread gdThread = new GenerateDropThread();//总控线程运行
gdThread.start();
}
else if(e.getKeyCode() == KeyEvent.VK_F3)
{
isStart = false;//停止
}
else if(!e.isActionKey())
{
pressKeyChar = e.getKeyChar();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -