接触java不满一个月,看厚厚的java入门简直要醉,故利用实例来巩固所学知识。

画板的实现其实从原理来说超级简单,可能一会儿就完成了。

但作为一名强迫症患者,要实现和win下面的画板一样的功能还是需要动下脑筋的。

画板雏形:

画板顾名思义,最主要功能就是要来画画的



Java里面的Graphics类里面提供了如下几种方法。

画圆画方画直线都不成问题,只需要提x1,x2,y1,y2即可。

在窗体上加个监听器,在mousePressed时用getX()和getY()获取x1,y1,在mouseReleased时用getX()和getY()获取x2,y2就完成了最简单的画板。

多边形:

多边形如何画呢,win下的画图板通过点击一处放置一个点,再点击一处放置另一个点,双击连接第一个点的和最后一个点完成绘制多边形。

利用以上思路,可以整理为,在mouseClicked时记录点的位置,若是第一个点,则要保存到一个固定的参数,若是其他点,则通过g.drawLine来连接上一个点和这个点,最后通过e.getClickCount()方法来获得是否双击来判断是否需要连接当前点和第一个点。

界面:

窗体的设计非常简单。其中按钮可以用循环来放置。加入监听器后可以通过e.getActionCommand()来获取按钮上的字符串。颜色按钮则可以通过新建一个JButton并利用getSource获取按下的Button,再利用JButton里面的getBackground获取颜色。

最后在本地p个图,利用下边界布局即可获得初级的界面。

最后再在可以绘画的位置加一个Panel,并从窗体获取graphics变成从该Panel获取,监听器改到该Panel下就可以保证画图的部分不会超过绘图区域了。

完成效果如下。

============华丽丽的分割线 强迫症从这里开始==============

画板的基本功能已经实现,但是作为一个强迫症怎么能够满足于鼠标拖拽时最后才凭空冒出来的一根线?

画板改进:

加入MouseMotionListener监听器

MouseMotionListener提供了两种方法

一个鼠标移动,一个是鼠标拖拽。

要想画直线拖拽鼠标的时候有一条实实在在的直线跟在后面跑,岂不是直接在mouseDragged时getx、y然后画出来就好了……于是就变成了这样:



初看觉得美美哒,而且它确确实实画了 不过每移动一点点位置就画了……

解决方案很容易就想到,每次画新的前,用背景色把上一条再画一遍不就好了。于是一条直线的拖拽就做好了。

然而当画第二条直线和第一条相交的时候……把第一条擦掉了是什么鬼!!!!!!!

想到两条解决方法~

1.把画板每个像素的涂色状态用二维数组来储存,然后每次画完一个图形都跟新一次数组。清空时把整个数组清0即可。该方法可能可以通过把现在画的通过BufferedImage中的createGraphyics形成graphycis tmp,然后画在tmp上,最后在读取图片数据来实现。不过貌似好麻烦……舍去。、

2.每画完一笔生成一个图片,然后把背景改成这个,然后再画……额 这个感觉还是有种治标不治本的感觉……舍去。

3.建立链表!!把所有的数据都保存在链表里面去!!然后每次画一笔就从头开始把刚才画的所有东西都画一遍。

由于是初学者,而且第一次在Java上实现链表,于是就按照自己对链表的理解,写了节点如下

package com.frame;

import java.awt.Color;
import java.awt.Graphics; public class PaintedList {
private String cmd;
private DuoList PLi;
private int x1, y1, x2, y2;
private DuoList li;
private PaintedList next;
private Color color; public DuoList getPLi() {
return PLi;
} public void setPLi(DuoList pLi) {
PLi = pLi;
} public Color getColor() {
return color;
} public void setColor(Color color) {
this.color = color;
} public String getCmd() {
return cmd;
} public void setCmd(String cmd) {
this.cmd = cmd;
} public PaintedList getNext() {
return next;
} public void setNext(PaintedList next) {
this.next = next;
} public int getX1() {
return x1;
} public void setX1(int x1) {
this.x1 = x1;
} public int getY1() {
return y1;
} public void setY1(int y1) {
this.y1 = y1;
} public int getX2() {
return x2;
} public void setX2(int x2) {
this.x2 = x2;
} public int getY2() {
return y2;
} public void setY2(int y2) {
this.y2 = y2;
} public DuoList getLi() {
return li;
} public void setLi(DuoList li) {
this.li = li;
} public void paint(Graphics g) {
g.setColor(color);
if (cmd.equals("直线")) {
g.drawLine(x1, y1, x2, y2);
} else if (cmd.equals("椭圆")) {
g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
} else if (cmd.equals("矩形")) {
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
} else if (cmd.equals("三角形")) {
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x2 - Math.abs(x2 - x1) * 2, y2);
g.drawLine(x2 - Math.abs(x2 - x1) * 2, y2, x1, y1);
} else if (cmd.equals("多边形")) {
PLi = li;
while (PLi.getnext() != null) {
PLi.printline(g);
PLi = PLi.getnext();
}
}
}
}

