仿XP画图板—升级版


画图板界面如下:


      截取后的图片 截图.png               

                           

实现的功能有:

1、左边工具栏中功能:截图并保存,橡皮擦,取色笔,铅笔,刷子,喷枪,文本框,直线,矩形,椭圆,圆角矩形等功能

2、颜色选择功能(2处):底部颜色选择(第一个大的方形显示画笔当前的颜色)、菜单栏中“颜色”选择器

3、鼠标形状的切换:如:选择喷枪工具后,进入绘图区,鼠标变为喷枪形状

4、菜单栏中:“新建” 画图的功能,”打开“ 图片,”保存“ 修改后的图片的功能


由于内容太多,以 下叙述可能不是很详细  尴尬

资源已打包(附详细注释)可以直接下载或者联系我,还可以互相交流一下下,嘿嘿 微笑

      下载链接:http://download.csdn.net/detail/u010622887/6009271


总体分为九个类:

MainFrame.java: 主界面        MyMenuBar.java: 菜单栏      ColorPane.javal: 底部颜色面板       ToolPanel.java: 工具面板      PaintPanel.java: 画图面板

MyMouseListener.java: 鼠标监听类        MyList.java: 保存数组类       ImageCut.java: 截图功能类         Test.java:  测试类


 Test.java:  测试类   

      public static void main(String[] args){
            MainFrame frame=new MainFrame();
           frame.showFrame();
      }

一、MainFrame:   

功能:创建菜单栏、底部颜色面板、工具面板、画图面板对象,并添加到主界面上;为画图面板添加监听

        1、  布局方式:不用设置,为默认布局方式:BorderLayou

                this.add(toolPanel,BorderLayout.WEST);
               this.add(colorPanel,BorderLayout.SOUTH);
               this.add(paintPanel,BorderLayout.CENTER);

2、为画图区创建鼠标监听时,可以只用MouseAdapter  ; 但添加监听必须为两个:MouseListener  ;   MouseMotionListener

// 创建建鼠标监听,将三个面板传递给鼠标监听
MyMouseAdapter mouse_listener=new MyMouseAdapter(toolPanel,colorPanel,paintPanel);
/*为画图区
添加鼠标监听(按下、释放、单击、进入或离开)*/
paintPanel.addMouseListener(mouse_listener);
//另外还得添加鼠标移动的监听器(光标移动、拖拽
)否则无法画出铅笔等
paintPanel.addMouseMotionListener(mouse_listener);


二、MyMenuBar:

                               

功能:实现菜单子项目等的添加,并为之添加监听

1、创建菜单条后,将菜单选项添加至菜单条,再将子选项添加至菜单目录下  (JMenuBar;JMenu;JMenuItem)                                                    

     //例:添加菜单子选项“新建”

     menu_file=new JMenu("文件");

     this.add(menu_file);

     item_new=new JMenuItem("新建");

     menu_file.add(item_new);

     其子项目他同上

2、内部类形式创建ActionListener();获取选项命令menu_command:判断后,做出相应的反映:

     JFileChooser默认的路径为桌面的TEST      

     (1.)新建功能:  重新加载一个新窗体 

              MainFrame frame=new MainFrame();
             frame.showFrame();

     (2.)打开对话框,选择要打开的图片

     想在面板中显示图像:Graphics2D中有drawImage();【 g.drawImage(image, 5, 5, image.getWidth(), image.getHeight(), null);】

     必须得到面板的画布:g 、所需显示的图形对象 image、显示图像的位置

      (3.)保存修改后的图片(详见后文,截图功能后)     

       (4.)全部清除的功能:

             

     (5.)打开颜色选择器

              保存用户所选择的颜色:color=JColorChooser.showDialog(fileChooser, "选择颜色", Color.black);

              选择颜色后改变ColorPanel:中大按钮的背景色为当前选择的颜色,故需要得到颜色面板中的大按钮

              创建完监听器后,给子选项添加监听器


三、ColorPanel:

功能:改变画布的颜色,并显示在颜色面板的第一个大矩形区域内

           1、流式布局,向左靠齐:setLayout(new FlowLayout(FlowLayout.LEFT));

           2、用一数组装颜色,以遍历数组的方式,给每个按钮添加背景颜色,创建监听,添加监听

           3、监听具体内容:当鼠标点击时,获得所选按钮的背景颜色,将第一个JPanel中的大按钮的背景色改成当前所选的颜色


四:ToolPanel:

功能:添加工具到工具面板上,并为之添加监听

           流式布局:String[] 装图形的名称,for循环顺序为每个按钮添加图形

           创建ActionListener监听,按下按钮后,获取tool_command;

            提供getCommand(),传递给鼠标监听类


