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

}
`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章