更改 JPanel Graphics g 颜色绘制线

2023-12-12

我有一个类似于绘画的程序。而且我正在尝试实现更改笔颜色,但是当我更改颜色时,当前绘制的所有内容都会更改为红色,例如在我的程序中,我怎样才能使其不会将当前绘制的所有内容重新绘制为当前颜色改变颜色?下面的代码将编译并运行

JPanel 绘图区域的类

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
//refer to http://jkost.ergoway.gr/jnkjavaconnection/freedraw.html for the algorithm.
public class STDrawingArea extends JPanel {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    ArrayList<Rectangle> dPoint = new ArrayList<Rectangle>();
    Point point = new Point(-1,-1);
    private Color currentColor;

    public STDrawingArea()
    {
         setBorder(BorderFactory.createLineBorder(Color.black));
         setBackground(Color.WHITE);

         addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) 
            {
                dPoint.add(new Rectangle(point.x,point.y,e.getX(),e.getY()));
                point.x = e.getX();
                point.y = e.getY();
                repaint();
            }

             });

         addMouseListener(new MouseAdapter(){
             public void mousePressed(MouseEvent e)
             {
                 System.out.println("mousePressed X: "+e.getX()+"mousePressed Y: "+e.getY());
                 dPoint.add(new Rectangle(e.getX(),e.getY(),-1,-1));
                 point.x = e.getX();
                 point.y = e.getY();
             }
         });

         addMouseListener(new MouseAdapter(){
             public void mouseReleased(MouseEvent e)
             {
                 System.out.println("mouseReleased X: "+e.getX()+"mouseReleased Y: "+e.getY());
                 repaint();
             }
         });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(700,500);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
       g.setColor(getCurrentColor());
        for (int i=0; i < dPoint.size(); i++) {  
            Rectangle r = dPoint.get(i);
            if (r.width != -1)
            {
              g.drawLine(r.x, r.y, r.width, r.height);  
            }
           }  
            /* Draw current point.*/ 
            g.drawLine(point.x, point.y, point.x, point.y);  
    }

    //set current drawing color
    public void changePenColor(Color color)
    {
        if (color == null)
        setCurrentColor(Color.BLACK);
        else
        setCurrentColor(color);
    }

    //clear drawings method
    public void clearDrawings()
    {
        if(!(dPoint==null))
        {
             dPoint.clear();
             repaint();
        }

    }

    private void setCurrentColor(Color currentColor) {
        this.currentColor = currentColor;
    }

    private Color getCurrentColor() {
        return currentColor;
    }
}

测试主类。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class STTestMain extends JFrame {
    STDrawingArea drawingArea = new STDrawingArea();
    public STTestMain()
    {
        //JFrame settings
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Spelling Trainer");
        setResizable(false);
        setVisible(true);


        //Panel of buttons
        JPanel buttonContainer = new JPanel();
        JButton btnPenColor = new JButton("Red Pen");

        buttonContainer.add(btnPenColor);
        //Drawing Area instantiation


        //Adding things to JFrame
        getContentPane().add(drawingArea);
        getContentPane().add(buttonContainer,BorderLayout.PAGE_END);
        pack();


        //button listener
        btnPenColor.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                drawingArea.changePenColor(Color.RED);
            }
        });
    }


    public static void main(String args[])
    {
        STTestMain test = new STTestMain();
    }

}

单程:

  • 使用 ArrayList 在绘制当前曲线时绘制它,但是
  • 使用 BufferedImage 绘制完成的曲线
  • 您可以在 mouseReleased 上执行此操作,并使用当前颜色将当前曲线绘制到 BufferedImage。
  • 在绘制到 BufferedImage 后,您还需要重新初始化点的 ArrayList。
  • 使用完 BufferedImage 的 Graphics 对象后,不要忘记将其丢弃。
  • 在 super.paintComponent 之后但在绘制当前曲线之前,在 PaintComponent 方法中绘制 BufferedImage。
  • 这样,当您更改绘图的颜色时,只有当前曲线受到影响。