五:MyMouseListener:

功能:处理鼠标发生相应变化时发生的事件

在MainFrame 中创建此类;获得来自MainFrame 中的toolPanel, colorPanel,paintPanel

1、改变光标:

进入画图区时:mouseEntered();

          cursor=Toolkit.getDefaultToolkit().

          createCustomCursor(new ImageIcon("images/"+name+".jpg").getImage(),new Point(10,10), name);

          cursor=new Cursor(Cursor.CROSSHAIR_CURSOR);

          paint_panel.setCursor(cursor);

2、画简单几何图形:

按下时:获得点的坐标:(X1,Y1);

释放时:获得点的坐标(X2,Y2);

          g.drawLine(X1Y1X2Y2);

          g.drawRect(Math.min(X1,X2),Math.min(Y1, Y2) , Math.abs(X1-X2), Math.abs(Y1-Y2));

          g.drawOval(Math.min(X1,X2),Math.min(Y1, Y2) , Math.abs(X1-X2), Math.abs(Y1-Y2));                               g.drawRoundRect(Math.min(X1,X2),Math.min(Y1Y2) , Math.abs(X1-X2), Math.abs(Y1-Y2), (Math.abs(X1-X2))/3, (Math.abs(Y1-Y2))/3);

多边形:

设置画的第一条边的起始点为第一坐标点,用第一条边的结束点作为第二条边的起始点,

直到有一条边的结束点为第一条边的起始点,结束画图,count清零

所画直线分为两种,第一条边为g.drawLine(X1,Y1,X2,Y2);此后的直线,可以用

         g.drawLine(next_x,next_y,X2,Y2);

        next_x=X2;

        next_y=Y2;

3、简单类似工具:铅笔,橡皮擦,刷子(类似的画法)

在拖动mouseDragged()中:(X2,Y2)是动态变化的点

类似于画多边形

g.drawLine(X1Y1X2Y2);

X1=X2;

Y1=Y2;

橡皮擦,刷子=多个铅笔并排一起画

for(int x=X2;x<X2+8;x++){

for(int y=Y2;y<Y2+8;y++){

g.drawLine(x, y,X2Y2);

}

}

4、喷枪:

mousePressed()中,

//画10个点,在距离鼠标10个单位内

for(int i=0;i<10;i++){

int x,y;

x=X1+new Random().nextInt(10);

y=Y1+new Random().nextInt(10);

     }

mouseDragged()中,取随机数

x=X2+new Random().nextInt(10);

y=Y2+new Random().nextInt(10);

g.fillRect(x,y, 1, 1);

5、取色笔  (详见MyMouseAdapter.java)

color = new Robot.getPixelColor(mousepoint.xmousepoint.y);

6、文本框:

思路:显示一个文本框,输入字符串。单击文本框以外的地方,将字符串显示在面板上,文本框移除

mouseReleased()中,

