Java学习记录 : 画板的实现
接触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学习记录 : 画板的实现的更多相关文章
- Java 学习记录
•Eclipse相关 Eclipse常用设置 解决 Eclipse 项目中有红色感叹号的详细方法(图文) JRE System Library [JavaSE-1.8](unbound) •Java ...
- Java学习记录第一章
学习Java第一章的记录,这一章主要记录的是Java的最基础部分的了解知识,了解Java的特性和开发环境还有Java语言的优缺点. 计算机语言的发展大概过程:机器语言--->汇编语言---> ...
- JAVA学习记录(一)————JAVA中的集合类
这个图是总体的框架图,主要是两个接口Collection和Map都继承接口Iterator(Iterable),为了实现可以使用迭代器.Collection和Map类似平级关系. 1.这里我先学习下A ...
- JAVA学习记录<一>
一: JAVA初体验: 1.JAVA简介: 2.环境搭建: 3:MyEclipse的使用简介: 4:程序的移植:项目的导入,导出. 5:学习JAVA的经验: 多写,多问,总结和复习!!!
- Java学习记录-Jdk包简单介绍
java.applet Java语言编写的一些小应用程序 java.awt AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交 ...
- Java学习记录-注解
注解 一.org.springframework.web.bind.annotation ControllerAdviceCookieValue : 可以把Request header中关于cooki ...
- java学习记录
1,接口(不实现任何方法)——>抽象类(实现部分公共方法)——>简单实现类——>具体实现类 2,抽象类不能被直接实例化,只能实现抽象方法,以匿名内部类的方式表现. 3,如果stati ...
- Java学习记录:降低耦合度
耦合度定义 耦合度(Coupling)是对模块间关联程度的度量.耦合的强弱取决与模块间接口的复杂性.调用模块的方式以及通过界面传送数据的多少. 模块间的耦合度是指模块之间的依赖关系,包括控制关系.调用 ...
- Java学习记录:文件的输入输出流
Java中的输入.输出流中可以用于文件的读写,拷贝. 由于文件都是由字节组成的,可以将文件中的内容以字节的方式读取出来. 输入流还可以直接转换为图片来使用.其实ImageIcon提供了方法可以直接打开 ...
随机推荐
- 怎么把系统装进u盘(ultraiso)
首先要下载一个叫ultraiso的软件.可以在百度中搜索此软件下载.下载后安装,安装后打开软件,如图所示. 点击左上角的文件选项,在弹出的菜单中,点击打开选项,打开一个你要装进U盘的 ...
- Spring+SpringMVC+MyBatis+easyUI整合
进阶篇 Spring+SpringMVC+MyBatis+easyUI整合进阶篇(一)设计一套好的RESTful API 优化篇 Spring+SpringMVC+MyBatis+easyUI整合优化 ...
- Log4net快速配置使用指南。(快速搭建log4net日志平台手册)
每做一个新项目,都会用到log4net,但总是忘记如何快速配置.有时在网上搜半天也找不到好的模板,大都在介绍参数的使用,在此做下总结,争取下次用时仅10分钟就可搭建好log4net. 直接上介绍的步骤 ...
- JSR-303 Bean Validation 介绍及 Spring MVC 服务端参数验证最佳实践
任何时候,当要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情. 应用程序必须通过某种手段来确保输入参数在上下文来说是正确的. 分层的应用很多时候同样的数据验证逻辑会出现在不同的层,这样 ...
- JavaScript闭包,只学这篇就够了
# 闭包不是魔法 这篇文章使用一些简单的代码例子来解释JavaScript闭包的概念,即使新手也可以轻松参透闭包的含义. 其实只要理解了核心概念,闭包并不是那么的难于理解.但是,网上充斥了太多学术性的 ...
- 【复制】【编码】MySQL复制中的编码问题
编码背景知识 Latin-1,全称ISO 8859-1 Latin 1 对ASCII的拉丁语扩展 向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x8 ...
- ARP协议详解RARP
简单来说,ARP协议是IP地址转换成MAC地址的协议.链路层协议.过程如下: 1:首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系. 2:当源主机要 ...
- dll的两种加载方式(pend)+ delayload
看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib ...
- Gate One
运维堡垒机介绍: 运维堡垒机的理念起源于跳板机.2000年左右,高端行业用户为了对运维人员的远程登录进行集中管理,会在机房里部署跳板机.跳板机就是一台服务器,维护人员在维护过程中,首先要统一登录到这台 ...
- 使用百度云同步盘和Git Extensions进行代码托管
一.软件安装 百度云同步盘和Git Extensions的安装和配置略过. 二.建立Git代码库,以[GHO2VMDK转换工具]项目为例 1. 建立本地代码库 进入[GHO2VMDK转换工具]项目文件 ...