分为两个项目分别为:
- 《绘图项目》设计
- 《学生管理项目》设计
(二)、《绘图项目》设计
1、完成效果图
- 可以画圆
- 可以画矩形
- 可以移动图形
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