文章目录
1.绘图入门
package com.wei.draw;
import javax.swing.*;
import java.awt.*;
@SuppressWarnings({"all"})
public class DrawCircle extends JFrame { //JFrame对应窗口
private MyPanel mp = null;// 定义一个画板
public static void main(String[] args) {
new DrawCircle();
}
public DrawCircle() {
// 初始化面板
mp = new MyPanel();
// 把面板放入到窗口
this.add(mp);
// 设置窗口大小
this.setSize(400, 300);
// 当点击窗口的小X,程序完全退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置为可以显示
this.setVisible(true);
}
}
// 1.定义一个面板(相当于画板),需要继承JPanel类
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) { //绘图方法
super.paint(g);// 调用父类的方法完成初始化
// 画圆形
g.drawOval(10, 10, 100, 100);
// g.draw3DRect(12,12,100,100,true);
System.out.println("绘图方法paint");
}
}
2.绘图方法
package com.wei.draw;
import javax.swing.*;
import java.awt.*;
@SuppressWarnings({"all"})
public class DrawCircle extends JFrame { //JFrame对应窗口
private MyPanel mp = null;// 定义一个画板
public static void main(String[] args) {
new DrawCircle();
}
public DrawCircle() {
// 初始化面板
mp = new MyPanel();
// 把面板放入到窗口
this.add(mp);
// 设置窗口大小
this.setSize(400, 300);
// 当点击窗口的小X,程序完全退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 设置为可以显示
this.setVisible(true);
}
}
// 1.定义一个面板(相当于画板),需要继承JPanel类
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) { //绘图方法
super.paint(g);// 调用父类的方法完成初始化
// 1. 画圆形
// g.drawOval(10, 10, 100, 100);
// 2. 画直线
// g.drawLine(10,100,100,200);
// 3. 画矩形边框
// g.drawRect(10,10,100,100);
// // 设置画笔颜色
// g.setColor(Color.red);
// // 填充颜色
// g.fillRect(10,10,100,100);
// 4.画图片
// 获取图片资源
// Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/smell.png"));
// g.drawImage(image,10,10,100,100,this);
// 4.画字符串
g.setColor(Color.red);
// 4.设置画笔字体
g.setFont(new Font("宋体",Font.BOLD,50));
g.drawString("你好啊!tom",100,100);
}
}
3.绘制坦克
- 新建Tank类,供以后所有的tank继承
package com.tank.tankGame;
public class Tank {
private int x; //坦克横坐标
private int y; // 坦克纵坐标
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
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;
}
}
- 定义自己的MyTank类,继承Tank父类
package com.tank.tankGame;
/**
* 自己的坦克
*/
public class MyTank extends Tank{
public MyTank(int x, int y) {
super(x, y);
}
}
- 定义绘制坦克的类
package com.tank.tankGame;
import javax.swing.*;
import java.awt.*;
/**
* 绘图区域
*/
public class MyPanel extends JPanel {
// 定义我的坦克
MyTank myTank = null;
public MyPanel() {
myTank = new MyTank(100, 100);//初始化一个自己的坦克
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
// 画出坦克-封装方法
drawTank(myTank.getX(), myTank.getY(), g, 0, 0);
}
// 编写方法,画出坦克
/**
* @param x 坦克x坐标
* @param y 坦克左上角坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
// 根据不同类型坦克,绘制不同颜色
switch (type) {
case 0: // 我的坦克
g.setColor(Color.cyan);
break;
case 1: //敌人的坦克
g.setColor(Color.yellow);
break;
}
// 根据坦克的方向来绘制坦克
switch (direct) {
case 0: //表示方向向上
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y - 10);//炮筒
break;
default:
System.out.println("暂时不处理");
}
}
}
- 主方法
package com.tank.tankGame;
import javax.swing.*;
public class HspTankGame01 extends JFrame {
// 定义MyPanel
MyPanel mp = null;
public static void main(String[] args) {
HspTankGame01 hspTankGame01 = new HspTankGame01();
}
public HspTankGame01() {
mp = new MyPanel();
this.add(mp);
this.setSize(1000, 750);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
- 运行效果图
4.小球移动
package com.tank.event;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class BallMove extends JFrame {//窗口
MyPanel mp = null;
// 构造器
public BallMove() {
mp = new MyPanel();
this.add(mp);
this.setSize(400, 300);
// 窗口JFrame对象可以监听键盘事件,即可以监听到面板上发生的键盘事件
this.addKeyListener(mp);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
BallMove ballMove = new BallMove();
}
}
// 面板,可以画出小球
//KeyListener 是监听器,可以监听键盘事件
class MyPanel extends JPanel implements KeyListener {
//为了让小球可以移动,把它左上角的坐标(x,y)设置变量
int x = 10;
int y = 10;
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 20, 20); //默认黑色
}
// 有字符输出时,会触发
@Override
public void keyTyped(KeyEvent e) {
}
// 当某个键按下触发
@Override
public void keyPressed(KeyEvent e) {
System.out.println((char) e.getKeyCode() + "被按下");
//根据用户按下的不同键,来控制小球移动
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
y += 10;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
y -= 10;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
x -= 10;
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
x += 10;
}
// 重绘面板
this.repaint();
}
// 键松开会触发
@Override
public void keyReleased(KeyEvent e) {
}
}
5.JAVA事件处理机制
6.绘制坦克上下左右移动
package com.tank.tankGame02;
import javax.swing.*;
import java.awt.*;
/**
* 绘图区域
*/
public class MyPanel extends JPanel {
// 定义我的坦克
MyTank myTank = null;
public MyPanel() {
myTank = new MyTank(100, 100);//初始化一个自己的坦克
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
// 画出坦克-封装方法
drawTank(myTank.getX(), myTank.getY(), g, 0, 0);
drawTank(myTank.getX() + 200, myTank.getY(), g, 1, 1);
drawTank(myTank.getX() + 400, myTank.getY(), g, 2, 1);
drawTank(myTank.getX() + 600, myTank.getY(), g, 3, 1);
}
// 编写方法,画出坦克
/**
* @param x 坦克x坐标
* @param y 坦克左上角坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
// 根据不同类型坦克,绘制不同颜色
switch (type) {
case 0: // 我的坦克
g.setColor(Color.cyan);
break;
case 1: //敌人的坦克
g.setColor(Color.yellow);
break;
}
// 根据坦克的方向来绘制坦克
// direct 表示方向(0,1,2,3)上右下左
switch (direct) {
case 0: //表示方向向上
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y - 10);//炮筒
break;
case 1: //表示方向向右
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 30, y + 20, x + 60, y + 20);//炮筒
break;
case 2: //表示方向向下
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y + 60);//炮筒
break;
case 3: //表示方向向左
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 20, x - 20, y + 20);//炮筒
break;
default:
System.out.println("暂时不处理");
}
}
}
7.让坦克动起来
package com.tank.tankGame02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* 绘图区域
*/
// 实现KeyListener方法,监听键盘事件,
public class MyPanel extends JPanel implements KeyListener {
// 定义我的坦克
MyTank myTank = null;
public MyPanel() {
myTank = new MyTank(100, 100);//初始化一个自己的坦克
myTank.setSpeed(2); // 设置坦克速度
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
// 画出坦克-封装方法
drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirict(), 1);
}
// 编写方法,画出坦克
/**
* @param x 坦克x坐标
* @param y 坦克左上角坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
// 根据不同类型坦克,绘制不同颜色
switch (type) {
case 0: // 我的坦克
g.setColor(Color.cyan);
break;
case 1: //敌人的坦克
g.setColor(Color.yellow);
break;
}
// 根据坦克的方向来绘制坦克
// direct 表示方向(0,1,2,3)上右下左
switch (direct) {
case 0: //表示方向向上
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y - 10);//炮筒
break;
case 1: //表示方向向右
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 30, y + 20, x + 70, y + 20);//炮筒
break;
case 2: //表示方向向下
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y + 70);//炮筒
break;
case 3: //表示方向向左
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 20, x - 20, y + 20);//炮筒
break;
default:
System.out.println("暂时不处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wdsc键按下的情况
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
//改变坦克方向
myTank.setDirict(0);
// 修改坦克坐标
myTank.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
//改变坦克方向
myTank.setDirict(1);
myTank.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
//改变坦克方向
myTank.setDirict(2);
myTank.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
//改变坦克方向
myTank.setDirict(3);
myTank.moveLeft();
}
this.repaint();//重绘面板
}
@Override
public void keyReleased(KeyEvent e) {
}
}
8.绘制敌人的坦克
package com.tank.tankGame02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
/**
* 绘图区域
*/
// 实现KeyListener方法,监听键盘事件,
public class MyPanel extends JPanel implements KeyListener {
// 定义我的坦克
MyTank myTank = null;
// 定义敌人的坦克,放入到Vector
Vector<HerTank> herTanks = new Vector<>();
int herTankSize = 3;
public MyPanel() {
//初始化一个自己的坦克
myTank = new MyTank(100, 100);
myTank.setSpeed(2); // 设置坦克速度
// 初始化敌人的坦克
for (int i = 0; i < herTankSize; i++) {
//创建一个敌人的坦克
HerTank herTank = new HerTank((100 * (i + 1)), 0);
// 设置坦克方向向下
herTank.setDirict(2);
herTanks.add(herTank);
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色
// 画出自己的坦克-封装方法
drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirict(), 1);
// 画出敌人的坦克
//遍历Vector
for (int i = 0; i < herTanks.size(); i++) {
// 取出坦克
HerTank herTank = herTanks.get(i);
drawTank(herTank.getX(), herTank.getY(), g, herTank.getDirict(), 0);
}
}
// 编写方法,画出坦克
/**
* @param x 坦克x坐标
* @param y 坦克左上角坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克
*/
public void drawTank(int x, int y, Graphics g, int direct, int type) {
// 根据不同类型坦克,绘制不同颜色
switch (type) {
case 0: // 我的坦克
g.setColor(Color.cyan);
break;
case 1: //敌人的坦克
g.setColor(Color.yellow);
break;
}
// 根据坦克的方向来绘制坦克
// direct 表示方向(0,1,2,3)上右下左
switch (direct) {
case 0: //表示方向向上
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y - 10);//炮筒
break;
case 1: //表示方向向右
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 30, y + 20, x + 70, y + 20);//炮筒
break;
case 2: //表示方向向下
g.fill3DRect(x, y, 10, 60, false);//左边的轮子
g.fill3DRect(x + 30, y, 10, 60, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 20, 40, false);//中间的盖子
g.fillOval(x + 10, y + 20, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 30, x + 20, y + 70);//炮筒
break;
case 3: //表示方向向左
g.fill3DRect(x, y, 60, 10, false);//左边的轮子
g.fill3DRect(x, y + 30, 60, 10, false);//右边的轮子
g.fill3DRect(x + 10, y + 10, 40, 20, false);//中间的盖子
g.fillOval(x + 20, y + 10, 20, 20);//中间的小圆盖
g.drawLine(x + 20, y + 20, x - 20, y + 20);//炮筒
break;
default:
System.out.println("暂时不处理");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
//处理wdsc键按下的情况
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
//改变坦克方向
myTank.setDirict(0);
// 修改坦克坐标
myTank.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
//改变坦克方向
myTank.setDirict(1);
myTank.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
//改变坦克方向
myTank.setDirict(2);
myTank.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
//改变坦克方向
myTank.setDirict(3);
myTank.moveLeft();
}
this.repaint();//重绘面板
}
@Override
public void keyReleased(KeyEvent e) {
}
}
9.程序进程线程
10.线程基本使用
package com.tank.threaduse;
public class Thread01 {
public static void main(String[] args) {
// 创建一个Cat对象,可以当做线程使用
Cat cat = new Cat();
cat.start();
}
}
// 当一个类继承了Thread类,该类就可以当做线程使用
class Cat extends Thread {
@Override
public void run() {
int i = 0;
super.run();//重写run方法,写上自己的业务逻辑
while (true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
System.out.println("hello" + i);
if (i == 80) {
break;
}
}
}
}
package com.tank.threaduse;
/**
* 通过实现Runnable 来开发线程
*/
public class Thread02 {
public static void main(String[] args) {
Dog dog = new Dog();
// dog.start();// 这里不能调用start
// 创建Thread对象,把dog对象(实现Runnable)放入Thread
Thread thread = new Thread(dog);
thread.start();
}
}
class Dog implements Runnable { //通过实现Runnable 来开发线程
int count = 0;
@Override
public void run() {
while (true) {
System.out.println("hello" + (++count) + Thread.currentThread().getName());
// 休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 10) {
break;
}
}
}
}
package com.tank.threaduse;
/**
* mian线程启动两个子线程
*/
public class Thread03 {
public static void main(String[] args) {
T1 t1 = new T1();
T2 t2 = new T2();
Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);
thread1.start();
thread2.start();
}
}
class T1 implements Runnable {
int count = 0;
@Override
public void run() {
// 每隔一秒输出hello
while (true) {
System.out.println("hello" + (count++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 50) {
break;
}
}
}
}
class T2 implements Runnable {
int count = 0;
@Override
public void run() {
while (true) {
// 每隔一秒输出world
System.out.println("world" + (++count));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 100) {
break;
}
}
}
}
11.继承Thread与实现Runnable的区别
package com.tank.ticket;
/**
* 使用多线程,模拟三个窗口同时售票100张,,出现超卖的问题
*/
public class SellTicket {
public static void main(String[] args) {
// 使用Thread ,出现超卖的问题
// SellTicket01 sellTicket01 = new SellTicket01();
// SellTicket01 sellTicket02 = new SellTicket01();
// SellTicket01 sellTicket03 = new SellTicket01();
//
// sellTicket01.start();
// sellTicket02.start();
// sellTicket03.start();
// 使用Runnable,也会出现超卖的问题
SellTicket02 sellTicket02 = new SellTicket02();
new Thread(sellTicket02).start();
new Thread(sellTicket02).start();
new Thread(sellTicket02).start();
}
}
// 使用Runnable
class SellTicket02 implements Runnable {
private int ticketNum = 100;//让多个线程共享ticketNum
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
break;
}
// 休眠50毫秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票,剩余票数为:" + (--ticketNum));
}
}
}
// 使用Thread
class SellTicket01 extends Thread {
private static int ticketNum = 100;//让多个线程共享ticketNum
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
System.out.println("售票结束...");
break;
}
// 休眠50毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口" + Thread.currentThread().getName() + "售出一张票,剩余票数为:" + (--ticketNum));
}
}
}
12.线程终止
package com.tank.exit;
/**
* 主线程终止子线程
*/
public class ThreadExit {
public static void main(String[] args) {
T t1 = new T();
t1.start();
// 如果希望主线程去控制t1 线程的终止,修改loop就可以了
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 让主线程休眠10s
t1.setLoop(false);
}
}
class T extends Thread {
private int count = 0;
// 设置一个控制变量
private boolean loop = true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("AThread运行中..." + (count++));
}
}
}
13.线程常用方法