Java-GUI程式設計之處理點陣圖

愚生淺末發表於2022-04-13

如果僅僅繪製一些簡單的幾何圖形,程式的圖形效果依然比較單調 。 AWT 也允許在元件上繪製點陣圖, Graphics 提供了 drawlmage() 方法用於繪製點陣圖,該方法需要一個Image引數一一代表點陣圖,通過該方法就可 以繪製出指定的點陣圖 。

點陣圖使用步驟:

1.建立Image的子類物件BufferedImage(int width,int height,int ImageType),建立時需要指定點陣圖的寬高及型別屬性;此時相當於在記憶體中生成了一張圖片;

2.呼叫BufferedImage物件的getGraphics()方法獲取畫筆,此時就可以往記憶體中的這張圖片上繪圖了,繪圖的方法和之前學習的一模一樣;

3.呼叫元件的drawImage()方法,一次性的記憶體中的圖片BufferedImage繪製到特定的元件上。

使用點陣圖繪製元件的好處:

使用點陣圖來繪製元件,相當於實現了圖的緩衝區,此時繪圖時沒有直接把圖形繪製到元件上,而是先繪製到記憶體中的BufferedImage上,等全部繪製完畢,再一次性的影像顯示到元件上即可,這樣使用者的體驗會好一些。

案例:

​ 通過BufferedImage實現一個簡單的手繪程式:通過滑鼠可以在視窗中畫圖。

Java-GUI程式設計之處理點陣圖

演示程式碼:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

public class HandDraw {
    //定義畫圖區的寬高
    private final int AREA_WIDTH = 500;
    private final int AREA_HEIGHT = 400;
    //定義變數,儲存上一次滑鼠拖動時,滑鼠的座標
    private int preX = -1;
    private int preY = -1;
    //定義一個右鍵選單,用於設定畫筆的顏色
    private PopupMenu colorMenu = new PopupMenu();
    private MenuItem redItem = new MenuItem("紅色");
    private MenuItem greenItem = new MenuItem("綠色");
    private MenuItem blueItem = new MenuItem("藍色");
    //定義一個BufferedImage物件
    private BufferedImage image = new BufferedImage(AREA_WIDTH,AREA_HEIGHT,BufferedImage.TYPE_INT_RGB);
    //獲取BufferedImage物件關聯的畫筆
    private Graphics g = image.getGraphics();
    //定義視窗物件
    private Frame frame = new Frame("簡單手繪程式");
    //定義畫布物件
    private Canvas drawArea =  new Canvas(){
        public void paint(Graphics g) {
            //把點陣圖image繪製到0,0座標點
            g.drawImage(image,0,0,null);
        }
    };
    //定義一個Color物件,用來儲存使用者設定的畫筆顏色,預設為黑色
    private Color forceColor = Color.BLACK;
    public void init(){
        //定義顏色選單項單擊監聽器
        ActionListener menuListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
                switch (command){
                    case "紅色":
                        forceColor=Color.RED;
                        break;
                    case "綠色":
                        forceColor = Color.GREEN;
                        break;
                    case "藍色":
                        forceColor = Color.BLUE;
                        break;
                }
            }
        };

        //為三個選單項新增點選事件
        redItem.addActionListener(menuListener);
        greenItem.addActionListener(menuListener);
        blueItem.addActionListener(menuListener);
        //把選單項新增到右鍵選單中
        colorMenu.add(redItem);
        colorMenu.add(greenItem);
        colorMenu.add(blueItem);
        //把右鍵選單新增到繪圖區域drawArea
        drawArea.add(colorMenu);
        //將iamge圖片背景設定為白色
        g.fillRect(0,0,AREA_WIDTH,AREA_HEIGHT);
        //設定繪圖區域drawArea的大小
        drawArea.setPreferredSize(new Dimension(AREA_WIDTH,AREA_HEIGHT));
        //繪圖區域drawArea設定滑鼠移動監聽器
        drawArea.addMouseMotionListener(new MouseMotionAdapter() {
            //用於繪製影像
            public void mouseDragged(MouseEvent e) {//按下滑鼠鍵並拖動會觸發
                //如果上次滑鼠的座標在繪圖區域,才開始繪圖
                if (preX>0 && preY>0){
                    //設定當前選中的畫筆顏色
                    g.setColor(forceColor);
                    //繪製線條,需要有兩組座標,一組是上一次滑鼠拖動滑鼠時的座標,一組是現在滑鼠的座標
                    g.drawLine(preX,preY,e.getX(),e.getY());
                }

                //更新preX和preY
                preX = e.getX();
                preY = e.getY();

                //重新繪製drawArea元件
                drawArea.repaint();
            }
        });
        drawArea.addMouseListener(new MouseAdapter() {

            //用於彈出右鍵選單
            public void mouseReleased(MouseEvent e) {//鬆開滑鼠鍵會觸發
                boolean popupTrigger = e.isPopupTrigger();
                if (popupTrigger){
                    //把colorMenu顯示到drawArea畫圖區域,並跟隨滑鼠顯示
                    colorMenu.show(drawArea,e.getX(),e.getY());
                }
                //當滑鼠鬆開時,把preX和preY重置為-1
                preX = -1;
                preY = -1;

            }
        });
        //把drawArea新增到frame中
        frame.add(drawArea);

        //設定frame最佳大小並可見
        frame.pack();
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        new HandDraw().init();
    }
}

公眾號文章地址:https://mp.weixin.qq.com/s/TrbmvkBjNkurrAId7VMLnQ

個人部落格:https://kohler19.gitee.io/
公眾號:愚生淺末

相關文章