使用Java Swing绘制随鼠标拖拽可见轨迹的矩形(不会一直绘制矩形,而是类似ps中的矩形工具)

来源:互联网 发布:芈月怎么玩 知乎 编辑:程序博客网 时间:2024/05/13 09:22

使用Java Swing绘制随鼠标拖拽可见轨迹的矩形(不会一直绘制矩形,而是类似ps中的矩形工具)

小画板画矩形
作为学生党,为了完成java程序设计的实验(自制小画板工具),在网上找了很久相关的资料,但是结果都不太理想,。而且由于是第一次接触java,虽然以前学c和c++,还自己看过一段c#,但对于Gui编程是一头雾水(Api函数多到爆炸,头皮发麻)。这一上手直接图形界面,还是十分头疼的。
好了,说重点吧,其实这个小程序最难搞的(我认为)就是绘制矩形或椭圆的时候让其显示动态轨迹。如ps中的矩形工具那样的效果。
为了做到这个,我可是想了不少办法(毕竟是小白),
首先,直接在mouseDragged 中获取x,y值,传到绘制矩形的函数中,但是这样做的后果是绘制时矩形是随着mouseDragged的触发频率连续绘制的,效果惨不忍睹,不说了,看图
这里写图片描述
红线画出的地方就是因为事件一直连续发生,所以绘制出的矩形的坐标点也是连续的,这样一画就是一大片。
这种方法尝试失败后,我又想了另一种方法,借鉴于Ps的图层这种模式,我想将Bufferedimage当作一个图层,每次在上面绘制当前的图像,然后将图像绘制到当作底板的jpanel上,岂不美滋滋。
我以为graphics的Drawimage方法能将Bufferedimage的有效部分叠加绘制到对象Observer上,可是现实并不乐观,事实证明这是不可行的。Drawimage每次会将Bufferedimage覆盖到Observer上从而使得从前次绘制的不可见。
最后就是综合了前两种,既然每次会覆盖,那就手动将他们的颜色叠加,在mouseReleased方法中获取当前bufferedimage像素信息,与底层bufferedimage的像素信息,将表层中为0的值用底层的替代,最后将这个数组输出到新的底层bufferedimage中,这样再绘制一遍底层就能添加所需图形了。
`import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class FSPaint extends JPanel {
//常量
private int PenStyle = 1;
private int a = 0, b = 0;
private int oa = 0, ob = 0;
private int LastX = 0, LastY = 0;
private boolean Drag = false;
private boolean Save = false;
private Graphics2D Pen;
//控件
private Font Tip_font;
private JLabel Position_X;
private JLabel Position_Y;
//缓冲区
private BufferedImage Temp;
private BufferedImage STemp;

public FSPaint ( ) throws IOException, FontFormatException {    setSize (786, 385);    setBackground (Color.BLACK);    //设置字体    Tip_font = Font.createFont (Font.TRUETYPE_FONT, new FileInputStream (new File ("D:\\P\\java\\T0\\src\\swfit .TTF")));    Tip_font = Tip_font.deriveFont (8.0f);    super.setVisible (true);    Temp = new BufferedImage (786, 385, BufferedImage.TYPE_4BYTE_ABGR_PRE);    setCursor (Toolkit.getDefaultToolkit ().createCustomCursor (            Toolkit.getDefaultToolkit ().getImage (this.getClass ().getResource ("arr_pen.png")), new Point (0, 0), "stick"));    //Position    Position_X = new JLabel ();    Position_X.setFont (Tip_font);    Position_X.setForeground (new Color (170, 170, 170));    Position_X.setText ("x:" + "   ");    Position_Y = new JLabel ();    Position_Y.setFont (Tip_font);    Position_Y.setForeground (new Color (170, 170, 170));    Position_X.setText ("y:" + "   ");    this.addMouseListener (new java.awt.event.MouseAdapter () {        public void mouseReleased ( MouseEvent e ) {            Drag = false;            //Temp = AddToBg (STemp, Temp);            switch ( PenStyle ) {                case 0:                    break;                case 1:            }        }        public void mouseEntered ( MouseEvent e ) {            switch ( PenStyle ) {                case 0:                    break;                case 1:            }        }        public void mouseExited ( MouseEvent e ) {            repaint ();        }        public void mousePressed ( MouseEvent e ) {            oa = a = e.getX ();            ob = b = e.getY ();        }    });    this.addMouseMotionListener (new MouseAdapter () {        @Override        public void mouseDragged ( MouseEvent e ) {            super.mouseDragged (e);            Drag = true;            switch ( PenStyle ) {                case 0:                    DrawAny (Pen, e.getX (), e.getY ());                    break;                case 1:                    DrawRect (Pen, e.getX (), e.getY ());                    break;            }        }        @Override        public void mouseMoved ( MouseEvent e ) {            SetPosition (e.getX (), e.getY ());        }    });}public void setPenStyle ( int mode ) {    this.PenStyle = mode;}@Overrideprotected void paintComponent ( Graphics g ) {    super.paintComponent (g);    Graphics2D G = ( Graphics2D ) g;    DrawbacBground (G);    G.drawImage (Temp, 0, 0, 786, 385, this);//  if ( Drag ) G.drawImage (STemp, 0, 0, 786, 385, this);}//绘制背景private void DrawbacBground ( Graphics2D G ) {    G.setColor (new Color (42, 22, 22));    G.fillRect (1, 1, 784, 384);    G.setColor (new Color (26, 13, 13));    G.fillRect (0, 0, 1, 384);    G.setColor (new Color (49, 26, 26));    G.fillRect (1, 0, 785, 1);    G.setColor (new Color (59, 31, 31));    G.fillRect (815, 0, 1, 385);    G.setColor (new Color (32, 17, 17));    G.fillRect (0, 384, 785, 1);}//画笔工具private void DrawAny ( Graphics2D g, int x, int y ) {    g = ( Graphics2D ) Temp.getGraphics ();    g.setColor (new Color (255, 255, 255));    g.setStroke (new BasicStroke (1.0f));    g.drawLine (a, b, x, y);    a = x;    b = y;    repaint ();    g.dispose ();}//绘制矩形private void DrawRect ( Graphics2D g, int x, int y ) {//  STemp = new BufferedImage (786, 385, BufferedImage.TYPE_4BYTE_ABGR_PRE);

// g = ( Graphics2D ) STemp.getGraphics ();
g = ( Graphics2D ) Temp.getGraphics ();
a = x - oa > 0 ? x - oa : oa - x;
b = y - ob > 0 ? y - ob : ob - y;
LastX = oa > x ? x : oa;
LastY = ob > y ? y : ob;
g.setColor (new Color (255, 255, 255));
g.fillRect (LastX, LastY, a, b);
repaint ();
g.dispose ();
}

//显示坐标private void SetPosition ( int x, int y ) {    Position_X.setText ("x:" + "   " + "" + x);    Position_Y.setText ("y:" + "   " + "" + y);}//图层叠加private BufferedImage AddToBg ( BufferedImage up, BufferedImage down ) {    BufferedImage Combain = new BufferedImage (down.getWidth (), down.getHeight (), BufferedImage.TYPE_4BYTE_ABGR_PRE);    int[] upRgb;    int[] downRgb;    upRgb = up.getRGB (0, 0, up.getWidth (), up.getHeight (), null, 0, up.getWidth ());    downRgb = down.getRGB (0, 0, down.getWidth (), down.getHeight (), null, 0, down.getWidth ());    for ( int i = 0; i < down.getWidth () * down.getHeight (); i++ )        if ( upRgb[ i ] != 0 ) downRgb[ i ] = upRgb[ i ];    //此处可插入图像处理    Combain.setRGB (0, 0, down.getWidth (), down.getHeight (), downRgb, 0, down.getWidth ());    return Combain;}//外部显示public void Show_Position ( JFrame F ) {    Position_X.setVisible (true);    Position_X.setBounds (913, 576, 72, 15);    Position_Y.setVisible (true);    Position_Y.setBounds (985, 576, 72, 15);    F.add (Position_X);    F.add (Position_Y);}

}
`

原创粉丝点击