【问题标题】:Changing JPanel Graphics g color drawing line更改 JPanel Graphics g 颜色绘制线
【发布时间】:2011-08-31 14:45: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();
    }

}

【问题讨论】:

    标签: java swing drawing mouselistener


    【解决方案1】:

    一种方式:

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

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

    编辑 2
    BufferedImage 构造函数将需要图像宽度、高度和图像类型——我不是 100% 熟悉的。我通常将 BufferedImage.TYPE_INT_RGB 用于通用绘图,将 BufferedImage.TYPE_INT_ARGB 用于需要 alpha 的通用绘图。然后,您将从 BufferedImage 中提取一个 Graphics 对象,如果您只需要一个 Graphics 对象而不是 Graphics2D 对象,则说 getGraphics()。然后,当您在构造函数中初始化 BufferedImage 时,用 Color.white 填充它,就像您为 JPanel 一样。然后释放 Graphics 对象。然后每次你想画的时候,你就拿到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());
       }
    }
    

    【讨论】:

    • 嗨,对不起,我以前没有处理过缓冲图像的经验,因为我还没有经验,还有其他方法吗?
    • @kyrogue:请参阅上面我的回答中的编辑。
    • 我读到 bufferedImage 构造函数将采用图像类型?但是我的 JPanel 绘图不是图像,它只是徒手绘制的线条,这是如何联系起来的
    • BufferedImage 构造函数需要图像宽度、高度和图像类型——我不是 100% 熟悉的。我通常将 BufferedImage.TYPE_INT_RGB 用于通用绘图,将 BufferedImage.TYPE_INT_ARGB 用于也需要 alpha 的通用绘图。
    • @kyrogue:我已经发布了使用 BufferedImage 的示例代码。希望对您有所帮助。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      感谢气垫船,我已经完成了它,查看了您的代码并摆弄了大声笑。

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

      【讨论】:

        猜你喜欢
        • 2018-04-07
        • 2018-05-23
        • 2013-11-18
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-08
        • 1970-01-01
        相关资源
        最近更新 更多