多边形也用链表保存了所有的节点

package com.frame;

import java.awt.Graphics;

public class DuoList {
private int x;
private int y;
private DuoList next; public int getx() {
return this.x;
} public int gety() {
return this.y;
} public void setx(int x) {
this.x = x;
} public void sety(int y) {
this.y = y;
} public void setnext(DuoList next) {
this.next = next;
} public DuoList getnext() {
return this.next;
} public void printline(Graphics g) {
if (this.getnext() != null) {
g.drawLine(x, y, next.getx(), next.gety());
}
}
}

值得注意的一点是,由于Java没有指针啥的,每次用完一个节点,在利用这个变量名之前要new一下,相当于malloc一个新的储存空间。

窗体的代码

package com.frame;

import java.awt.*;

import javax.swing.*;

public class Frame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L; public Frame() {
MouseAction m = new MouseAction();
String[] kind = new String[] { "直线", "矩形", "椭圆", "三角形", "多边形", "清空" };
Color[] color = { Color.black, Color.BLUE, Color.GREEN, Color.YELLOW };
this.setSize(827, 647);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBackground(Color.lightGray);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setLayout(new BorderLayout()); ImageIcon im = new ImageIcon("image/bg.jpg");
JLabel jla = new JLabel(im);
this.getLayeredPane().add(jla, new Integer(Integer.MIN_VALUE));
jla.setBounds(0, 0, 827, 627);
JPanel jpanel = (JPanel) this.getContentPane();
jpanel.setOpaque(false); JPanel west = new JPanel();
west.setPreferredSize(new Dimension(189, 0));
JPanel tmp1 = new JPanel();
tmp1.setPreferredSize(new Dimension(189, 120));
tmp1.setOpaque(false);
JPanel tmp2 = new JPanel();
tmp2.setPreferredSize(new Dimension(18, 0));
tmp2.setOpaque(false);
JPanel westcenter = new JPanel();
westcenter.setOpaque(false);
west.setLayout(new BorderLayout());
west.add(tmp1, BorderLayout.NORTH);
west.add(tmp2, BorderLayout.WEST);
west.add(westcenter, BorderLayout.CENTER);
for (int i = 0; i < kind.length; i++) {
JButton jbu = new JButton(kind[i]);
jbu.setBorderPainted(false);
jbu.setFont(new Font("楷体", 15, 15));
jbu.setPreferredSize(new Dimension(130, 40));
jbu.setBackground(Color.orange);
westcenter.add(jbu, BorderLayout.CENTER);
jbu.addActionListener(m);
}
for (int i = 0; i < color.length; i++) {
JButton jbu = new JButton();
jbu.setBorderPainted(false);
jbu.setBackground(color[i]);
jbu.setPreferredSize(new Dimension(130, 40));
westcenter.add(jbu, BorderLayout.CENTER);
jbu.addActionListener(m);
}
west.setOpaque(false);
this.add(west, BorderLayout.WEST); JPanel east = new JPanel();
east.setPreferredSize(new Dimension(630, 0));
this.add(east, BorderLayout.EAST);
east.setOpaque(false);
east.setLayout(null); JPanel board = new JPanel();
board.setBounds(23, 28, 589, 567);
// board.setBackground(Color.black);
board.setOpaque(false);
east.add(board); this.setVisible(true); Graphics g = board.getGraphics();
board.addMouseListener(m);
board.addMouseMotionListener(m); m.setGraphics(g);
m.setJFrame(this); }
}

