更改JPanelgraphics颜色绘制线

我有一个类似于油漆的程序。 而我试图实现改变笔的颜色,但是当我改变颜色,当前绘制的所有东西都改为颜色红色,例如在我的程序中,我怎样才能使它不会重绘当前绘制到当前改变颜色?下面的代码将编译并运行

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(rx, ry, 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; } } 

testing主类。

 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。
  • 这样,当您更改绘图的颜色时,只会影响当前的曲线。

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

编辑2
BufferedImage的构造函数将需要图像的宽度,高度和图像types – 我不是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。 每次绘制新path或曲线时,该程序都会改变颜色。

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

自定义绘画方法提供了两个想法,你可能会这样做。

感谢气垫船,我已经做了看你的代码,摆弄哈哈。

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