getGraphics和paintComponent的Graphics对象之间的区别

2023-12-01

如果我使用 JPanel,getGraphics 返回的 Graphics 对象与在 PaintComponent 方法中传递的 Graphics 对象有什么区别?


getGraphics

  • Can be null
  • 是最后一次喷漆过程的“快照”
  • 任何涂在上面的东西都会在下一个油漆周期中丢失

你应该避免使用getGraphics并简单地使用过去的内容paintComponent method.

理论上,它们之间没有区别,但如果您希望所绘制的内容在重新绘制之间保留下来,那么您应该使用paintComponent

更新了示例

我猜没有示例代码可供参考......但是......

enter image description here

基本上,这有一个JPanel它充当绘制图像的主要“画布”,并且在设置后,Rectangle作为选择。

它使用第二类作为MouseListener真正决定画什么

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MouseSelection {

    public static void main(String[] args) {
        new MouseSelection();
    }

    public MouseSelection() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                ImagePane imgPane = new ImagePane();
                new MouseHandler(imgPane);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(imgPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MouseHandler    extends MouseAdapter {

        private ImagePane imgPane;

        private Point clickPoint;

        public MouseHandler(ImagePane imgPane) {
            this.imgPane = imgPane;
            imgPane.addMouseMotionListener(this);
            imgPane.addMouseListener(this);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            imgPane.clearSelection();
            clickPoint = e.getPoint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            clickPoint = null;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (clickPoint != null) {
                Point dragPoint = e.getPoint();

                int x = Math.min(clickPoint.x, dragPoint.x);
                int y = Math.min(clickPoint.y, dragPoint.y);
                int width = Math.max(clickPoint.x, dragPoint.x) - x;
                int height = Math.max(clickPoint.y, dragPoint.y) - y;

                imgPane.setSelection(new Rectangle(x, y, width, height));

            }
        }

    }

    public class ImagePane extends JPanel {

        private BufferedImage img;
        private Rectangle selection;

        public ImagePane() {
            try {
                img = ImageIO.read(new File("C:\\hold\\thumbnails\\issue459.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (img != null) {
                int x = (getWidth() - img.getWidth()) / 2;
                int y = (getHeight() - img.getHeight()) / 2;
                g2d.drawImage(img, x, y, this);
            }
            if (selection != null) {

                Color color = UIManager.getColor("Table.selectionBackground");
                g2d.setColor(color);
                Composite comp = g2d.getComposite();
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.fill(selection);
                g2d.setComposite(comp);
                g2d.draw(selection);

            }
            g2d.dispose();
        }

        protected void clearSelection() {
            selection = null;
            repaint();
        }

        protected void setSelection(Rectangle rectangle) {
            selection = rectangle;
            repaint();
        }
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

getGraphics和paintComponent的Graphics对象之间的区别 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Junit:如何测试从属性文件读取属性的方法

    嗨 我有课ReadProperty其中有一个方法ReadPropertyFile返回类型的Myclass从属性文件读取参数值并返回Myclass目的 我需要帮助来测试ReadPropertyFile方法与JUnit 如果可能的话使用模拟文件
  • 如何循环遍历所有组合,例如48 选择 5 [重复]

    这个问题在这里已经有答案了 可能的重复 如何在java中从大小为n的集合中迭代生成k个元素子集 https stackoverflow com questions 4504974 how to iteratively generate k
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • 如何更改javaFX中按钮的图像?

    我正在使用javaFX 我制作了一个按钮并为此设置了图像 代码是 Image playI new Image file c Users Farhad Desktop icons play2 jpg ImageView iv1 new Ima
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • Android:无法使用 DbHelper 和 Contract 类将数据插入 SQLite

    public class Main2Activity extends AppCompatActivity private EditText editText1 editText2 editText3 editText4 private Bu
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 找不到符号 NOTIFICATION_SERVICE?

    package com test app import android app Notification import android app NotificationManager import android app PendingIn
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 使用 CXF-RS 组件时,为什么我们使用 而不是普通的

    作为后续这个问题 https stackoverflow com questions 20598199 对于如何正确使用CXF RS组件我还是有点困惑 我很困惑为什么我们需要

随机推荐