`
fancyCR7
  • 浏览: 7567 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

初识线程

阅读更多

最近写了一个程序,可以通过按键在画板上生成随机大小随机颜色的小球并且小球可以在画板上运动,实现了鼠标点击小球可以进行消除的功能,并且还实现了小球的暂停与重新运动的操作。

首先我们还是得先将窗体设置好,然后在窗体上添加鼠标事件监听器还有键盘事件监听器。

package com.hnu.yc0802BallThread;

import java.awt.Graphics;

import javax.swing.JFrame;

public class BallFrame extends JFrame{
	
	public static void main(String args[]){
		BallFrame ba=new BallFrame();
		ba.initUI();
	}
	
	
	/**
	 * 实现窗体的方法
	 */
	public void initUI(){
		
//		设置窗体基本属性
		this.setSize(700,700);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(3);
		this.setResizable(false);
		
//		添加键盘及鼠标监听器
		Action ka=new Action(this);
		this.addKeyListener(ka);
		this.addMouseListener(ka);
		
		this.setVisible(true);
		
		
		
	}

}

 

 

 

然后我们要定义小球类(继承Thread类),其中包括小球得基本属性,并且要确定好参数的传递方式,是用构造方法还是设置setget方法。最后还得写run方法,其中就得写小球的运动算法。

package com.hnu.yc0802BallThread;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class Ball extends Thread{
	
	
	private int x,y,movex,movey,size;//小球的起始坐标,每运动一次移动的坐标,大小
	private BallFrame bf;
	
//	这两个布尔变量都是在线程运行时进行判断使用,后面会介绍用法
	Boolean haha=false;
	Boolean hahaha=true;
	
	Color co;//小球的颜色
	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	

	
	

	
	/**
	 * 构造方法
	 * @param x小球起始横坐标
	 * @param y小球起始纵坐标
	 * @param movex 小球移动一步横坐标长度
	 * @param movey  小球移动一步纵坐标长度
	 * @param g 画笔
	 */
	public Ball(int x, int y, int movex, int movey, BallFrame bf,Color co,int size) {
		super();
		this.setX(x);
		this.setY(y);
		this.movex = movex;
		this.movey = movey;
		this.bf = bf;
		this.co=co;
		this.setSize(size);
	}
	
	public void run(){
		Graphics g=bf.getGraphics();
		
		while (hahaha){//hahaha(个人习惯用哈哈作为布尔变量,只要在我的代码中看到ha,那就代表布尔变量)
                                 //这里的布尔变量控制循环语句的执行,当我要结束线程,就要结束这个循环,改变布尔变量即可			
			if (haha){//这里的布尔变量控制小球的暂停,但是这只是让小球停在那里没有运动,
				           //线程一直在执行,只是没有让线程执行后面的部分,所以说小球看起来不动,暂停了
				continue;
			}
			g.setColor(bf.getBackground());
			g.fillOval(getX(), getY(), getSize(), getSize());
//			
			setX(getX() + movex);
			setY(getY() + movey);
			g.setColor(co);
			g.fillOval(getX(), getY(), getSize(), getSize());
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

	
}

 

 

 

接下来我们就要写实现事件监听的类,

package com.hnu.yc0802BallThread;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

public class Action implements KeyListener, MouseListener {

	BallFrame bf;
	Random rand;// 定义一个随机数变量,在小球的大小,颜色,运行速度随机时使用
	PerfectQueue<Ball> pq;// 定义一个泛型队列变量,用来存储小球类型的对象

	/**
	 * 构造方法,用来传参
	 * 
	 * @param bf
	 */
	public Action(BallFrame bf) {
		super();
		this.bf = bf;
		rand = new Random();
		pq = new PerfectQueue<Ball>();
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	public void keyPressed(KeyEvent e) {

		if (e.getKeyCode() == KeyEvent.VK_U) {// 当按下U键 随机生成小球
			Ball ball = new Ball(0, 0, rand.nextInt(10) + 1,
					rand.nextInt(10) + 1, bf, new Color(rand.nextInt(256),
							rand.nextInt(256), rand.nextInt(256)),
					rand.nextInt(100) + 20);
			ball.start();// 启动线程,执行run方法,让小球动起来
			pq.add(ball);// 每次都新建一个小球,然后将小球对象存储在队列中,在后面指定消除哪个小球时会用到
		}
		if (e.getKeyCode() == KeyEvent.VK_I) {// 按下I键暂停小球运动
			// 暂停只是让线程空循环,不绘制图形,在Ball类run方法中有详细解释
			/**
			 * 遍历队列,将所有小球的布尔变量haha(控制小球暂停,在Ball类run方法中有详细解释)变为true 暂停所有小球的运动
			 */
			for (int i = 0; i < pq.size(); i++) {
				Ball ball = pq.get(i);
				ball.haha = true;
			}

		}
		if (e.getKeyCode() == KeyEvent.VK_O) {// 按下I键小球重新开始运动
			// 启动是让线程不再空循环 要绘制图形
			/**
			 * 遍历队列,将所有小球的布尔变量haha(控制小球暂停,在Ball类run方法中有详细解释)变为false 暂停所有小球的运动
			 */
			for (int i = 0; i < pq.size(); i++) {
				Ball ball = pq.get(i);
				ball.haha = false;
			}
		}

	}

	public void mouseReleased(MouseEvent e) {
		boolean ha = false;// 定义一个局部布尔变量,在判断鼠标点击点附近有没有小球时使用
		int minpq = 0;// 存储到鼠标点击点的最小距离的点的下标
		int min = 119;// 小球的大小是119,要将小球的坐标(小球就是画的内切圆,将矩形左上角的坐标定位小球的坐标)与鼠标点击点取距离,小于119才有效
		// 得到鼠标释放的坐标
		int Mouse_x = e.getX();
		int Mouse_y = e.getY();

		/**
		 * 遍历队列,寻找鼠标点击点附近是否有符合要求的小球,有的话,取出距离鼠标点击点最近的那个
		 */
		for (int i = 0; i < pq.size(); i++) {
			// 当不符合要求时,进入下一次循环
			if (pq.get(i).getX() > Mouse_x || pq.get(i).getY() > Mouse_y
					|| (Mouse_x - pq.get(i).getX()) > 119
					|| (Mouse_y - pq.get(i).getY()) > 119) {
				continue;
			} else {
				// pq.get(i).setX(800);
				// pq.get(i).setY(800);
				int a = (int) distence(Mouse_x, pq.get(i).getX(), Mouse_y, pq
						.get(i).getY());// 此方法为定义的计算两点距离的方法
				if (a < min) {
					min = a;
					minpq = i;
				}

				ha = true;// 说明鼠标附近有符合要求的小球

			}

		}
		if (ha) {
			pq.get(minpq).hahaha = false;// 将hahaha控制while语句循环的条件设置为false,停止此小球线程运行
			Graphics g = bf.getGraphics();// 得到画笔
			g.setColor(bf.getBackground());// 糊一个与背景色相同的小球覆盖上去
			g.fillOval(pq.get(minpq).getX(), pq.get(minpq).getY(), pq
					.get(minpq).getSize(), pq.get(minpq).getSize());

			pq.delete(minpq);//在队列中删除此小球
		}
	}

	// 求两点之间距离的算法
	public double distence(int ax, int bx, int ay, int by) {
		return Math.hypot(ax - bx, ay - by);

	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent e) {

		// TODO Auto-generated method stub

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub

	}

}

 最后,将泛型队列代码附上

 

package com.hnu.yc0802BallThread;

public class PerfectQueue<E> {
	
	private Object[] array;
	private int size;

	// 构造方法 实例化数组
	public PerfectQueue() {
		array = new Object[size];
	}

	// 添加方法
	public void add(E o) {
		Object array1[] = new Object[size + 1];
		for (int i = 0; i < size; i++) {
			
			array1[i] = array[i];
		}
		array1[size] = o;
		size++;
		array = array1;
	}
	
	public E get(int index){
		if(index<0||index>=size)
			return null;
		return (E)array[index];
	}

	// 删除方法
	public E delete(int index) {
		if(index<0||index>=size)
		return null;
		Object[] temp=new Object[size-1];
		for(int i=0;i<index;i++){
			temp[i]=array[i];
		}
		for(int i=index+1;i<size;i++){
			temp[i-1]=array[i];
		}
		Object obj=array[index];
		size--;
		return (E)obj;
		
	}

	// 查找方法
	public boolean find(Object obj) {
		for(int i=0;i<size;i++){
			if(array[i]==obj){
				return true;
			}
		}
		return false;
	}
	
	public int size(){
		return size;
	}


}

 

分享到:
评论

相关推荐

    C# 线程相关知识总结

    初识线程 线程是一个独立的运行单元,每个进程内部都有多个线程,每个线程都可以各自同时执行指令。每个线程都有自己独立的栈,但是与进程内的其他线程共享内存。但是对于.NET的客户端程序(Console,WPF,WinForms...

    再读苹果《ThreadingProgrammingGuide》笔记(一):初识线程

    如今关于iOS多线程的文章层出不穷,但我觉得若想更好的领会各个实践者的文章,应该先仔细读读官方的相关文档,打好基础,定会有更好的效果。文章中有对官方文档的翻译,也有自己的理解,官方文档中代码片段的示例在...

    初识通信——多线程服务器的建立

    本文将详细讲解如何初识通信,并以多线程服务器的构建为例,来阐述相关技术点。 首先,理解多线程的概念至关重要。多线程是指在一个进程中可以同时执行多个线程,这样可以充分利用CPU资源,提高程序的执行效率。在...

    头歌初识redis答案.rar

    在头歌平台初识Redis的答案可以总结如下: 一、基础知识 Redis数据库数量: Redis默认有16个数据库,可以使用select命令进行切换。 数据库大小与键的查看: 使用DBSIZE命令查看当前数据库的大小(即键的数量)。 ...

    深海王国小学生都能玩的语音模块?项目工程文件,(7)初识多线程

    使用方法与介绍,请参考系列文章——【深海王国】小学生都能做的语音模块?

    初识Java_课后补充作业

    9. **多线程**:了解线程的创建方式,同步机制(synchronized关键字、wait()、notify()、notifyAll()),以及线程池的使用。 10. **文件与目录操作**:学习如何在Java中创建、读取、修改和删除文件及目录。 11. **...

    java多线程相关面试题 1

    * 创建线程池时,初识化核心线程数和最大线程数 * 当有新的任务提交时,检查是否有空闲线程,如果有,则将任务分配给空闲线程 * 如果没有空闲线程,则检查是否已经达到最大线程数,如果没有,则创建新的线程 * 如果...

    【2018最新最详细】并发多线程教程

    8.初识Lock与AbstractQueuedSynchronizer(AQS) 9.深入理解AbstractQueuedSynchronizer(AQS) 10.彻底理解ReentrantLock 11.深入理解读写锁ReentrantReadWriteLock 12.详解Condition的await和signal等待通知机制 13....

    Java多线程的初识与简单的安全问题解决

    多线程 目录 进程 进程的了解 线程 什么是线程 线程的组成 线程的创建 线程的状态 线程的方法 线程的安全问题 1.进程 1.1.进程的了解 简单的来说进程就是运行中的程序,简称为进程。 单核CPU在任意一个时间节点上,...

    python入门课程 步骤一:Python基础知识 步骤二:Python函数与模块 步骤三:初识面向对象 步骤四:正则表达式与综合实战 步骤五:内存管理与多线程

    步骤三让学生初识面向对象编程,这是一个编程范式,它利用对象和类的概念来设计软件。在这个阶段,学生将学会如何创建类,如何使用继承、封装和多态性等面向对象的原则来组织代码,从而提高代码的可读性和可维护性。...

    Java线程初识

    1. 进程是什么 windows电脑中,打开任务管理器,可以看到电脑中执行的每一个程序,每一个程序就是一个进程。 Windows系统是一个多任务系统。 电脑可以同时执行多个程序。...线程抢占过程就类似于进

    JAVA语言技术初识

    Java语言技术初识 Java,作为一种革命性的编程语言,由Sun Microsystems公司的James Gosling等人于1991年创立,并于1995年正式发布。它的核心特性是跨平台能力,这得益于Java虚拟机(JVM),使得“编写一次,到处...

    1.初识Java.zip

    【初识Java】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(后被Oracle公司收购)于1995年发布。它的设计目标是具备“简单性、面向对象、健壮性、安全性、可移植性、高效性、多线程和动态性”等...

    头歌初识redis答案

    本篇文章将围绕《头歌初识Redis答案》的内容进行展开,详细介绍Redis的基础知识、数据类型及操作、事务与监视机制、持久化策略以及主从同步等方面的内容。 #### 基础概念 - **内存存储**:Redis主要基于内存进行...

    Gatling初识.pdf

    标题“Gatling初识.pdf”表明这是一个关于Gatling框架的基础入门指南,而描述中提到的“参数化用于性能测试脚本编写”则指出了Gatling在参数化方面的应用。参数化是性能测试中的一个关键概念,它允许测试脚本使用...

    Maven3之初识

    **Maven3之初识** Maven,一个在Java开发领域广泛应用的项目管理和综合工具,是Apache软件基金会的一个重要项目。它的核心目标是简化构建过程,通过提供一套标准的方式来管理项目的构建、报告和文档。Maven3是Maven...

Global site tag (gtag.js) - Google Analytics