Java实训项目笔记(绘画项目)

分为两个项目分别为:

  • 《绘图项目》设计
  • 《学生管理项目》设计

(二)、《绘图项目》设计

1、完成效果图

image-20210706160800582

  • 可以画圆
  • 可以画矩形
  • 可以移动图形

2、项目的目录

每个项目里都有注释代码,所以不再过多描述

3、每个文件下的代码

- ShapeMgr.java

package org.ngweb.drawing.manager;
import java.awt.Graphics;
import java.util.*;

import org.ngweb.drawing.shapes.inferfaze.IShape;
public class ShapeMgr {
	private List<IShape> shapeList;
	//类型:List
	//用于存放所有的形状的接口
	
	//构造方法
	public ShapeMgr(){
		shapeList = new LinkedList();
	}
	//添加和移除
	public void addShape(IShape shape){
		shapeList.add(shape);
	}
	//通过下标移除形状
	public void removeShape(int shapeIndex){
		shapeList.remove(shapeIndex);
	}
	//size中含有多少个形状
	public int size(){
		return shapeList.size();
	}
	//获得某个下标值得一个形状
	public IShape getShape(int shapeIndex){
		return shapeList.get(shapeIndex);
	}
	
	
	//接收一个参数Graphics g,对每一个绘制图像都需要一个Graphics g这个参数
	//所有和drawing有关的参数都要加上这个参数
	public void redrawing(Graphics g){
		for(int i=0; i<shapeList.size();i++){
			IShape shape = shapeList.get(i);
			shape.drawing(g);
		}
	}
}

- MyCircle.java

package org.ngweb.drawing.shapes;

import java.awt.Graphics;
//继承了MyShape类
public class MyCircle extends MyShape{
	//get\set方法
	public int getRadius() {
		return radius;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}

	int radius;
	//面积
	@Override
	public int area() {
		// TODO Auto-generated method stub
		return (int)Math.PI*radius*radius;
	}
	//字符输出,表示什么位置画的是啥
	@Override
	public void drawing(Graphics g) {
		//画圆
		g.fillOval(location.getX(), location.getY(),radius,radius);
		//x,y,长=宽
		System.out.println("在位置(x="+location.getX()+",y="+location.getY()+")画一个圆, 半径是=" + radius + ", 面积是="+area());
	}

	//判断鼠标是否在形状中:鼠标的x,y的坐标距离圆心的距离
	@Override
	public boolean insideMe(int x, int y) {
		int centerX = location.getX() + (int)radius /2;
		int centerY = location.getY() +	(int)radius /2;
		if (Math.sqrt((x - centerX)* (x-centerX) + (y - centerY)
				*(y - centerY))< radius/2) {
			return true;
		}
				return false;
	}

}

- MyLocation.java

//表示屏幕的x,y坐标
package org.ngweb.drawing.shapes;
public class MyLocation {
	private int x;
	private int y;
	//默认构造方法
	public MyLocation(){
		
	}
	//带有屏幕坐标位置的方法,进行初始化
	public MyLocation(int x, int y){
		this.x=x;
		this.y=y;
	}
	//用于设置location的位置。
	public void setMyLocation(int x, int y){
		this.x=x;
		this.y=y;
	}
	//get、set方法
	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;
	}
	
}

- MyRectangle.java

package org.ngweb.drawing.shapes;

import java.awt.Graphics;

public class MyRectangle extends MyShape{
	//高度、宽度的属性
	int width;
	int height;
	
	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	//获取面积
	@Override
	public int area() {
		return height*width;
	}

	//字符输出,表示什么位置画的是啥
	@Override
	public void drawing(Graphics g) {
		//画长方形
		g.fillRect(location.getX(),location.getY(), width, height);
		System.out.println("在位置(x=" + location.getX() + ",y=" + location.getY()
				+ ")画一个矩形, 高是=" + height + ", 宽是=" + width + ", 面积是=" + area());
	}

	//判断鼠标是否在形状中:满足两个条件
	@Override
	public boolean insideMe(int x, int y) {
		if (x>location.getX()&& x<location.getX()+width) {
			if (y>location.getY()&& y<location.getY()+height) {
				return true;
			}
		}
		return false;
	}

}

