课程设计 JAVA 画板 模拟画图工具Word格式文档下载.docx
《课程设计 JAVA 画板 模拟画图工具Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《课程设计 JAVA 画板 模拟画图工具Word格式文档下载.docx(20页珍藏版)》请在冰点文库上搜索。
2.2.2图形绘制
在工具栏里面实现了基本图形的绘制,图形属性的设置,如画笔粗细和画笔颜色的设置,以及橡皮擦,文字输入等功能,而这些功能的实现都是通过添加内部事件监听器类来实现的。
一个类用来监听绘制基本图形以及橡皮擦按钮;
另一个类用来监听的是选择颜色按钮、选择画笔粗细按钮、和输入文字按钮,里面都用if语句和e.getSource来判断事件源,从而在触发时,调用不同的函数,当事件源为输入文字时,用JOptionPane.showMessageDialog来弹出一个提示操作的对话框。
画图区域的功能主要是通过添加鼠标监听器来实现的:
一个鼠标监听器监听的是:
单击鼠标,释放鼠标,鼠标进入绘图区域,鼠标离开绘图区域这四个鼠标的动作事件;
另一个监听的是:
鼠标拖拽和鼠标移动。
而且,两个监听器之间是存在着密不可分的关系的,它们同时监听画图区域。
铅笔作画和橡皮擦的使用是画图板设计的核心也是难点,而且两者的实现原理是一样的,我们通常画图的时候,一定是先单击鼠标然后拖拽鼠标最后释放鼠标的,所以,在画图的过程中,只要鼠标单击一下就获得(x1,y1),紧接着用if语句判断画的基本图形是哪一个,如果是铅笔或者橡皮擦,则获得(x2,y2),说明在铅笔或橡皮擦的时候,鼠标单击一下,就获得一个点,x1=x2,y1=y2,且这个点的坐标就是鼠标单击的位置,而且这个点是算作第一个基本图形的,此时index=1;
拖拽的过程中动态获得鼠标所在位置的横纵坐标且始终x1=x2,y1=y2,并且等于第一个基本图形也就是index=1的那个点的x2,y2,即,在铅笔作画的过程中,在鼠标不断拖拽的过程中,index=1时的那个点在以点的点的长度不断增加,这就是铅笔作画过程的实现;
鼠标释放的时候,在铅笔或橡皮的状态下,也是得到一个点。
所以,可以总结,铅笔和橡皮都是通过设置画直线方法中的点的坐标相等来实现的。
其它图形的绘制,可以直接调用Graphics2D中的方法实现,相对比较简单。
3详细设计与实现
3.1框架类DrawGraphic
3.1.1菜单
菜单栏有两个按钮“画图板”、“帮助”,通过添加内部匿名类来实现,一旦下拉菜单中的“新建”、“打开”、“保存”、“退出”四个键被触发,就调用相关的函数,具体代码如下:
(1)“新建”执行时,调用的函数代码如下:
publicvoidnewFile(){
index=0;
currentChoice=3;
color=Color.BLUE;
stroke=1.0f;
createNewItem();
repaint();
}
(2)“打开”执行时,调用的函数代码如下:
publicvoidopenFile(){
JFileChooserfileChooser=newJFileChooser();
//为用户选择文件提供了一种简单的机制
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
intresult=fileChooser.showOpenDialog(this);
//弹出一个"
OpenFile"
文件选择器对话框,父组件
if(result==JFileChooser.CANCEL_OPTION)return;
FilefileName=fileChooser.getSelectedFile();
fileName.canRead();
//测试应用程序是否可以读取此抽象路径名表示的文件
if(fileName==null||fileName.getName().equals("
"
)){
JOptionPane.showMessageDialog(fileChooser,"
这个名字不可以用的"
"
"
JOptionPane.ERROR_MESSAGE);
}
else{
try{
FileInputStreamfis=newFileInputStream(fileName);
input=newObjectInputStream(fis);
intcountNumber=0;
countNumber=input.readInt();
for(index=0;
index<
countNumber;
index++){
DrawingsinputRecord=(Drawings)input.readObject();
itemList[index]=inputRecord;
}
createNewItem();
input.close();
repaint();
}catch(EOFExceptionendofFileException){//当输入过程中意外到达文件或流的末尾时,抛出此异常
JOptionPane.showMessageDialog(this,"
nomorerecordinfile"
"
endoffile"
JOptionPane.ERROR_MESSAGE);
}catch(ClassNotFoundExceptionclassNotFoundException){
unabletocreateobject"
classnotfound"
}catch(IOExceptionioException){
errorduringreadfromfile"
readerror"
}
(3)“保存”执行时,调用的代码如下:
publicvoidsaveFile(){
//允许用户只选择文件
intresult=fileChooser.showSaveDialog(this);
SaveFile"
文件选择器对话框
fileName.canWrite();
fileName.delete();
FileOutputStreamfos=newFileOutputStream(fileName);
output=newObjectOutputStream(fos);
output.writeInt(index);
//写入一个32位的int值
for(inti=0;
i<
index;
i++){
DrawingsoutputRecord=itemList[i];
output.writeObject(outputRecord);
//将指定的对象写入ObjectOutputStream
output.flush();
//此操作将写入所有已缓冲的输出字节,并将它们刷新到底层流中
output.close();
fos.close();
}catch(IOExceptionioe){
ioe.printStackTrace();
}
3.1.2工具栏
工具栏按钮功能的实现,是通过添加两个内部事件监听类ButtonHandler1、ButtonHandler2来达到目的的。
(1)ButtonHandler1监听绘制基本图形的按钮,if语句判断事件源,具体代码如下:
publicclassButtonHandler1implementsActionListener{
publicvoidactionPerformed(ActionEvente){
for(intj=3;
j<
choices.length-3;
j++){
if(e.getSource()==choices[j]){
currentChoice=j;
createNewItem();
repaint();
(2)ButtonHandler2监听颜色选色器、画笔粗细、添加文字按钮,if语句判断事件源,相应的按钮被触发,就执行相应的函数,具体代码如下:
publicclassButtonHandler2implementsActionListener{
if(e.getSource()==choices[choices.length-3]){
chooseColor();
if(e.getSource()==choices[choices.length-2]){
setStroke();
icon=newImageIcon(getClass().getResource("
/images/smile.png"
));
if(e.getSource()==choices[choices.length-1]){
JOptionPane.showMessageDialog(null,"
想在哪里添加文字呢?
鼠标先点一下那里吧!
"
JOptionPane.INFORMATION_MESSAGE,icon);
currentChoice=14;
3.1.3画图区域
(1)createNewItem()用来new各种基本图形,在函数的一开始,我设置了一下光标的样子,然后用switch函数接收currentChoice来判断用户要new的是哪一个基本图形,关键代码如下:
voidcreateNewItem(){
if(currentChoice==14){
drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
switch(currentChoice){
case3:
itemList[index]=newPencil();
break;
case4:
itemList[index]=newLine();
case5:
itemList[index]=newRect();
case6:
itemList[index]=newfillRect();
case7:
itemList[index]=newOval();
case8:
itemList[index]=newfillOval();
case9:
itemList[index]=newCircle();
case10:
itemList[index]=newfillCircle();
case11:
itemList[index]=newRoundRect();
case12:
itemList[index]=newfillRoundRect();
case13:
itemList[index]=newRubber();
case14:
itemList[index]=newWord();
itemList[index].type=currentChoice;
itemList[index].R=R;
itemList[index].G=G;
itemList[index].B=B;
itemList[index].stroke=stroke;
(2)chooseColor()用来选择各种颜色,具体代码如下:
publicvoidchooseColor(){
color=JColorChooser.showDialog(null,"
在这里选择自己喜欢的颜色"
color);
R=color.getRed();
G=color.getGreen();
B=color.getBlue();
(3)setStroke()用来设置画笔粗细,具体代码如下:
publicvoidsetStroke(){
Stringinput;
input=JOptionPane.showInputDialog(null,"
在这里重新输入画笔的粗细值(一个>0的实数)"
1.0"
);
stroke=Float.parseFloat(input);
//将字符串参数转换为一个float值
(4)mouseA监听鼠标单击、释放、进入、离开四个事件,当鼠标单击的时候,用e.getSource()先得到一个点的坐标初始化(x1,y1),再判断单击的是哪一个按钮,如果是绘制其它图形的按钮,那就光得到一个点(x1,y1);
如果是铅笔或者橡皮擦,则继续初始化第二个点的坐标(x2,y2),此时x1=x2,y1=y2,即鼠标单击绘出一个点,而这个点是用绘直线方式画出的,表示已绘制的图形个数的index++;
如果是添加文字按钮,则弹出一个可以输入文字的对话框。
当鼠标释放的时候,如果是铅笔或橡皮,同样得到一个点,如果是绘制其它图形的基本按钮,那就光得到(x2,y2),关键代码如下:
classmouseAextendsMouseAdapter{
publicvoidmousePressed(MouseEvente){
statusBar.setText("
MousePressed@:
["
+e.getX()+"
+e.getY()+"
]"
itemList[index].x1=e.getX();
itemList[index].y1=e.getY();
if(currentChoice==3||currentChoice==13){
itemList[index].x2=e.getX();
itemList[index].y2=e.getY();
index++;
if(currentChoice==14){
itemList[index].x1=e.getX();
itemList[index].y1=e.getY();
Stringinput;
input=JOptionPane.showInputDialog("
可以添加你想写的文字咯!
//可以输入内容的对话框
itemList[index].s1=input;
itemList[index].x2=f1;
itemList[index].y2=f2;
//f1,f2用来存放当前字体风格
itemList[index].s2=stylel;
drawingArea.repaint();
publicvoidmouseReleased(MouseEvente){
MouseReleased@:
itemList[index].x2=e.getX();
itemList[index].y2=e.getY();
index++;
createNewItem();
repaint();
(5)mouseB监听鼠标拖拽和移动,在鼠标拖拽的时候,由于鼠标的拖拽一定是在单击之后的,所以mouseA和mouseB的监听功能必须连在一起来分析,上面得知,如果事件源是铅笔或橡皮,鼠标单击就得到了第一个点,紧接着鼠标开始拖拽,拖拽的过程中,也一直在动态的得到点,只是第一个点的x2,y2一直在以点的长度动态增加,index++;
如果事件源是绘制其它图形的按钮,则鼠标在动态拖拽的过程中只需要,得到点(x2,y2)就好:
classmouseBextendsMouseMotionAdapter{
publicvoidmouseDragged(MouseEvente){
MouseDragged@:
itemList[index-1].x2=itemList[index].x2=itemList[index].x1=e.getX();
itemList[index-1].y2=itemList[index].y2=itemList[index].y1=e.getY();
else{
itemList[index].x2=e.getX();
itemList[index].y2=e.getY();
publicvoidmouseMoved(MouseEvente){
MouseMoved@:
3.2基本图形类
3.2.1父类Drawings
classDrawingsimplementsSerializable{
intx1,y1,x2,y2;
intR,G,B;
floatstroke;
inttype;
Strings1,s2;
voiddraw(Graphics2Dg2d){};
3.2.2子类(只列出部分)
(1)铅笔:
classPencilextendsDrawings{
voiddraw(Graphics2Dg2d){
g2d