鼠标以及事件监听器的代码

package com.frame;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JFrame; public class MouseAction implements MouseListener, ActionListener, MouseMotionListener {
private Graphics g;
private int time = 0;
private int x1, x2, y1, y2, oldx1, oldy1, curx1, cury1, flag = 0, x3, y3;
private DuoList Li = new DuoList();
private DuoList FLi = new DuoList();
private DuoList PLi = new DuoList();
private PaintedList ALLi = new PaintedList();
private PaintedList FALLi = new PaintedList();
private PaintedList PALLi = new PaintedList();
public DuoList TMP;
public PaintedList tmppaint = new PaintedList();
public PaintedList tmppaint2 = new PaintedList();
private int flag1 = 0; private String cmd = "直线";
private Color color = Color.black; private JFrame frame; public void setJFrame(JFrame frame) {
this.frame = frame;
} public void setGraphics(Graphics g) {
this.g = g;
} public void mouseClicked(MouseEvent e) {
TMP = new DuoList();
tmppaint = new PaintedList();
tmppaint2 = new PaintedList();
if (cmd.equals("多边形")) {
time = e.getClickCount();
if (time == 2 && flag == 1) {
flag = 0;
g.drawLine(curx1, cury1, oldx1, oldy1);
if (flag1 == 0) {
ALLi.setLi(Li);
ALLi.setColor(color);
ALLi.setCmd(cmd);
tmppaint.setX1(curx1);
tmppaint.setX2(oldx1);
tmppaint.setY1(cury1);
tmppaint.setY2(oldy1);
tmppaint.setColor(color);
tmppaint.setCmd("直线");
tmppaint.setNext(null);
ALLi.setNext(tmppaint);
FALLi = tmppaint;
flag1 = 1;
Li = new DuoList(); // 一定要new一个
FLi = new DuoList();
PLi = new DuoList();
} else {
tmppaint.setLi(Li);
tmppaint.setCmd(cmd);
tmppaint.setColor(color);
tmppaint2.setX1(curx1);
tmppaint2.setX2(oldx1);
tmppaint2.setY1(cury1);
tmppaint2.setY2(oldy1);
tmppaint2.setColor(color);
tmppaint2.setCmd("直线");
tmppaint2.setNext(null);
FALLi.setNext(tmppaint);
tmppaint.setNext(tmppaint2);
FALLi = tmppaint2;
Li = new DuoList();
FLi = new DuoList();
PLi = new DuoList();
}
} else {
if (flag == 0) {
flag = 1;
oldx1 = e.getX();
curx1 = oldx1;
oldy1 = e.getY();
cury1 = oldy1;
Li.setx(oldx1);
Li.sety(oldy1);
FLi = Li;
PLi = Li;
FLi.setnext(null);
} else {
FLi.setnext(TMP);
curx1 = e.getX();
cury1 = e.getY();
TMP.setx(curx1);
TMP.sety(cury1);
TMP.setnext(null);
FLi = TMP;
g.setColor(color);
}
}
x3 = curx1;
y3 = cury1;
}
} @Override
public void mouseEntered(MouseEvent e) {
} @Override
public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) {
x1 = e.getX();
x3 = x1;
y1 = e.getY();
y3 = y1;
g.setColor(color);
System.out.println(x1 + " " + y1); } public void mouseReleased(MouseEvent e) {
final PaintedList tmppaint = new PaintedList();
x2 = e.getX();
y2 = e.getY();
if (cmd.equals("直线")) {
g.drawLine(x1, y1, x2, y2);
} else if (cmd.equals("椭圆")) {
g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
} else if (cmd.equals("矩形")) {
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
} else if (cmd.equals("三角形")) {
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x2 - Math.abs(x2 - x1) * 2, y2);
g.drawLine(x2 - Math.abs(x2 - x1) * 2, y2, x1, y1);
}
if (cmd.equals("多边形")) { } else {
if (flag1 == 0) {
ALLi.setX1(x1);
ALLi.setX2(x2);
ALLi.setY1(y1);
ALLi.setY2(y2);
ALLi.setCmd(cmd);
ALLi.setColor(color);
ALLi.setNext(null);
FALLi = ALLi;
flag1 = 1;
} else {
FALLi.setNext(tmppaint);
tmppaint.setX1(x1);
tmppaint.setX2(x2);
tmppaint.setY1(y1);
tmppaint.setY2(y2);
tmppaint.setColor(color);
tmppaint.setCmd(cmd);
tmppaint.setNext(null);
FALLi = tmppaint;
}
PALLi = ALLi;
if (flag1 != 0) {
while (PALLi != null) {
PALLi.paint(g);
PALLi = PALLi.getNext();
}
}
}
} @Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("")) {
JButton jbu = (JButton) e.getSource();
color = jbu.getBackground();
} else {
cmd = e.getActionCommand();
}
if (cmd.equals("清空")) {
frame.repaint();
flag = 0;
flag1 = 0;
cmd = "直线";
} } @Override
public void mouseDragged(MouseEvent e) {
if (cmd.equals("直线")) {
g.setColor(Color.WHITE);
g.drawLine(x1, y1, x3, y3);
x3 = e.getX();
y3 = e.getY();
g.setColor(color);
g.drawLine(x1, y1, x3, y3); } else if (cmd.equals("椭圆")) {
g.setColor(Color.WHITE);
g.drawOval(Math.min(x1, x3), Math.min(y1, y3), Math.abs(x1 - x3), Math.abs(y1 - y3));
x3 = e.getX();
y3 = e.getY();
g.setColor(color);
g.drawOval(Math.min(x1, x3), Math.min(y1, y3), Math.abs(x1 - x3), Math.abs(y1 - y3));
} else if (cmd.equals("矩形")) {
g.setColor(Color.WHITE);
g.drawRect(Math.min(x1, x3), Math.min(y1, y3), Math.abs(x1 - x3), Math.abs(y1 - y3));
x3 = e.getX();
y3 = e.getY();
g.setColor(color);
g.drawRect(Math.min(x1, x3), Math.min(y1, y3), Math.abs(x1 - x3), Math.abs(y1 - y3));
} else if (cmd.equals("三角形")) {
g.setColor(Color.WHITE);
g.drawLine(x1, y1, x3, y3);
g.drawLine(x3, y3, x3 - Math.abs(x3 - x1) * 2, y3);
g.drawLine(x3 - Math.abs(x3 - x1) * 2, y3, x1, y1);
g.setColor(color);
x3 = e.getX();
y3 = e.getY();
g.drawLine(x1, y1, x3, y3);
g.drawLine(x3, y3, x3 - Math.abs(x3 - x1) * 2, y3);
g.drawLine(x3 - Math.abs(x3 - x1) * 2, y3, x1, y1);
}
PALLi = ALLi;
if (flag1 != 0) {
while (PALLi != null) {
PALLi.paint(g);
PALLi = PALLi.getNext();
}
} } @Override
public void mouseMoved(MouseEvent e) {
if (cmd.equals("多边形") && flag == 1) {
g.setColor(Color.WHITE);
g.drawLine(curx1, cury1, x3, y3);
g.setColor(color);
x3 = e.getX();
y3 = e.getY();
g.drawLine(curx1, cury1, x3, y3);
while (PLi != null) {
PLi.printline(g);
PLi = PLi.getnext();
}
PLi = Li;
PALLi = ALLi;
if (flag1 != 0) {
while (PALLi != null) {
PALLi.paint(g);
PALLi = PALLi.getNext();
}
}
} } }