- MyShape.java

package org.ngweb.drawing.shapes;

import org.ngweb.drawing.shapes.inferfaze.IShape;
//引入抽象类
public abstract class MyShape implements IShape{
	MyLocation location;
	//定义所有形状的位置

	@Override
	public MyLocation getMylocation() {
		
		return location;
	}

	
	@Override
	public void moveTo(MyLocation location) {
		this.location = location;
		//将当前的位置设置为传入的值
	}

	@Override
	public void setMyLocation(MyLocation location) {
		this.location = location;
		
	}

}

- DrawingTest.java

package org.ngweb.drawing.test;

import org.ngweb.drawing.shapes.*;

public class DrawingTest {
	public static void main(String[] args) {
		MyRectangle r = new MyRectangle();
		
		MyLocation l = new MyLocation(20,30);
		r.setMyLocation(l);
		r.setHeight(150);
		r.setWidth(100);
		System.out.println("移动前是");
		//r.drawing();
		
		r.moveTo(new MyLocation(50,50));
		System.out.println("移动后是");
		//r.drawing();
	}
}


- ShapeMgrTest.java

package org.ngweb.drawing.test;
import org.ngweb.drawing.manager.ShapeMgr;
import org.ngweb.drawing.shapes.*;
public class ShapeMgrTest {
   public static void main(String[] args) {
      ShapeMgr  canvas = new ShapeMgr();
      MyRectangle r = new MyRectangle();
      r.setMyLocation(new MyLocation(30,50));
      r.setHeight(80);
      r.setWidth(50);
      MyCircle c = new MyCircle();
      c.setMyLocation(new MyLocation(200,220));
      c.setRadius(70);
      canvas.addShape(r);
      canvas.addShape(c);
      System.out.println("当前画布上是:");
      //canvas.redrawing();

      canvas.removeShape(0);
      System.out.println("\n删除第一个形状后画布上是:");
      //canvas.redrawing();
   }
}

- Painting.java

package org.ngweb.drawing.view;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

import org.ngweb.drawing.manager.ShapeMgr;
import org.ngweb.drawing.shapes.*;
import org.ngweb.drawing.shapes.inferfaze.IShape;

public class Painting extends JFrame{
	// 定义表示动作的常量
	final int MOVE =0;  // 移动图形
	final int CIRCLE =1;  // 添加圆
	final int RECTANGLE =2; // 添加矩形
	
	// 记录用户对动作的选择,默认是添加圆
	int action = CIRCLE;
	
	// 管理形状
	ShapeMgr shapeMgr = new ShapeMgr();

	// 当前操作的形状下标
	int shapeIndex =0;
	
	// 拖动鼠标时的位移量
	int incX=0;
	int incY=0;

