Java图形化界面编程——处理位图 笔记

2.8.3 处理位图

​ 如果仅仅绘制一些简单的几何图形,程序的图形效果依然比较单调 。 AWT 也允许在组件上绘制位图, Graphics 提供了 drawlmage() 方法用于绘制位图,该方法需要一个Image参数一一代表位图,通过该方法就可 以绘制出指定的位图 。

位图使用步骤:

1.创建Image的子类对象BufferedImage(int width,int height,int ImageType),创建时需要指定位图的宽高及类型属性;此时相当于在内存中生成了一张图片

2.调用BufferedImage对象的getGraphics()方法获取画笔缓冲区的画笔),此时就可以往内存中的这张图片上绘图了,绘图的方法和之前学习的一模一样;

3.调用组件paint方法中提供的Graphics对象(最终画布上的画笔)的drawImage()方法,一次性的内存中的图片BufferedImage绘制到特定的组件上。

使用位图绘制组件的好处:

使用位图来绘制组件,相当于实现了图的缓冲区,此时绘图时没有直接把图形绘制到组件上,而是先绘制到内存中的BufferedImage上,等全部绘制完毕,再一次性的图像显示到组件上即可,这样用户的体验会好一些。

案例:

​ 通过BufferedImage实现一个简单的手绘程序:通过鼠标可以在窗口中画图。Java图形化界面编程——处理位图 笔记_第1张图片

package Draw;

import javax.swing.plaf.ComboBoxUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

public class HandDraw {
    //定义窗口对象
    private Frame frame = new Frame("简单手绘程序");

    //定义画图区的宽高
    private final int AREA_WIDHT = 500;
    private final int AREA_HEIGHT = 400;

    //定义一个右键菜单,用于设置画笔的颜色
    private PopupMenu colorMenu = new PopupMenu();
    private MenuItem redItem = new MenuItem("红色");
    private MenuItem greenItem = new MenuItem("绿色");
    private MenuItem blueItem = new MenuItem("蓝色");

    //定义一个变量来记录当前画笔的颜色
    private Color forceColor = Color.BLACK;

    //创建BufferedImage位图对象,缓冲区
    BufferedImage image = new BufferedImage(AREA_WIDHT,AREA_HEIGHT,BufferedImage.TYPE_INT_RGB);

    //通过位图,获取关联的Graphics对象,画笔
    Graphics g = image.getGraphics();

    //自定义一个类来继承Canvas,画布
    private class MyCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            g.drawImage(image,0,0,null);
        }
    }
    MyCanvas drawArea = new MyCanvas();

    //定义变量,来记录鼠标拖动过程中,上一次所处的坐标
    private int preX = -1;
    private int preY = -1;

    public void init() {
        //组装视图,逻辑控制
        //实现右键菜单更换画笔颜色的逻辑
        //先创建事件监听器
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String actionCommand = e.getActionCommand();  //获取上面的条目
                switch (actionCommand) {
                    case "红色":
                        forceColor = Color.RED;
                        break;
                    case "绿色" :
                        forceColor = Color.GREEN;
                        break;
                    case "蓝色" :
                        forceColor = Color.BLUE;
                        break;
                }
            }
        };
        //将监听器添加到菜单组件中
        redItem.addActionListener(listener);
        greenItem.addActionListener(listener);
        blueItem.addActionListener(listener);

        colorMenu.add(redItem);
        colorMenu.add(greenItem);
        colorMenu.add(blueItem);

        //实现右键出现菜单条的逻辑
        //把colorMenu添加给绘图区域
        drawArea.add(colorMenu);
        //在drawArea中注册鼠标事件监听器
        drawArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {  //当释放鼠标键时被调用
                boolean popupTrigger = e.isPopupTrigger();  //获取点击的是鼠标的哪个键
                if(popupTrigger) {                     //true则说明是右键
                    colorMenu.show(drawArea,e.getX(),e.getY());
                }
                else {
                    //倘若不是右键,则说明监听到拖动结束的标志了
                    //重置preX和preY
                    preX = -1;
                    preY = -1;
                }
            }
        });

        //实现绘图的逻辑
        //先设置位图的背景为白色
        g.setColor(Color.WHITE);
        g.fillRect(0,0,AREA_WIDHT,AREA_HEIGHT);
        //通过监听鼠标的移动,完成线条绘制
        drawArea.addMouseMotionListener(new MouseMotionAdapter() {
            //该方法,当鼠标左键按下,并进行拖动时,会被调用
            @Override
            public void mouseDragged(MouseEvent e) {
                //注意这里是画在缓冲区
                //判断一下是否第一次拖动
                if(preX>0 && preY>0) {
                    //画线条,需要两组坐标,分别是线条的起点和终点, e.getX()和 e.getY()可以获取鼠标坐标
                    //这里是终点的坐标,因此需要先记录起点的坐标
                    g.setColor(forceColor);
                    g.drawLine(preX, preY, e.getX(), e.getY());
                }
                //修正preX和preY的值
                preX = e.getX();
                preY = e.getY();

                //重绘组件,到画布中
                drawArea.repaint();
            }
        });

        drawArea.setPreferredSize(new Dimension(AREA_WIDHT,AREA_HEIGHT));
        frame.add(drawArea);

        //设置窗口最佳大小和可见性
        frame.pack();
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        new HandDraw().init();
    }
}

你可能感兴趣的:(java,笔记,python,职场和发展)