更改JPanel Graphics g颜色绘制线 [英] Changing JPanel Graphics g color drawing line

查看:209
本文介绍了更改JPanel Graphics g颜色绘制线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i have a program similar to paint. and that i am trying to implement a change pen color however when i change the color, everything currently drawn is changed to the color RED for example in my program,how can i make it such that it will not repaint everything currently drawn to the currently changed color?Below code will compile and run

JPanel绘图区的类

Class for the JPanel drawing area

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。

  • 这样当你改变颜色时你的绘图只会影响当前曲线。

  • Use your ArrayList to draw the current curve as it is being drawn, but
  • Use a BufferedImage to draw your completed curves
  • You would do this on mouseReleased and would draw the current curve to the BufferedImage using the current color.
  • You'll also need to re-initialize your ArrayList of points after drawing to the BufferedImage.
  • Don't forget to dispose of the BufferedImage's Graphics object after you're done using it.
  • Draw the BufferedImage in your paintComponent method after super.paintComponent but before drawing your current curve.
  • This way when you change the color of your drawing, only the current curve is effected.

编辑

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

EDIT
You've mentioned in a comment that you're not familiar with BufferedImage, and are looking for another way. I suppose you could create a class that holds an ArrayList of Points together with a Color, and then on each mouseReleased create an object of this class and add it to an ArrayList in your drawing panel. Then your paintComponent method could iterate through that ArrayList, drawing the list of Points with their associated color, but my gut tells me that you're an intelligent guy and that you'd pick up on how to use a BufferedImage in no time. I really think it's the best solution. And if you try it and it flops, show us your code, and we'll likely be able to help you.

编辑2

BufferedImage构造函数将需要图像宽度,高度和图像类型 - 我是'我不是100%熟悉。我通常将BufferedImage.TYPE_INT_RGB用于通用绘图,而BufferedImage.TYPE_INT_ARGB通常用于需要alpha的通用目的。然后你将从BufferedImage中提取一个Graphics对象,比如getGraphics(),如果你需要的只是Graphics对象而不是Graphics2D对象。然后,当您在构造函数中初始化BufferedImage时,请使用Color.white填充它,就像使用JPanel一样。然后处理Graphics对象。然后每次你想要绘制,你得到图形,用它绘制,就像你在paintComponent方法中一样,完成时处理Graphics,最后通过drawImage方法在paintComponent中绘制BufferedImage。

EDIT 2
The BufferedImage constructor will need the image width, height and an image type -- something I'm not 100% familiar with. I usually use BufferedImage.TYPE_INT_RGB for general purpose drawing, and BufferedImage.TYPE_INT_ARGB for general purpose that needs an alpha too. Then you'll extract a Graphics object out of the BufferedImage, say getGraphics() if all you need is a Graphics object and not a Graphics2D object. Then when you initialize the BufferedImage in your constructor, fill it with a Color.white, just as you for your JPanel. Then dispose the Graphics object. Then each time you want to draw, you getGraphics, draw with it, just like you do in the paintComponent method, dispose of the Graphics when done, and finally draw the BufferedImage in the paintComponent via the drawImage method.

编辑3

示例程序不能完成你想做的事情,但确实说明了使用带绘图的BufferedImage。每次绘制新路径或曲线时,此程序都会更改颜色。

EDIT 3
Example program that doesn't do quite what you are trying to do but does illustrate use of a BufferedImage with drawing. This program changes the color each time a new path or curve is drawn.

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());
   }
}

这篇关于更改JPanel Graphics g颜色绘制线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