EDIT
您在评论中提到您不熟悉 BufferedImage,并且正在寻找另一种方法。我想您可以创建一个类,其中包含点的 ArrayList 和颜色,然后在每个 mouseReleased 上创建该类的一个对象,并将其添加到绘图面板中的 ArrayList 中。然后你的paintComponent方法可以迭代该ArrayList,绘制具有相关颜色的点列表,但我的直觉告诉我,你是一个聪明的人,你很快就会学会如何使用BufferedImage。我真的认为这是最好的解决方案。如果您尝试但失败了,请向我们展示您的代码,我们很可能会为您提供帮助。

EDIT 2
BufferedImage 构造函数需要图像宽度、高度和图像类型——我对此并不 100% 熟悉。我通常使用 BufferedImage.TYPE_INT_RGB 进行通用绘图,并使用 BufferedImage.TYPE_INT_ARGB 进行通用,也需要 alpha。然后,如果您需要的是 Graphics 对象而不是 Graphics2D 对象,则将从 BufferedImage 中提取 Graphics 对象,例如 getGraphics()。然后,当您在构造函数中初始化 BufferedImage 时,用 Color.white 填充它,就像您在 JPanel 中一样。然后处理 Graphics 对象。然后每次要绘制的时候,就获取Graphics,用它进行绘制,就像在paintComponent方法中所做的那样,完成后将Graphics处理掉,最后通过drawImage方法在paintComponent中绘制BufferedImage。

EDIT 3
示例程序并没有完全完成您想要做的事情,但确实说明了 BufferedImage 与绘图的使用。每次绘制新路径或曲线时,该程序都会更改颜色。

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.*;