(1、)创建文本框前提:

             if("word".equals(tool_command)&&(textArea_show==false)&&(Math.abs(X1-X2)>20&& Math.abs(Y1-Y2)>20)

(2、)释放鼠标,得到坐标,设置矩形文本框的大小

(3、)给文本框创建监听器,添加监听,保存文本框的字符串

             text=textArea.getText();

(4、)面板被单击时,将文本框的字符串画到画图面板上

               g.drawString(text, text_x, text_y);

          注意:此处画字符串的起始点在文本框左上角点的下方一些

(5、)移除文本框,重绘画板区(必须)

              paint_panel.remove(textArea);

              paint_panel.repaint();

文本框功能重点:给文本框添加监听的类型:

       JTextField:创建的是单行文本框;JTextArea:多行文本框

(1、JTextField,能添加ActionListener();TextListener();

           ActionListener():必须按下回车键才触发事件,获取文本字符串,繁琐

          TextListener():文本框发生改变时,触发事件,从而方便的获取文本内容

       //  内部类形式

         TextListener text_listener=new TextListener(){

                  public void textValueChanged(TextEvent e) {

                           text=textArea.getText();

                 }

         };

        textArea.addTextListener(text_listener);

(2、JTextArea,不能添加上面两种监听;能添加KeyListener;

           /**

             * 单击画板后,文本框才会失去焦点,即要画板被点击后才能获取文本

            * 内容,矛盾。造成text 为空,报错

            */

         FocusListener text_focusListener=new FocusListener(){

                  public void focusGained(FocusEvent e) {  }

                  public void focusLost(FocusEvent e) {

                              text=textArea.getText();

                   }

         };

   textArea.addFocusListener(text_focusListener);

           //在文本框区域外单击,文本框消失,字符显示

            if(textField.getComponentAt(e.getPoint())==null){

                      paint_panel.setTextList(textList.saveValue(text, text_x, text_y,

                           textArea.getLineCount(),textArea.getColumns(),color));//保存行,列数值到数组里面

            }

6、截图:

思路:鼠标释放后,抓图得到截图的矩形区域(类似画矩形),传给ImageCut.java ,由ImageCut.对象将其保存为图片

              //得到鼠标释放点的坐标,创建一个相对屏幕的矩形
     Rectangle rectangle=new Rectangle(mousepoint.x, mousepoint.y, Math.abs(X1-X2), Math.abs(Y1-Y2));
     new ImageCut(rectangle).cutImage();//创建截图对象,调用截图方法


六、PaintPanel

功能:接收从MyMouseAdapter传入的所需自定义数组队列显示画图面板,实现重绘画图面板区的功能

          //提供设置数组的方法,从MyMouseAdapter传入所需数组队列

            public void  setTextList(Object[] my_list){
this.textList=my_list;
     }

         /**
           * 重绘画板区

          */
public void paint(Graphics g){
super.paint(g); 

                //重绘图片
if(!(bufferedImage==null)){
System.out.println("重绘图片。。。。");
g.drawImage(bufferedImage, 5, 5, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
};

               //非拖曳区重绘,第一个数组,每次取出六个数,赋值后画出(画矩形为例)
for(int i=0;i<myList_1.length;i=i+6){
X1=(Integer)myList_1[i];
Y1=(Integer)myList_1[i+1];
X2=(Integer)myList_1[i+2];
Y2=(Integer)myList_1[i+3];
tool_command=(String)myList_1[i+4];
color=(Color)myList_1[i+5];
g.setColor(color); 

                       if("rect".equals(tool_command)){
g.drawRect(Math.min(X1,X2),Math.min(Y1, Y2) , Math.abs(X1-X2), Math.abs(Y1-Y2));
}

                }

               //拖曳区,每次取出六个数,赋值后画出(铅笔为例)
for(int i=0;i<myList_2.length;i=i+6){
X1=(Integer)myList_2[i];
Y1=(Integer)myList_2[i+1];
X2=(Integer)myList_2[i+2];
Y2=(Integer)myList_2[i+3];
tool_command=(String)myList_2[i+4];
color=(Color)myList_2[i+5];
g.setColor(color);

if("pencil".equals(tool_command)){
g.drawLine(X1, Y1, X2, Y2);
X1=X2;
Y1=Y2;
}

                }

        }


七、Mylist

 功能:实现单个或多个数据添加到自定义队列中(例:每次添加六个值);

           保存画图面板中的图形数据(坐标等),等待重绘时使用

      //定义两个数组:目标数组长度是原始数组+6;将原始数组数据顺序复制到目标数组,再将六个需要保存的数据添加到目标数组尾部

        private Object[] my_list = new Object[0];

        private Object[] destArray = new Object[my_list.length+6];

/**
* 用数组保存基本图形坐标值,六个值为Object类
*/
public Object[] saveValue(int x1,int y1,int x2,int y2,String tool_command,Color color){

//清空目标数组,设置长度为源数组+6
destArray = new Object[my_list.length+6];
for(int i=0;i<my_list.length;i++){
destArray[i] = my_list[i];
};
destArray[my_list.length] = x1;
destArray[my_list.length+1] = y1;
destArray[my_list.length+2] = x2;
destArray[my_list.length+3] = y2;
destArray[my_list.length+4]=tool_command;
destArray[my_list.length+5]=color;

my_list = destArray;
return my_list;
}


八、ImageCut:

功能:实现画图板指定区域的截图,并将图片命名后保存至选择的文件中

单独创建一个截图类:ImageCut.java   需要获得所要截取图形的区域rectangle

1、获取截图对象:image = new Robot().createScreenCapture(Rectangle r);

2、显示保存对话框【用户选择完保存的路径,输入命名文件的字符串】

fileChooser.showSaveDialog(fileChooser)

3、若用户选择确定保存按钮:获得当前路径,使用拼接路径(当前路径+用户输入的文件名)创建一个新文件

String   fileName=fileChooser.getSelectedFile().getName();

String savePath=fileChooser.getCurrentDirectory()+"\\"+fileName+".png";//拼接存储路径

File destFile=new File(savePath);

4、将图片写入新的空文件中

ImageIO.write(image"png", destFile);

详见

7、保存修改后的图片的功能

跟截图功能一样,只是截图的大小为原始的大小

Point point_screen=paint_panel.getLocationOnScreen();

Rectangle rectangle=new Rectangle(point_screen.x+5, point_screen.y+5, image.getWidth(), image.getHeight());


源代码下载链接:http://download.csdn.net/detail/u010622887/6009271



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值