更改JPanel Graphics g颜色绘制线

时间:2011-05-24 03:28:25

标签: java swing drawing mouselistener

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

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

}

3 个答案:

答案 0 :(得分:9)

一种方式:

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

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

编辑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。

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

答案 1 :(得分:1)

Custom Painting Approaches提供了两个关于如何做到这一点的想法。

答案 2 :(得分:0)

谢谢气垫船,我已经看完了你的代码并摆弄了大声笑。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

public class STDrawingArea extends JPanel {
    /**
     * 
     */
    private static final int DA_WIDTH = 700;
    private static final int DA_HEIGHT = 500;
    private static final Color DA_BGCOLOR = Color.WHITE;
    private static final long serialVersionUID = 1L;


    ArrayList<Point> points = new ArrayList<Point>();

    private Color currentColor;
    BufferedImage bImage = new BufferedImage(DA_WIDTH, DA_HEIGHT, BufferedImage.TYPE_INT_RGB);

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

         //Basic Settings for bImage
         Graphics g2d = bImage.getGraphics();
         g2d.setColor(DA_BGCOLOR);
         g2d.fillRect(0, 0, DA_WIDTH, DA_HEIGHT);
         g2d.dispose();

         addMouseListener(new MouseAdapter(){
             public void mousePressed(MouseEvent e)
             {
                points.clear();
                points.add(e.getPoint());
             }
         });

         addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) 
            {
                points.add(e.getPoint());
                repaint();
            }

             }); 

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

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DA_WIDTH,DA_HEIGHT);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawIntoBufferedImage();
        g.drawImage(bImage,0,0,null);
        freehandLines(g);

    }
    public void drawIntoBufferedImage()
    {
        Graphics g = bImage.getGraphics();
        freehandLines(g);
        g.dispose();
    }

    public void freehandLines(Graphics g)
    {
         if(points != null && points.size() > 1)
         {

             g.setColor(getCurrentColor());
              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;
                   g.drawLine(x1, y1, x2, y2);
               }
         }
    }
    //clear drawings method
    public void clearDrawings()
    {
        if(points!=null)
        {
            points.clear();
            Graphics g = bImage.getGraphics();
            g.setColor(DA_BGCOLOR);
            g.fillRect(0, 0, DA_WIDTH, DA_WIDTH);
            g.dispose();
            repaint();
        }

    }

    public void setCurrentColor(Color currentColor) {
        if(currentColor == null)
        {
            currentColor = Color.BLACK;
        }else{
            this.currentColor = currentColor;
        }

    }

    public Color getCurrentColor() {
        if (currentColor == null)
        return Color.BLACK;
        else
        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 btnRedPen = new JButton("Red Pen");
        JButton btnGreenPen = new JButton("Green Pen");
        JButton btnClear = new JButton("Clear");
        buttonContainer.add(btnRedPen);
        buttonContainer.add(btnGreenPen);
        buttonContainer.add(btnClear);
        //Drawing Area instantiation


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


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

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

        btnGreenPen.addActionListener(new ActionListener() {

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

        btnClear.addActionListener(new ActionListener() {

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


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

}