接触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. css 实现三角形、圆形

    .div { width:0px; height:0px; border:100px solid red; border-color:red red transparent transparent; ...

  2. TASKCTL产品功能清单-转载

    功能分类 功能描述 一级 二级 关系 调度控制 作业依赖关系调度 作业依赖关系调度是调度最基本的功能,指作业间具有顺序的运行,比如:a.b.c三个作业,只有当a完成后才运行b,b完成才能运行c 作业并 ...

  3. LoadRunner入门(一)

    以LR自带的web系统为例(前提条件:已安装好lordrunner 11 ): 一.WebTours系统 是lordrunner自带一个飞机订票系统网站,支持IE浏览器 1. WebTours服务启动 ...

  4. Luogu P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    题目描述 Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has ...

  5. SpringMVC实现垂直搜索引擎

    本篇博客是在上一篇<Lucene搜索引擎+HDFS+MR完成垂直搜索>的基础上,在数据收集之后的JSP/Servlet方面,换为SpringMVC框架来实现. 借助SpringMVC技术完 ...

  6. TCP和UDP的区别(Socket)

    TCP和UDP区别 TCP和UDP编程区别 TCP编程的服务器端一般步骤是:  1.创建一个socket,用函数socket():  2.设置socket属性,用函数setsockopt(); * 可 ...

  7. 谈谈php依赖注入和控制反转

    要想理解php依赖注入和控制反转两个概念,就必须搞清楚如下的问题: DI--Dependency Injection   依赖注入 IoC--Inversion of Control  控制反转 1. ...

  8. JavaWeb(四)JDBC操作Oracle

    JDBC:Java DataBase Connectivity(java数据库连接) SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. jdbc是一套标准, ...

  9. 我学习go的五个感悟(译)

    我学习go的五个感悟(译) 原文 5 things about programming I learned with Go By MICHAŁ KONARSKI Go在最近一段时间内开始变得十分流行. ...

  10. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(一)用ffmpeg解码视频

    一.概述 myRTSPClient(RTSPClient)获取音视频数据之后,接下来的工作便是将音视频数据交给解码器去解码(ffmpeg),ffmpeg解码之后于是便有了呈现在终端用户(USER)面前 ...