主函数

package com.main;

import com.frame.Frame;

public class Game {
public static void main(String[] args) {
new Frame();
}
}

后附一张background

Java学习记录 : 画板的实现的更多相关文章

  1. Java 学习记录

    •Eclipse相关 Eclipse常用设置 解决 Eclipse 项目中有红色感叹号的详细方法(图文) JRE System Library [JavaSE-1.8](unbound) •Java ...

  2. Java学习记录第一章

    学习Java第一章的记录,这一章主要记录的是Java的最基础部分的了解知识,了解Java的特性和开发环境还有Java语言的优缺点. 计算机语言的发展大概过程:机器语言--->汇编语言---> ...

  3. JAVA学习记录(一)————JAVA中的集合类

    这个图是总体的框架图,主要是两个接口Collection和Map都继承接口Iterator(Iterable),为了实现可以使用迭代器.Collection和Map类似平级关系. 1.这里我先学习下A ...

  4. JAVA学习记录<一>

    一: JAVA初体验: 1.JAVA简介: 2.环境搭建: 3:MyEclipse的使用简介: 4:程序的移植:项目的导入,导出. 5:学习JAVA的经验: 多写,多问,总结和复习!!!

  5. Java学习记录-Jdk包简单介绍

    java.applet Java语言编写的一些小应用程序 java.awt AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交 ...

  6. Java学习记录-注解

    注解 一.org.springframework.web.bind.annotation ControllerAdviceCookieValue : 可以把Request header中关于cooki ...

  7. java学习记录

    1,接口(不实现任何方法)——>抽象类(实现部分公共方法)——>简单实现类——>具体实现类 2,抽象类不能被直接实例化,只能实现抽象方法,以匿名内部类的方式表现. 3,如果stati ...

  8. Java学习记录:降低耦合度

    耦合度定义 耦合度(Coupling)是对模块间关联程度的度量.耦合的强弱取决与模块间接口的复杂性.调用模块的方式以及通过界面传送数据的多少. 模块间的耦合度是指模块之间的依赖关系,包括控制关系.调用 ...

  9. Java学习记录:文件的输入输出流

    Java中的输入.输出流中可以用于文件的读写,拷贝. 由于文件都是由字节组成的,可以将文件中的内容以字节的方式读取出来. 输入流还可以直接转换为图片来使用.其实ImageIcon提供了方法可以直接打开 ...