public class STTestSimple {
   private static void createAndShowUI() {
      STDrawPanel drawPanel = new STDrawPanel();
      STMouseAdapter mAdapter = new STMouseAdapter(drawPanel);
      drawPanel.addMouseListener(mAdapter);
      drawPanel.addMouseMotionListener(mAdapter);

      JFrame frame = new JFrame("Drawing");
      frame.getContentPane().add(drawPanel);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setResizable(false);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

@SuppressWarnings("serial")
class STDrawPanel extends JPanel {
   private static final int ST_WIDTH = 700;
   private static final int ST_HEIGHT = 500;
   private static final Color BACKGROUND_COLOR = Color.white;
   private static final float STROKE_WIDTH = 6f;
   private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH,
            BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
   private static final Color[] colors = {Color.black, Color.blue, Color.red,
      Color.green, Color.orange, Color.MAGENTA};

   private BufferedImage bImage = new BufferedImage(ST_WIDTH, ST_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
   private Color color = Color.black;
   private ArrayList<Point> points = new ArrayList<Point>();
   private int colorIndex = 0;

   public STDrawPanel() {
      Graphics g = bImage.getGraphics();
      g.setColor(BACKGROUND_COLOR);
      g.fillRect(0, 0, ST_WIDTH, ST_HEIGHT);
      g.dispose();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawImage(bImage, 0, 0, null);
      Graphics2D g2 = (Graphics2D) g;
      drawCurve(g2);
   }

   private void addCurveToBufferedImage() {
      Graphics2D g2 = bImage.createGraphics();
      drawCurve(g2);
      g2.dispose();
   }

   private void drawCurve(Graphics2D g2) {
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setStroke(STROKE);
      g2.setColor(color);
      if (points != null && points.size() > 1) {
         for (int i = 0; i < points.size() - 1; i++) {
            int x1 = points.get(i).x;
            int y1 = points.get(i).y;
            int x2 = points.get(i + 1).x;
            int y2 = points.get(i + 1).y;
            g2.drawLine(x1, y1, x2, y2);
         }
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(ST_WIDTH, ST_HEIGHT);
   }

   public void curveStart(Point point) {
      points.clear();
      points.add(point);
   }

   public void curveEnd(Point point) {
      points.add(point);
      addCurveToBufferedImage();
      points.clear();
      repaint();

      colorIndex++;
      colorIndex %= colors.length;
      setColor(colors[colorIndex]);
   }

   public void curveAdd(Point point) {
      points.add(point);
      repaint();
   }

   public void setColor(Color color) {
      this.color = color;
   }
}

class STMouseAdapter extends MouseAdapter {
   private STDrawPanel drawPanel;

   public STMouseAdapter(STDrawPanel drawPanel) {
      this.drawPanel = drawPanel;
   }

   @Override
   public void mousePressed(MouseEvent e) {
      drawPanel.curveStart(e.getPoint());
   }

   @Override
   public void mouseReleased(MouseEvent e) {
      drawPanel.curveEnd(e.getPoint());
   }

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

更改 JPanel Graphics g 颜色绘制线 的相关文章

  • “java.io.IOException:连接超时”和“SocketTimeoutException:读取超时”之间有什么区别

    如果我设置一个套接字 SoTimeout 并从中读取 当读取时间超过超时限制时 我会收到 SocketTimeoutException 读取超时 这是我的例子中的堆栈 java net SocketTimeoutException Read
  • Guice 忽略注入构造函数参数上的 @Nullable

    我正在使用 Guice v 3 0 并且有一个值被注入到构造函数中 该值可以为 null 因此我在构造函数中使用 Nullable 来自 javax annotations 注释了该参数 public MyClass Parameter1
  • 获取文件的锁

    我想在对特定文件开始 threo read 时获取文件上的锁定 以便其他应用程序无法读取已锁定的文件并希望在线程终止时释放锁定文件 您可以获得一个FileLock https docs oracle com javase 8 docs ap
  • Android 中的列表(特别是 RecyclerView 和 CardView)如何工作

    请原谅我问这个问题 但我是 Android 开发新手 尽管我正在尝试了解developer android com 网站上的基础知识 但大多数示例 即使他们说它们是为 Android Studio 构建的 尚未设置为使用 Gradle 因此
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • 如何将jscrollpane添加到jframe?

    我有以下源代码 有人可以给我建议如何将 jscrollpane 添加到 jframe 上吗 我尝试了几次将其添加到 jframe 但没有任何进展 它甚至没有显示 public class Form3 JFrame jframe new JF
  • 删除优先级队列的尾部元素

    如何删除优先级队列的尾部元素 我正在尝试使用优先级队列实现波束搜索 一旦优先级队列已满 我想删除最后一个元素 优先级最低的元素 Thanks 没有简单的方法 将元素从原始元素复制到新元素 最后一个除外 PriorityQueue remov
  • 为什么Iterator接口没有add方法

    In IteratorSun 添加了remove 方法来删 除集合中最后访问的元素 为什么没有add方法来向集合中添加新元素 它可能对集合或迭代器产生什么样的副作用 好的 我们开始吧 设计常见问题解答中明确给出了答案 为什么不提供 Iter
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 在 MongoDB 和 Apache Solr 之间同步数据的简单方法

    我最近开始使用 MongoDB 和 Apache Solr 我使用 MongoDB 作为数据存储 并且希望 Apache Solr 为我的数据创建索引 以实现应用程序中的搜索功能 经过一些研究 我发现 基本上有两种方法可以在 MongoDB
  • 如何通过注解用try-catch包装方法?

    如果应该在方法调用中忽略异常 则可以编写以下内容 public void addEntryIfPresent String key Dto dto try Map
  • Eclipse - 安装新的 JRE (Java SE 8 1.8.0)

    我正在尝试安装 Java 8 到目前为止我所做的 安装最新版本的 Eclipse 下载并安装 Java SE 运行时环境 8http www oracle com technetwork java javase downloads jre8
  • Spring Data JPA:查询如何返回非实体对象或对象列表?

    我在我的项目中使用 Spring Data JPA 我正在演奏数百万张唱片 我有一个要求 我必须获取各种表的数据并构建一个对象 然后将其绘制在 UI 上 现在如何实现我的 Spring 数据存储库 我读到它可以通过命名本机查询来实现 如果指
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • Karaf / Maven - 无法解决:缺少需求 osgi.wiring.package

    我无法在 Karaf 版本 3 0 1 中启动捆绑包 该包是使用 Maven 构建的并导入gson http mvnrepository com artifact com google code gson gson 2 3 1 我按照要求将
  • 使用Java绘制维恩图

    我正在尝试根据给定的布尔方程绘制维恩图 例如 a AND b AND c我想在 Android 手机上执行此操作 因此我需要找到一种使用 Java 来执行此操作的方法 我找到了一个完美的小部件 它可以完成我在这方面寻找的一切布尔代数计算器
  • 如何在Java中对对象数组进行字段级别排序以进行等级比较?

    In Java Class StudentProgress String Name String Grade CTOR goes here main class main method StudentProgress arrayofObje
  • ECDH使用Android KeyStore生成私钥

    我正在尝试使用 Android KeyStore Provider 生成的私有文件在 Android 中实现 ECDH public byte ecdh PublicKey otherPubKey throws Exception try
  • Java 的 PriorityQueue 与最小堆有何不同?

    他们为什么命名PriorityQueue如果你不能插入优先级 它看起来与堆非常相似 有什么区别吗 如果没有区别那为什么叫它PriorityQueue而不是堆 默认的PriorityQueue是用Min Heap实现的 即栈顶元素是堆中最小的
  • 如何使用通配符模拟泛型方法的行为

    我正在使用 EasyMock 3 2 我想基于 Spring Security 为我的部分安全系统编写一个测试 我想嘲笑Authentication http docs spring io autorepo docs spring secu

随机推荐

  • 如何在 C# 中计算 OneDrive XOrHash

    我们希望以与 OneDrive 相同的方式计算 XOrHash 以便我们可以检测与 OD4B 后端同步所需的任何更改 我有当前使用的 XOrHash 算法的实现 可以在这里找到https learn microsoft com en us
  • 如何使用 Zapier 代码发布推文

    以下内容在 Code by Zapier 操作中不起作用 fetch https api twitter com 1 1 statuses update json status encodeURIComponent textToTweet
  • Java内存转储问题

    我尝试使用下面的代码创建内存转储 usr lib jvm j2sdk1 5 sun bin jmap heap 10699 但我遇到了下面提到的错误 任何人都可以帮助我 正在附加进程 ID 10699 请稍候 附加到进程时出错 sun jv
  • 不带参数的 git filter-branch 有什么作用?

    什么是git filter branch没有争论吗 我在我的仓库上运行了这个 不小心过早地按了回车键 没有什么 它似乎计算了哈希值并没有发现任何变化
  • ActionScript 2 缺乏 Flash ActionScript 3 功能

    自从 Adob e 随 Flash Player 9 引入 ActionScript 3 以来 我们中的许多人转换得很慢 简而言之 我想知道 AS3 作为一个框架可以做什么 这在 AS2 中是根本不可能或非常困难的 我不是在谈论现成的组件
  • 如何从 java servlet 中的 POST 数据中分离出查询字符串参数

    当您在 servlet 中收到 doGet 或 doPost 调用时 您可以使用getparameterxxx 在一个简单的地方获取查询字符串或发布数据 如果调用是 GET 您可以从 url 查询字符串获取数据 如果调用是 POST 您将获
  • CPU 如何从 RAM 访问应用程序和数据

    在应用程序加载到 RAM 并打开文件后 因此文件的数据也存储在 RAM 中 我在理解 CPU 如何从 RAM 访问应用程序和数据时遇到了一些困难 根据我的理解 CPU 只是在程序计数器滴答时从 RAM 获取指令或在中断后执行任务 那么它如何
  • 在 protobuf 消息中存储单个字节

    我使用什么数据类型在协议缓冲区消息中存储单个字节 查看列表位于https developers google com protocol buffers docs proto scalar似乎 int32 类型之一是最合适的 有没有更有效的方
  • 使用比较运算符比较 time_t 值

    我有2个time t值 我想找出哪一个更大 time t是内部的 int64在我的平台上 我可以用吗 lt gt and 运算符来比较值 我不想知道两个时间值之间的差异 代码只会在 Windows 上运行 所以我不关心可移植性 以这种方式比
  • 如何使用Python脚本控制LabView VI前面板开关(开/关、条调节器)?

    我有一个LabView前面板控制硬件的开关和传感器电压调节器 需要使用 Python 脚本来控制它们 我对此了解不多LabView 请解释如何做到这一点 我在 LabVIEW 讨论板上找到了一份参考资料 该参考资料成功地this 它使用以下
  • 如何在 C++ 中将窗口的屏幕截图作为位图对象获取?

    如何在 C 中将窗口的屏幕截图作为位图对象获取 假设我已经有了窗口句柄 我还想知道是否可以在最小化状态下获取窗口的屏幕截图 这里的 C 是指 VC 以及与 Windows XP win32 相关的所有库 你应该调用 PrintWindow
  • RubyMine 代码自动完成

    我即将习惯在 Android Studio 中使用 Java 最棒的是一切都被强烈声明 因此 当我输入 MyClass someme 时 IDE 会为我提供高级代码自动完成功能 发展是迅速而令人愉快的 但后来我想学习 RubyOnRails
  • 如何在 Bash 中读取文件或标准输入

    以下 Perl 脚本 my pl 可以从命令行参数中的文件或从标准输入 标准输入 while lt gt print perl my pl将从标准输入读取 而perl my pl a txt将从中读取a txt 这非常方便 Bash 中有类
  • 如何将 2 个 Excel 文件合并为一个具有不同工作表的 Excel 文件?

    我有 2 个 Excel 文件 我想将它们合并为 1 个具有单独工作表的文件 我尝试与 Microsoft Office Interop Excel 进行合并 但我不明白如何使用它 对于叶海亚 这里是获取范围的方法 我想将它们与不同的文件合
  • 如何为 cout 编写一个允许表达语法的函数包装器?

    我想包起来std cout用于格式化 如下所示 mycout what type x optional args do some formatting on x first std cout lt lt x 并且仍然能够使用表达语法 例如
  • 样式和主题的背景问题

    在 attrs 我有
  • 强制方向为纵向模式

    我的所有应用程序都处于纵向模式 但我有一个横向模式的视图控制器作为图像库 在 项目摘要 选项卡上启用 LandscapeLeft 模式 因此我必须在视图控制器的其余部分中以这种方式禁用旋转 但图像库的 VC 中除外 我想保持旋转为纵向模式
  • 我可以仅使用 twiml bin 将短信转发到电子邮件吗?

    非常清楚如何使用 twilio 将 SMS 转发到电子邮件地址 他们有一个使用托管在第三方服务器上的 php 代码执行此操作的很好的示例 但是 我想仅使用 twiml 应用程序将短信转发到电子邮件地址 而不使用其他第三方请求 代码 我尝试使
  • Spring boot Tomcat – 启用/禁用目录列表

    I have spring boot应用程序和我正在使用embedded tomcat作为网络服务器 我在列出目录时遇到问题 我现在就想怎样才能enable or disable listing directories在嵌入式tomcat中
  • 更改 JPanel Graphics g 颜色绘制线

    我有一个类似于绘画的程序 而且我正在尝试实现更改笔颜色 但是当我更改颜色时 当前绘制的所有内容都会更改为红色 例如在我的程序中 我怎样才能使其不会将当前绘制的所有内容重新绘制为当前颜色改变颜色 下面的代码将编译并运行 JPanel 绘图区域