有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java更改JPanel图形g颜色绘制线

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

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

}

共 (2) 个答案

  1. # 1 楼答案

    一种方式:

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

    编辑
    您在评论中提到,您不熟悉BuffereImage,正在寻找另一种方法。我想你可以创建一个类来保存一个带有颜色的点的ArrayList,然后在每个鼠标上创建这个类的一个对象,并将其添加到绘图面板中的ArrayList中。然后你的paintComponent方法可以遍历ArrayList,绘制点列表及其相关颜色,但我的直觉告诉我,你是一个聪明的人,你很快就会学会如何使用BuffereImage。我真的认为这是最好的解决办法。如果你尝试了,但失败了,给我们看看你的代码,我们很可能会帮助你

    编辑2
    BuffereImage构造器将需要图像宽度、高度和图像类型,我对这些不是100%熟悉。我通常使用BuffereImage。键入_INT_RGB(通用图形)和BuffereImage。键入_INT_ARGB,用于需要alpha的一般用途。然后,您将从BuffereImage中提取一个图形对象,如果您只需要一个图形对象而不是Graphics2D对象,请使用getGraphics()。然后在构造函数中初始化BuffereImage时,用颜色填充它。白色,就像你的JPanel一样。然后处理图形对象。然后每次你想画画的时候,你都会得到图形,用它画画,就像你在paintComponent方法中做的那样,完成后处理图形,最后通过drawImage方法在paintComponent中绘制BuffereImage

    编辑3
    示例程序,它不完全执行您试图执行的操作,但说明了BuffereImage在绘图中的使用。每次绘制新路径或曲线时,该程序都会更改颜色

    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());
       }
    }
    
  2. # 2 楼答案

    谢谢气垫船,我看了你的代码就搞定了,哈哈

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