随机推荐

  1. 微信开发中遇到的问题,关于cdnmidimgurl 图片获取

    访问了微信服务器 返回的数据: [{MsgId=3349810483943419227, FromUserName=@@855c3ada0e9c387cfbcff93e9a1a639f024bcfd1 ...

  2. JavaScript闭包,只学这篇就够了

    # 闭包不是魔法 这篇文章使用一些简单的代码例子来解释JavaScript闭包的概念,即使新手也可以轻松参透闭包的含义. 其实只要理解了核心概念,闭包并不是那么的难于理解.但是,网上充斥了太多学术性的 ...

  3. 分辨率验证工具 - 【Firesizer】的使用

    Firesizer是一款测试分辨率的插件. 下载方式:Firefox工具栏——〉工具——〉附加组件--〉搜索Firesizer并安装,浏览器会自动重启 使用方式:浏览器右下角直接切换分辨率即可,如下图 ...

  4. 进程通信-SendMessage使用方法

    进程通信-SendMessage的使用方法 用过SendMessage进行进程通信的同学都知道,这个函数一般都搭配FindWindow使用.通过FindWindow查找进程句柄,然后使用SendMes ...

  5. [INS-30060]:Check for group existence failed

    --[INS-30060]:Check for group existence failed -------------------------------------------------2013 ...

  6. db2 表关联查询

    今天在MapReduce的练习中看到了一个题目: file: CHILD PARENT ---------- ---------- tom lucy tom jack jone lucy jone j ...

  7. XP oracle32位客户端安装找不到orandce11.dll.dbl

    同事在XP上装oracle客户端,遇到下面的问题,mark一下. 提示找不到:orandce11.dll.dbl 点继续还会提示这个文件:orancds11.dll.dbl 网上找到解决方法: 删除注 ...

  8. Qt控件窗体区域区分

    控件窗体区域区分几何参数: 指的是窗口的大小和位置,一个窗口有两套几何参数,一套是窗口外边框所占的矩形区域,另一套是窗口客户区所占的矩形区域,所谓窗口客户区就是窗口中除去边框和标题栏用来显示内容的区域 ...

  9. android炫酷动画源码,QQ菜单、瀑布流、二维码源码

    Android精选源码 自定义弹框封装,ProgressDialog,StatusDialog和Toast,支持自定义颜色 有深度感的fragment代码 在屏幕顶部或者底部显示提示 短信转发工具,自 ...

  10. scope引起的问题

    背景 执行mvn clean test命令提示部分包不存在,但通过eclipse的clean操作后可以执行mvn test命令 解决方法 mvn clean操作为清空编译的class文件,test的话 ...