今天为大家分享一个java语言写的画图程序,该程序和window自带的画图板功能非常相似,后续会进一步完善。整个系统界面漂亮,有完整源码,希望大家可以喜欢。喜欢的帮忙点赞和关注。一起编程、一起进步
开发环境
开发语言为Java,开发环境Eclipse或者IDEA都可以,无需要数据库。运行主程序,或者执行打开JAR文件即可以运行本程序。
系统框架
利用JDK自带的SWING框架开发,下载。纯窗体模式,直接运行Main文件即可以。同时带有详细得设计文档。
主要功能点
本次分享的为Java编写的画图板,功能类似window自带的画板,主要的功能有以下一些
1 画笔功能:画直线、画矩形、画椭圆、画五角星
2橡皮擦功能:类似window的橡皮擦,擦擦指定的区域
3 文字:在指定的区域编写文字,包括文字
4 设置:设置字体类型,字体大小、字体颜色,
5 打开图片,修改图片,保存图片
6 撤销和复制、粘贴。
7 设置画图板的前景颜色和背景颜色
8 对自动范围的图形进行移动操作
这个项目涵盖了java 窗体编程的各种知识,包括UI界面设计、时间处理、文件、事件处理操作等。通过这个项目能快速提升java 窗体编程,是非常好的一个项目。代码可以直接运行,没有任何bug。有详细的操作手册。
运行效果
关键代码
package cn.com.thinkbank;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import cn.com.thinkbank.Shape.*;
/**
* 设置画板属性
*/
public class MyPanel extends JPanel {
private static final long serialVersionUID = 6163201700139767006L;
private JPopupMenu po;
private Color a = Color.BLACK;
private MyGriding mg = new MyGriding(0, 0, 0, 0, Color.BLACK);
private MyShape currentShape;
private ArrayList<MyShape> shapeList = new ArrayList<MyShape>();// 图形集合;
private ArrayList<MyShape> selectedList = new ArrayList<MyShape>();// 选择集合;
private ArrayList<JLabel> labelList = new ArrayList<JLabel>();// 存文本;
private ArrayList<MyShape> allList = new ArrayList<MyShape>();// shapeList+selectedList;
private ArrayList<MyShape> temList = new ArrayList<MyShape>();// 用于复制剪切的临时集合;
private ArrayList<MyShape> temLineList = new ArrayList<MyShape>();// 用于移动与图形联系在一起的直线。
private int i = 1;// 选择当前图形;
private boolean paste;
private boolean bl = false;// 控制图形有没有被选中;
private boolean bb = false;// 控制在选择状态下不会画图;
private boolean br = false;// 控制移动时可否显示白框;
float x1, y1, x2, y2;
private MyText mm;
JScrollPane js;
private int updateX, updateY, sx1, sy1, sx2, sy2;
private MyRec mr;
Color c = getA();
public MyPanel() {
po = new JPopupMenu();
JMenuItem cut = new JMenuItem("剪切");
JMenuItem copy = new JMenuItem("复制");
JMenuItem paste = new JMenuItem("粘贴");
po.add(cut);
po.add(copy);
po.add(paste);
this.setLayout(null);
this.setBackground(new Color(0, 153, 255));
this.setVisible(true);
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
sx1 = e.getX();
sy1 = e.getY();
int x = e.getX();
int y = e.getY();
createShape(i);
if (currentShape != null && !bl) {
currentShape.setX1(x);
currentShape.setY1(y);
}
if (mm != null && bl) {
mm.setX1(x);
mm.setY1(y);
}
if (currentShape == null && selectedList != null) {
updateX = x;
updateY = y;
Iterator it = selectedList.iterator();
while (it.hasNext()) {
MyShape ms = (MyShape) it.next();
boolean b1 = (x >= ms.getX1() - 3)
&& (y >= ms.getY1() - 3)
&& (x <= ms.getX1() + 3)
&& (y <= ms.getY1() + 3);
boolean b2 = (x >= ms.getX2() - 3
&& y >= ms.getY2() - 3 && x <= ms.getX2() + 3 && y <= ms
.getY2() + 3);
if (b1) {
ms.setLocation(1);// 点在左上角;
} else if (b2) {
ms.setLocation(2);// 点在右下角;
} else if (!b1 && !b2)// 点在别的地方;
{
temLineList.clear();
ms.setLocation(3);
Iterator ite = selectedList.iterator();
while (ite.hasNext()) {
MyShape mss = (MyShape) ite.next();
findLine(mss);
}
}
}
}
}
/**
* <p>
* 监听事件.
* </p>
*
*/
public void mouseReleased(MouseEvent e) {
br = false;
sx2 = e.getX();
sy2 = e.getY();
int x = e.getX();
int y = e.getY();
if (currentShape != null && !bl) {
currentShape.setX2(x);
currentShape.setY2(y);
shapeList.add(currentShape);
}
if (mm != null && bl) {
mm.setX2(x);
mm.setY2(y);
mm = new MyText(mm.getX1(), mm.getY1(), mm.getX2(), mm
.getY2(), c);
mm.setMt(new JLabel(JOptionPane.showInputDialog("")));
shapeList.add(mm);
labelList.add(mm.getMt());
addm(mm);
repaint();
}
if (currentShape == null && bb) {
select(sx1, sy1, sx2, sy2);
}
repaint();
}
public void mouseClicked(MouseEvent e) {
if (currentShape == null) {
select(e.getX(), e.getY());
if (e.getClickCount() == 2) {
try {
Iterator it = selectedList.iterator();
while (it.hasNext()) {
MyShape ms = (MyShape) it.next();
if (ms.isText()) {
MyText mt = (MyText) ms;
selectedList.remove(mt);
labelList.remove(mt.getMt());
removem(mt);
repaint();
mm = new MyText(mt.getX1(), mt.getY1(), mt
.getX2(), mt.getY2(), c);
mm.setMt(new JLabel(JOptionPane
.showInputDialog("")));
shapeList.add(mm);
labelList.add(mm.getMt());
addm(mm);
repaint();
}
}
} catch (ConcurrentModificationException e1) {
}
}
repaint();
}
if (e.getButton()==MouseEvent.BUTTON3){
po.show(e.getComponent(), e.getX(), e.getY());
}
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (currentShape != null && !bl) {
currentShape.setX2(e.getX());
currentShape.setY2(e.getY());
}
if (mm != null && bl) {
mm.setX2(x);
mm.setY2(y);
br = true;
mr = new MyRec(mm.getX1(), mm.getY1(), mm.getX2(), mm
.getY2(), Color.WHITE);
mr.setBo(false);// 文本状态下拖动不画出叉形;
}
if (currentShape == null) {
mr = new MyRec(sx1, sy1, x, y, Color.WHITE);
mr.setBo(false);
if (selectedList != null) {
Iterator ite = selectedList.iterator();
while (ite.hasNext()) {
MyShape ms = (MyShape) ite.next();
if (ms.getLocation() == 1)// 点在左上角,可以变大小;
{
ms.setX1(x);
ms.setY1(y);
repaint();
} else if (ms.getLocation() == 2) {// 点在右下角,可以变大小;
ms.setX2(x);
ms.setY2(y);
repaint();
} else if (ms.getLocation() == 3) {
update(ms, e.getX(), e.getY());
}
}
}
updateX = x; // 不断更新坐标;
updateY = y;
}
repaint();
}
});
cut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
cutList();
}
});
copy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
copyList();
}
});
paste.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
setPaste(true);
pasteList();
}
});
}
public void createShape(int b) {
Color c = getA();
if (i == 1) {
bl = false;
currentShape = new MyLine(0, 0, 0, 0, c);
}
if (i == 2) {
bl = false;
currentShape = new MyRec(0, 0, 0, 0, c);
}
if (i == 3) {
bl = false;
currentShape = new MyOval(0, 0, 0, 0, c);
}
if (i == 4) {
bl = false;
currentShape = new MyFillRec(0, 0, 0, 0, c);
}
if (i == 5) {
bl = false;
currentShape = new MyFillOval(0, 0, 0, 0, c);
}
if (i == 6) {
bl = true;
mm = new MyText(0, 0, 0, 0, c);
currentShape = mm;
}
if (i == 7) {
bl = false;
bb = false;
currentShape = null;
}
if (i == 8) {
bl = false;
currentShape = null;
bb = true;
br = true;
}
if (i == 9) {
bl = false;
currentShape = new MyStar(0, 0, 0, 0, c);
}
}
/**
* <p>
* 添加文本方法
* </p>
*/
protected void paintComponent(Graphics g) {
super.paintComponent(g);
mg.draw(g);
if (br) {// 如果在文本状态下,则画方框;
mr.draw(g);
}
allList.clear();
allList.addAll(shapeList);
allList.addAll(selectedList);
Iterator itt = allList.iterator();
while (itt.hasNext()) {
MyShape myShape = (MyShape) itt.next();
myShape.draw(g);
}
if (currentShape != null && !bl) {
currentShape.draw(g);
}
}
// 清屏;
/**
* <p>
* 清空方法.
* </p>
* 编写画板的清空方法,将画板初始化
*/
public void clearList() {
currentShape = null; // 必须清掉currentShape;
shapeList.clear();
selectedList.clear();
allList.clear();
Iterator it = labelList.iterator();
while (it.hasNext()) {
JLabel jlabel = (JLabel) it.next();
this.remove(jlabel); // 清除所有文本;
}
}
/**
* <p>
* 添加文本.
* </p>
* 添加文本,调用 MyText中的方法,重绘
*/
public void addm(MyText mt) {
this.add(mt.getMt());
repaint();
}
/**
* <p>
* 移除文本.
* </p>
* 移除文本,调用MyText中的方法,重绘
*/
public void removem(MyText mt) {
this.remove(mt.getMt());
repaint();
}
/**
* <p>
* 选择方法.
* </p>
* 图形的选择方法
*/
public void select(int x, int y) {
ArrayList<MyShape> tem1 = new ArrayList<MyShape>();// 选中集合;
allList.addAll(selectedList);
allList.addAll(shapeList);
for (int i = 0; i < allList.size(); i++) {
MyShape ms = (MyShape) allList.get(i);
if (x > Math.min(ms.getX1(), ms.getX2()) + 3
&& x <= Math.max(ms.getX1(), ms.getX2()) - 3
&& y >= Math.min(ms.getY1(), ms.getY2()) + 3
&& y <= Math.max(ms.getY1(), ms.getY2()) - 3) {
tem1.add(ms);// 添加到选中集合;
}
}
int min = 1000000;
int minIndex = 0;
// 同时点选中几个图形,只选择距鼠标点较近的图形;
for (int i = 0; i < tem1.size(); i++) {
int minX = Math.min(tem1.get(i).getX1(), tem1.get(i).getX2());
int minY = Math.min(tem1.get(i).getY1(), tem1.get(i).getY2());
int dist = (minX - x) * (minX - x) + (minY - y) * (minY - y);
if (dist < min) {
min = dist;
minIndex = i;
}
}
if (tem1.size() != 0) {
tem1.get(minIndex).setBl(true);
shapeList.remove(tem1.get(minIndex));
selectedList.add(tem1.get(minIndex));
repaint();
}
if (tem1.size() == 0) { // 如果均没有选中,则选中集合全部清空;
for (int i = 0; i < selectedList.size(); i++) {
selectedList.get(i).setBl(false);
}
shapeList.addAll(selectedList);
selectedList.clear();
repaint();
}
tem1.clear();
allList.clear();
}
/**
* <p>
* 图形移动方法.
* </p>
* 图形的移动方法
*/
public void update(MyShape ms, int x, int y) {
repaint();
// 联系点跟着图形一起移动;
Iterator itt = temLineList.iterator();
while (itt.hasNext()) {
MyShape myshape = (MyShape) itt.next();
if (ms.link(myshape) == 1) {
myshape.setX1(ms.getSpecial().getX1() + 3 + (x - updateX));
myshape.setY1(ms.getSpecial().getY1() + 3 + (y - updateY));
repaint();
}
if (ms.link(myshape) == 2) {
myshape.setX2(ms.getSpecial().getX1() + 3 + (x - updateX));
myshape.setY2(ms.getSpecial().getY1() + 3 + (y - updateY));
repaint();
}
repaint();
}
// 图形移动;
ms.setX1(ms.getX1() + (x - updateX));
ms.setY1(ms.getY1() + (y - updateY));
ms.setX2(ms.getX2() + (x - updateX));
ms.setY2(ms.getY2() + (y - updateY));
br = false; // 控制移动选定集合时不显示白框;
repaint();
}
// 用于存放与选择图形相连的直线集合;
public void findLine(MyShape ms) {
Iterator it = shapeList.iterator();
while (it.hasNext()) {
MyShape myShape = (MyShape) it.next();
if (myShape.isLine()) {
if (ms.link(myShape) == 1 || ms.link(myShape) == 2)
temLineList.add(myShape);
}
}
}
/**
* <p>
* 文本删除方法.
* </p>
* 编写文本的删除方法,清空存放文本集合
*/
public void delete() {
Iterator it = selectedList.iterator();
while (it.hasNext()) {
MyShape mt = (MyShape) it.next();
if (mt.isText()) {
this.remove(mt.getMt());
}
repaint();
}
selectedList.clear();
repaint();
}
/**
* <p>
* 框选方法.
* </p>
* 图形的框选,多选方法
*/
public void select(int x1, int y1, int x2, int y2) {
int minX = Math.min(x1, x2);
int minY = Math.min(y1, y2);
int maxX = Math.max(x1, x2);
int maxY = Math.max(y1, y2);
List<MyShape> temporary = new ArrayList<MyShape>();
temporary.addAll(shapeList);
int size = shapeList.size(); // 用临时变量替换在变化的shapeList;
for (int i = 0; i < size; i++) { // shapeList在变,不能用shapeList.size();
MyShape ms = (MyShape) temporary.get(i);
int x3 = Math.min(ms.getX1(), ms.getX2());
int y3 = Math.min(ms.getY1(), ms.getY2());
int x4 = Math.max(ms.getX1(), ms.getX2());
int y4 = Math.max(ms.getY1(), ms.getY2());
if (x3 >= minX && y3 >= minY && x4 <= maxX && y4 <= maxY) {
ms.setBl(true);
shapeList.remove(ms);
selectedList.add(ms);
}
}
repaint();
}
/**
* <p>
* 复制方法.
* </p>
* 添加复制方法并且调用
*/
public void copyList() {
temList.clear();
for (int i = 0; i < selectedList.size(); i++) {
// MyShape ms=selectedList.get(i);
// 引用传递,ms变了,shapeList里的ms也变了,另创建一个与ms内容相同的对象。
selectedList.get(i).setBl(false);
if (selectedList.get(i).isText()) {
((MyText) selectedList.get(i)).setJp(this);
}// 这样也可以持有对方引用;
shapeList.add(selectedList.get(i).copy());
temList.add(selectedList.get(i));
}
selectedList.clear();
for (int i = 0; i < temList.size(); i++) {
temList.get(i).setX1(temList.get(i).getX1() + 30);
temList.get(i).setX2(temList.get(i).getX2() + 30);
temList.get(i).setY1(temList.get(i).getY1() + 30);
temList.get(i).setY2(temList.get(i).getY2() + 30);
temList.get(i).setBl(true);
selectedList.add(temList.get(i));
}
repaint();
}
/**
* <p>
* 剪切方法.
* </p>
* 剪切方法,用于图形的多元化
*/
public void cutList() {
temList.clear();
for (int i = 0; i < selectedList.size(); i++) {
if (selectedList.get(i).isText()) {
selectedList.get(i).getMt().setVisible(false);
}
}
temList.addAll(selectedList);
selectedList.clear();
repaint();
}
/**
* <p>
* 调用粘贴方法.
* </p>
* 粘贴方法
*/
public void pasteList() {
if (paste) {
selectedList.addAll(temList);
for (int i = 0; i < selectedList.size(); i++) {
if (selectedList.get(i).isText()) {
selectedList.get(i).getMt().setVisible(true);
}
}
repaint();
}
}
/**
* <p>
* 撤销方法.
* </p>
* 数据的撤销方法
*/
public void undo() {
try {
currentShape = null;
if (shapeList.get(shapeList.size() - 1).isText()){
this.remove(shapeList.get(shapeList.size() - 1).getMt());
}
shapeList.remove(shapeList.size() - 1);
repaint();
} catch (Exception e) {
// TODO: handle exception
}
}
/**
*
* @return 返回currentShape的值
*/
public MyShape getCurrentShape() {
return currentShape;
}
/**
*
* @param currentShape设置当前变量
*/
public void setCurrentShape(MyShape currentShape) {
this.currentShape = currentShape;
}
/**
*
* @return 返回i的值
*/
public int getI() {
return i;
}
/**
*
* @param i设置当前变量
*/
public void setI(int i) {
this.i = i;
}
/**
*
* @return 返回b1的值,做判断用
*/
public boolean isBl() {
return bl;
}
/**
* @param bl 设置当前的值
*/
public void setBl(boolean bl) {
this.bl = bl;
}
/**
* @return 返回当前颜色
*/
public Color getBack() {
return this.getBackground();
}
/**
*
* @return 返回br的值
*
*/
public boolean isBr() {
return br;
}
/**
*
* @param br 设置当前的值
*/
public void setBr(boolean br) {
this.br = br;
}
/**
*
* @return 返回selectedList的值
*/
public List<MyShape> getSelectedList() {
return selectedList;
}
/**
*
* @param selectedList设置selectedList的值
*/
public void setSelectedList(ArrayList<MyShape> selectedList) {
this.selectedList = selectedList;
}
/**
*
* @return 返回当前paste的值
*/
public boolean isPaste() {
return paste;
}
/**
*
* @param paste 设置当前paste的值
*/
public void setPaste(boolean paste) {
this.paste = paste;
}
/**
*
* @return 返回当前temList
*/
public List<MyShape> getTemList() {
return temList;
}
/**
*
* @param temList 设置当前的temList
*/
public void setTemList(ArrayList<MyShape> temList) {
this.temList = temList;
}
/**
* @return a 返回当前a的值
*/
public Color getA() {
return a;
}
/**
* @param a 要设置的 a
*
*/
public void setA(Color a) {
this.a = a;
Iterator it=selectedList.iterator();
while(it.hasNext()){
((MyShape)it.next()).setC(a);
}
repaint();
}
/**
*
* @return 返回当前labelLIst
*/
public ArrayList<JLabel> getLabelList() {
return labelList;
}
/**
*
* @param labelList 设置当前的labelList
*/
public void setLabelList(ArrayList<JLabel> labelList) {
this.labelList = labelList;
}
/**
*
* @return 返回当前shapeList
*/
public ArrayList<MyShape> getShapeList() {
return shapeList;
}
/**
*
* @param shapeList 设置当前shapeList的值
*/
public void setShapeList(ArrayList<MyShape> shapeList) {
this.shapeList = shapeList;
}
/**
*
* @return 返回allList的值
*/
public ArrayList<MyShape> getAllList() {
return allList;
}
/**
*
* @param allList 设置当前allList的值
*/
public void setAllList(ArrayList<MyShape> allList) {
this.allList = allList;
}
}