	/**
	 * 主方法,仅需调用构造方法
	 */
	public static void main(String[] args) {
		Painting p = new Painting();
	}
	/**
	 * 构造方法
	 */
	Painting(){
		super("网络31931班(盛文龙)");
		JPanel p1 = new JPanel(); // 画板
		JPanel p2 = new JPanel(); // 工具条
		
		// 1 定义工具条上的三个按钮以及监听器
		JButton m = new JButton("移动");
		JButton c = new JButton("圆形");
		JButton r = new JButton("矩形");
		m.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				action = MOVE;
			}
		});
		
		c.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				action = CIRCLE;
			}
		});
		
		r.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				action = RECTANGLE;
			}
		});
		
		// 2 将按钮加到工具条面板上
		p2.add(m);
		p2.add(c);
		p2.add(r);
		
		// 3 将面板加到JFrame上
		this.setLayout(new BorderLayout());
		this.add(BorderLayout.CENTER,p1);
		this.add(BorderLayout.SOUTH,p2);
		
		// 4 设置JFrame可见
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(400,300);
		this.setVisible(true);
		
		// 添加JFrame的监听器,点击鼠标时的动作
		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if(action == MOVE){
					// 找出选中哪个图形,记录下来,以后将移动这个图形
					// 如果在同一位置有二个,也只选第一个图形,放弃第二个或更多图形
					shapeIndex=-1;
					for(int i=0;i<shapeMgr.size();i++){
						IShape s = (IShape)shapeMgr.getShape(i);
						if(s.insideMe(e.getX(), e.getY())){
							shapeIndex=i;
							incX = e.getX()-s.getMylocation().getX(); 
							incY = e.getY()-s.getMylocation().getY(); 
							// 放弃第二个或更多图形
							break;
						}
					}
					// 如果没有选中,则提示
					if(shapeIndex==-1){
						showMsg("没有选中图形。");
						repaint();
					}
				}

				if(action == CIRCLE){
					// 添加一个圆,记录参考位置
					MyCircle c = new MyCircle();
					c.setMyLocation(new MyLocation(e.getX(),e.getY()));
					shapeMgr.addShape(c);
					shapeIndex = shapeMgr.size()-1;
				}
				if(action == RECTANGLE){
					// 添加一个矩形,记录参考位置
					MyRectangle r = new MyRectangle();
					r.setMyLocation(new MyLocation(e.getX(),e.getY()));
					shapeMgr.addShape(r);
					shapeIndex = shapeMgr.size()-1;
				}
			}
		});
		
		// 添加JFrame的监听器,拖动鼠标时的动作
		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				if(action == MOVE){
					if(shapeIndex>=0){
						// 如果曾经选中一个图形,移动它(拖动鼠标)
						IShape s = (IShape)shapeMgr.getShape(shapeIndex);
						s.moveTo(new MyLocation(e.getX()-incX,e.getY()-incY));
					}
				}

				if(action == CIRCLE){
					// 拖动鼠标,以纵或横向的距离设置圆的半径
					MyCircle c = (MyCircle)shapeMgr.getShape(shapeIndex);
					int x=Math.abs(e.getX()-c.getMylocation().getX());
					int y=Math.abs(e.getY()-c.getMylocation().getY());
					c.setRadius(x>y?x:y);
				}
				if(action == RECTANGLE){
					// 拖动鼠标,以纵和横向的距离设置矩形的宽和高
					MyRectangle r = (MyRectangle)shapeMgr.getShape(shapeIndex);
					int x=Math.abs(e.getX()-r.getMylocation().getX());
					int y=Math.abs(e.getY()-r.getMylocation().getY());
					r.setHeight(y);
					r.setWidth(x);
				}
				// 重新绘制整幅图
				// 该方法将自动调用paint(Graphics g)
				repaint();
			}
		});
	}
//swl:刚开始这里不能画图,原因是没有传入Graphics g这个参数,传入之后shapeMgr.redrawing
//报错,需要修改相应的
	public void paint(Graphics g){
		// 清屏幕
		super.paint(g);
		// 设置图的颜色
		g.setColor(Color.blue);
		shapeMgr.redrawing(g);
	}
	void showMsg(String msg){
		// 显示信息
		JOptionPane.showMessageDialog(this, msg);
	}
}

4、回答老师的关键问题

当圆形和矩形重叠在一起时,如果在重叠区域点击选择,那么,哪个图形将被移动?

为什么(实现原理)?

答:如果两个图形叠加在一起,选择移动的重叠部分的图形,会按照画图的先后顺序,来判断。比如我先画的圆,然后画的矩形,把它们叠加,然后选择移动叠加的部分,无论怎么选择都会选择圆,因为他的顺序是1,。倒过来先画矩形,就只会选择矩形。

代码:

		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if(action == MOVE){
					// 找出选中哪个图形,记录下来,以后将移动这个图形
					// 如果在同一位置有二个,也只选第一个图形,放弃第二个或更多图形
					shapeIndex=-1;
					for(int i=0;i<shapeMgr.size();i++){
						IShape s = (IShape)shapeMgr.getShape(i);
						if(s.insideMe(e.getX(), e.getY())){
							shapeIndex=i;
							incX = e.getX()-s.getMylocation().getX(); 
							incY = e.getY()-s.getMylocation().getY(); 
							// 放弃第二个或更多图形
							break;
						}
					}

还有一个问题是:如何让只选第二个图形,放弃第一个或更多图形?(与原本顺序相反)

//如下修改:
for(int i;i=shapeMgr.size()-1;i<=0;i--)

java变成exe:https://www.cnblogs.com/icewee/articles/2073203.html

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无法长大的Panda

您的鼓励是最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值