• Java-GUI编程之处理位图


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

    位图使用步骤:

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

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

    3.调用组件的drawImage()方法,一次性的内存中的图片BufferedImage绘制到特定的组件上。

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

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

    案例:

    ​ 通过BufferedImage实现一个简单的手绘程序:通过鼠标可以在窗口中画图。

    演示代码:

    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/
    公众号:愚生浅末


    __EOF__

    本文作者愚生浅末
    本文链接https://www.cnblogs.com/kohler21/p/16138695.html
    关于博主:评论和私信会在第一时间回复。或者直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    如何防止僵尸 API...
    android逆向工程反编译指南(详细教程)
    23种设计模式
    原来 flexbox 是这么工作的
    计算机网络
    Java IO流:Buffered处理流、对象处理流
    nuxt作为主应用接入qiankun的实践(附代码)
    kafka如何保证消息顺序性?
    js截取,拼接,字符串方法
    聊聊最近很火的混合专家模型(MoE)
  • 原文地址:https://www.cnblogs.com/kohler21/p/16138695.html