依旧是画板,已经写到第七个版本了,与上篇所说的相比,除了界面加上了一个可变画图面板,代码上进行了一些优化以外,还加上了画板的重绘,这样,就不用担心窗体最小化之后所画图形未保存了。下面上代码。
package Draw20111020;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 自制简单画图板,第七次修正
* @author 鲁大帅
*/
public class Draw05 extends JFrame {
//参数
private ImpList<NetJavaShape> shapes = new ImpList<NetJavaShape>();//定义一个队列用来存放数组对象
private boolean isChange = false;//用于后面的判断
private Graphics2D g;//画布定义成2D的,主要是因为加上了粗细这个参数
/** 主函数 */
public static void main(String[] args) {
Draw05 htb = new Draw05();
htb.showUI();
}
/** 实现界面的方法*/
public void showUI() {
this.setTitle("鲁大帅的画板");// 设置标题
this.setSize(600, 430);// 设置窗体大小
this.setDefaultCloseOperation(3);// 关闭的时候自动退出程序
this.setLocationRelativeTo(null);// 窗体显示位置居中
// 设置边框布局对象
BorderLayout bl = new BorderLayout();
this.setLayout(bl);
/** 添加四个面板 */
ToolBar tb = new ToolBar();// 工具栏
MyMenuBar mb = new MyMenuBar();// 菜单栏
ColorBox cp = new ColorBox();// 颜色栏
final JPanel center = new JPanel();// 右边面板
// //设置布局为流式,左对齐,上下,左右间距为5px,背景颜色为灰
center.setLayout(new FlowLayout(0, 5, 5));
center.setBackground(Color.GRAY);
final JPanel dp = new JPanel(){
public void paint(Graphics g){
super.paint(g);//调用父类的方法来绘制窗体
drawshape((Graphics2D)g);//调用绘制形状的方法
}
};// 设置画图的面板
dp.setBackground(Color.WHITE);// 颜色为白色
dp.setPreferredSize(new Dimension(400, 260));
center.add(dp);
/** 添加面板到窗体 */
this.add(tb, BorderLayout.WEST);
this.add(mb, BorderLayout.NORTH);
this.add(cp, BorderLayout.SOUTH);
this.add(center, BorderLayout.CENTER);
this.setVisible(true);// 窗体可见
MyListener ml = new MyListener(dp, tb, cp,shapes);// 实现鼠标监听
dp.addMouseListener(ml);
dp.addMouseMotionListener(ml);
// 拖动改变画布大小的实现
// 在匿名内部类中使用外面的局部变量,一定要定义成final
MouseAdapter ms = new MouseAdapter() {
int cursors;
//移动到右下角时改变光标的形状
public void mouseMoved(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if (x > dp.getPreferredSize().getWidth()
&& x < dp.getPreferredSize().getWidth() + 10
&& y > dp.getPreferredSize().getHeight()
&& y < dp.getPreferredSize().getHeight() + 10)
// 改变光标的形状
{ center.setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
cursors = 1;
isChange = true;
//右边和下面中点的情况
} else if (x > dp.getPreferredSize().getWidth()/2
&& x < dp.getPreferredSize().getWidth()/2 + 10
&& y > dp.getPreferredSize().getHeight()
&& y < dp.getPreferredSize().getHeight() + 10){
center.setCursor(new Cursor(Cursor.S_RESIZE_CURSOR));
cursors = 2;
isChange = true;
}else if(x > dp.getPreferredSize().getWidth()
&& x < dp.getPreferredSize().getWidth() + 10
&& y > dp.getPreferredSize().getHeight()/2
&& y < dp.getPreferredSize().getHeight()/2 + 10){
center.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
cursors = 3;
isChange = true;
}else {
// 设置为默认光标
center.setCursor(Cursor.getDefaultCursor());
isChange = false;
}
}
public void mouseReleased(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int x1 = (int) dp.getPreferredSize().getWidth();
int y1 = (int) dp.getPreferredSize().getHeight();
if (isChange) {
if(cursors == 1){
// 设置画布面板的大小
dp.setPreferredSize(new Dimension(x - 5, y - 5));
}else if(cursors == 2){
dp.setPreferredSize(new Dimension(x1,y -5));
}else if(cursors == 3){
dp.setPreferredSize(new Dimension(x-5,y1));
}
// 刷新
javax.swing.SwingUtilities.updateComponentTreeUI(dp);
center.setCursor(Cursor.getDefaultCursor());
isChange = false;
}
}
};
center.addMouseListener(ms);
center.addMouseMotionListener(ms);
dp.addMouseMotionListener(ms);
}
private void drawshape(Graphics2D g) {
//遍历队列
for(int i=0;i<shapes.size();i++){
NetJavaShape ss = shapes.get(i);
ss.draw(g);
}
}
}
以上是主函数,有些地方还是看起来很累赘,但目前能做的只有这样了。画板实现了主界面添加菜单栏,工具栏,颜色栏,可改变画布大小以及画布重绘等功能。工具栏和颜色栏虽有有些稍微的区别,但大体构架还是一样的,下面只说颜色栏。代码如下:
package Draw20111020;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JToolBar;
/**
* 颜色栏外加颜色监听
* @author Administrator
*
*/
public class ColorBox extends javax.swing.JToolBar{
//设置参数
private int col;//用于后面左右键的判断
private Color color;
//点击左右键所得的颜色
private Color lcolor=Color.BLACK;
private Color rcolor=Color.WHITE;
public ColorBox(){
colorchoose();
}
/**获得左右键颜色的值的方法*/
public Color getlColor(){
return lcolor;
}
public Color getrColor(){
return rcolor;
}
/**选择颜色的方法*/
public void colorchoose(){
/**
* color面板设置大小、颜色、流式布局
*/
this.setName("颜色");
this.setPreferredSize(new Dimension(600,90));//设置大小
FlowLayout g0 = new FlowLayout(FlowLayout.LEFT);
this.setLayout(g0);
/**
* 创建一个工具条,2个面板,jp1放置颜色监听,jp2放置颜色面板
*/
JPanel jtb = new JPanel();
JPanel jp1 = new JPanel();
JPanel jp2 = new JPanel();
jp1.setPreferredSize(new Dimension(41,41));//设置大小
jp1.setLayout(null);
jp1.setBackground(Color.WHITE);
jp2.setPreferredSize(new Dimension(282,41));//设置大小
/**对于jp1,设置front、back两面板,自由布局*/
final JButton front = new JButton();
final JButton back = new JButton();//新建两按钮
front.setPreferredSize(new Dimension(15,15));//面板大小
back.setPreferredSize(new Dimension(15,15));
front.setBounds(10,10,15,15);
back.setBounds(16,16,15,15);//设置location
front.setBackground(Color.BLACK);
back.setBackground(Color.WHITE);//设置初始背景色
back.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
showColorSelecter();
}
});//匿名内部类给back添加动作监听,点击调出颜色选择器
jp1.add(front);
jp1.add(back);//添加两面板
/**添加鼠标监听器*/
MouseAdapter al=new MouseAdapter(){
// 点击时返回对象数值
public void mouseClicked(MouseEvent e) {
//获得点击的值以判断左右键
col = e.getButton();
//获得对象
Object obj = e.getSource();
//强制转型
JButton but = (JButton)obj;
//获得color的值
color = but.getBackground();
//判断,如果点击左键,则设置front颜色;如果是右键,则设置back颜色
if(col==1){
front.setBackground(color);
lcolor=color;
}
else if(col==3){
back.setBackground(color);
rcolor=color;
}
}
};
/**对于jp2,用于装颜色面板*/
//定义一个Color数组
Color colorbox[]={Color.BLACK,new Color(128,128,128),new Color(128,0,0),new Color(128,128,0),new Color(0,128,0),new Color(0,128,128),new Color(0,0,128),
new Color(128,0,128),new Color(128,128,64),new Color(0,64,64),new Color(0,128,255),new Color(0,64,128),new Color(128,0,255),new Color(128,64,0),
Color.WHITE,new Color(192,192,192),new Color(255,0,0),new Color(255,255,0),new Color(0,255,0),new Color(0,255,255),new Color(0,0,255),
new Color(255,0,255),new Color(255,255,128),new Color(0,255,128),new Color(128,255,255),new Color(128,128,255),new Color(255,0,128),new Color(255,128,64)};
//通过for循环添加数组中按钮
for(int i=0;i<28;i++){
JButton btn = new JButton();
btn.setBackground(colorbox[i]);
btn.setPreferredSize(new Dimension(15,15));
btn.addMouseListener(al);
jp2.add(btn);
}
//将面板加到工具条上
jtb.add(jp1);
jtb.add(jp2);
// 将工具条加到大面板上
this.add(jtb);
}
/**调出颜色选择器的方法*/
private void showColorSelecter(){
this.color = javax.swing.JColorChooser.showDialog(null, "请选择颜色", java.awt.Color.BLACK);
}
}
完成了各个面板,接下来就是将他们连接起来的监听器了,来看看这个:
public class MyListener extends MouseAdapter{
/**
* 定义参数
*/
private int x1,y1,x2,y2;
private Color color;
private Graphics2D g;
private String command="pencil";
private ToolBar tb;
private ColorBox cp;
private int col;
private JPanel dp;
//定义一个队列用来保存绘制的形状
private ImpList<NetJavaShape> shapes ;
public MyListener(JPanel dp,ToolBar tb,ColorBox cp,ImpList<NetJavaShape> shapes){
this.dp = dp;
this.tb = tb;
this.cp = cp;
this.shapes = shapes;
}
//鼠标按下事件,取得起始坐标
public void mousePressed(MouseEvent e) {
g = (Graphics2D)dp.getGraphics();
//col作为判断左右键颜色的依据,获得color值
col=e.getButton();
if(col==1){
color = cp.getlColor();
}else if(col==3){
color=cp.getrColor();
}
x1 = e.getX();
y1 = e.getY();
}
//鼠标拖拽事件,画曲线
public void mouseDragged(MouseEvent e){
x2=e.getX();
y2=e.getY();
command = tb.getCommand(); //从tb中获得command的值
NetJavaShape s1= null;
/**曲线的画法*/
if(command.equals("pencil")){
s1= new Impline(x1,y1,x2,y2,1,color);
s1.draw(g);
x1=x2;
y1=y2;
}else if(command.equals("eraser")){
/**橡皮*/
s1= new Imperaser(x1,y1,x2,y2,10,Color.WHITE);
s1.draw(g);
x1=x2;
y1=y2;
}
shapes.add(s1);
}
//鼠标按下得到终点坐标
public void mouseReleased(MouseEvent e) {
x2 = e.getX();
y2 = e.getY();
NetJavaShape s2=new Impline(x1,y1,x2,y2,1,color);
if(command.equals("line")){
s2 = new Impline(x1, y1, x2, y2,1,color); //直线
}else if(command.equals("rect")){
s2 = new Imprect(x1, y1, x2, y2,1,color); //矩形
}else if(command.equals("oval")){
s2 = new Impoval(x1, y1, x2, y2,1,color); //椭圆
}else if(command.equals("rounded_rect")){
s2= new ImpRoundRect(x1, y1, x2, y2,1,color); //圆角矩形
}else if(command.equals("polygon")){
s2 = new Impjt(x1, y1, x2, y2,1,color); //三角形
}
s2.draw(g);
dp.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
shapes.add(s2);
}
}
监听器从主函数得到了画布对象和队列,又从颜色面板得到了画笔的颜色,这样一来,就可以通过监听和判断绘制图形了。本人不才,仅仅只实现了画曲线、直线、矩形、椭圆、圆角矩形、一个坑爹的三角形和橡皮。对与这些图形的画法,首先定义了一个抽象类NetJavaShape,所有的形状画法皆继承于此,绘制的方法大同小异。下面以矩形为例。下面有三种画法:第一种为最复杂,也最易理解,即分四种情况讨论x1、x2,y1、y2的大小。
if(x1<x2&&y1<y2){g.drawRect(x1, y1, x2-x1, y2-y1); }
else if(x1<x2&&y1>y2){g.drawRect(x1, y2, x2-x1, y1-y2);}
else if(x1>x2&&y1<y2){g.drawRect(x2, y1, x1-x2, y2-y1);}
else if(x1>x2&&y1>y2){g.drawRect(x2, y2, x1-x2, y1-y2);}
第二种是我自己的囧方法,即把边界通过画直线四点连接起来,这里就不说了。第三种是来自龙哥的很巧妙方法,看似简单,对我这种初学者来说确实很难想到。
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
一个小小的矩形就有这样不同的的写法,这说明要实现目标,方法是很多的。套用一句话:“没有做不到,只有想不到。”的确如此。只要多思考,然后付诸实践,很多问题都能解决的。好的想法应该是成功的第一步吧。当然,要成功中间还有很长的路要走,但只要坚持下去,别放弃,一定能行的。即使失败了,也绝不后悔。
至于队列的实现,这里就不写了。最后,再贴张图吧。
![](http://dl.iteye.com/upload/attachment/574267/a8c8dcd4-64d8-3f4e-873b-967a9c0b89ff.jpg)
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0057/4267/a8c8dcd4-64d8-3f4e-873b-967a9c0b89ff-thumb.jpg)
- 大小: 64.9 KB
分享到:
相关推荐
总结来说,玲珑画板6.045版是一款轻量级但功能强大的数学作图工具,它的出现为数学教育领域提供了新的可能性。无论是教学还是自学者,都可以从中受益,通过直观的图形化方式加深对数学的理解,提升学习效率。所以,...
总结而言,“几何画板文件打包机(GSP转EXE)”是一项具有革命性的发明。它不仅解决了教学资源分享的难题,而且显著提升了教学和学习的效率。这款工具让几何画板的使用更加灵活,方便教师和学生在没有安装几何画板...
总结起来,"几何画板课件350套 (2).zip" 是一个全面的几何学教育资源,包含了大量的教学实例和练习,适用于教师的教学辅助和学生的学习巩固。无论是在课堂教学还是自主学习中,这个压缩包都能提供丰富的素材,帮助...
总结来说,“易源码-画板”项目代表了软件开发领域中一种以用户为中心的开发理念,其目标是提供易于理解和使用的源代码,从而加速用户学习和开发的过程。尽管它可能使用了一种特殊格式的文件,但项目的透明度和可...
总结起来,《几何画板》作为一款专业的数学教学工具,以其独特的特点和广泛的应用实例,有力地支持了小学数学的教学工作,提升了教学效果,同时也为学生的数学学习提供了更为丰富和立体的体验。教师们应该充分利用这...
总结而言,几何画板5.0打包机是一个不可或缺的工具,它弥补了几何画板5.0在文件分享上的不足,使得优秀的作品能跨越时间和空间的限制,继续在教育和研究领域发挥其价值。对于那些还在寻找这款打包机的用户,应当珍视...
总结来说,几何画板5凭借其全面的功能和直观的操作界面,为中学数学特别是几何学的教学带来了全新的视角。它不仅提高了教学质量,还能有效激发学生的学习兴趣。通过这款软件,那些原本抽象难懂的几何概念得以转化为...
总结而言,《几何画板专家级课件gsp模版140例》为数学教学和学习提供了一套全面且实用的资源。无论是教师还是学生,都能从中获益匪浅。它借助几何画板的直观演示功能,将抽象的数学概念转化为易于感知的视觉体验,为...
总结来说,“我的小画板”这款应用程序,虽然定位为轻量级的数字画图工具,却为用户提供了相当全面的绘画功能。无论是儿童教育、业余爱好者的娱乐活动,还是专业人士的创意表达,它都能提供良好的支持。它的设计充分...
总结而言,《最全的几何画板实例教程》是一份覆盖了从基础到进阶知识的综合教程。它不仅为用户提供了对工具箱和状态栏的认识,还详细阐述了基本操作、解决问题的实例、高级技巧、实验方法和练习题等。通过这份教程的...
总结而言,几何画板实例教程:模拟时钟不仅仅是关于时钟制作的教程,更是一个全方位培养学生空间感知、逻辑推理、创新思维和问题解决能力的平台。通过这一系列知识的学习和实践,学生不仅能够深入理解几何概念,也...
总结来说,“易语言画板画显示器花屏损坏假象源码”是一个易语言编程的学习资源,它利用易语言的画板组件和编程技巧,模拟出一种视觉效果,展示了易语言在图形编程方面的潜力。对于学习者而言,研究这个源码可以帮助...
总结来说,ArtMath几何画板v1.0是一个创新的数学辅助教学工具。它直观且灵活地展现几何和解析几何的概念,不仅提高了教学的效率,也极大地促进了学生实践能力和创新意识的培养。无论是教师在备课时制作教学材料,...
总结来说,金排物理画板v2019是一款集物理符号绘制、图形编辑、课件制作于一体的优秀软件,它极大地提升了物理工作者的工作效率,丰富了物理教学手段。对于那些需要精准表达物理概念的人来说,它无疑是一个不可或缺...
总结而言,这种室内装饰用发热彩画板是一款集艺术装饰、温度调节于一体的多功能产品。通过其独特的构造和精心挑选的材料,不仅在功能上满足了用户对绘画和取暖的基本需求,还在美学设计上为室内增添了一份优雅。这一...
《易语言画板动态图画详解》 易语言是一款由中国程序员王江民开发的,专为初学者设计的编程语言,其特色在于采用直观的...对于初学者而言,这是一个难得的实践机会,能够将理论知识转化为实际操作,提升编程技能。
总结而言,易语言内存画板模块是利用GDI技术在内存中进行高效、无闪烁绘图的工具,对于提升图形界面的用户体验具有显著作用。它简化了开发者处理复杂绘图任务的过程,为易语言的图形应用开发开辟了新的可能。通过...
总结而言,"带有磁笔及印章的四象限彩色磁力画板"在建筑行业中,不仅是一件具有创新性设计的高效工具,更是沟通和合作的重要媒介。它把传统绘图艺术和现代科技完美结合,为建筑设计带来了新的工作模式。这不仅帮助...
总结来说,这款带有笔筒和可擦拭画板的台灯设计,不仅提供了一个实用的照明工具,更提供了一个高效、便捷的工作平台。它所代表的这种设计思路和方法,对于推动设计行业的发展具有重要的示范和引导作用。对于设计行业...
总结来说,Sketchpad5作为一款几何画板,不仅提供了一个直观的几何图形创建平台,还涵盖了函数、测量、计算等多个数学领域,实现了动态几何教学的创新。它通过互动和可视化的方式,帮助教师更有效地传授知识,让学生...