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

使用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;
}

@Override
protected 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);
}

}
`

猜你喜欢

转载自blog.csdn.net/q886yes/article/details/78108106
今日推荐