2011-05-24 76 views
4

我有一个类似于绘画的程序。并且我试图实现更改笔颜色,但是当我更改颜色时,当前绘制的所有内容都将更改为红色,例如在我的程序中,我如何使它不会重新绘制当前绘制到当前的所有内容变了脸色呢?下面的代码可以编译和运行更改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(); 
    } 

} 

回答

8

方式一:

  • 使用ArrayList中吸取电流曲线,因为它正在草拟,但
  • 使用一个BufferedImage绘制你完成曲线
  • 你会在做mouseReleased并使用当前颜色将当前曲线绘制到BufferedImage。
  • 您还需要在绘制到BufferedImage后重新初始化您的ArrayList的点。
  • 不要忘记在完成使用后处置BufferedImage的Graphics对象。
  • 在super.paintComponent之后但在绘制当前曲线之前,在paintComponent方法中绘制BufferedImage。
  • 通过这种方式,当您更改绘图的颜色时,只会生成当前曲线。

编辑
你已经在你不熟悉的BufferedImage,并正在寻找另一种方式的评论中提及。我想你可以创建一个类,它将Point的ArrayList与Color一起保存,然后在每个mouseReleased上创建该类的对象并将其添加到绘图面板中的ArrayList。然后你的paintComponent方法可以迭代ArrayList,并用它们的关联颜色绘制Points列表,但是我的直觉告诉我你是一个聪明的人,并且你很快就会学会如何使用BufferedImage。我真的认为这是最好的解决方案。如果你尝试它,它会失败,向我们展示你的代码,我们可能会帮助你。

EDIT 2
BufferedImage构造方法将所需要的图像的宽度,高度和图像类型 - 这是我不熟悉的100%。我通常将BufferedImage.TYPE_INT_RGB用于通用绘图,而BufferedImage.TYPE_INT_ARGB用于需要alpha的通用目的。然后你会从BufferedImage中提取一个Graphics对象,比如getGraphics(),如果你需要的只是一个Graphics对象而不是Graphics2D对象。然后,当您在构造函数中初始化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()); 
    } 
} 
+0

喜,抱歉,但我有对BufferedImage工作之前,作为即时通讯仍然缺乏经验没经验,有没有这样做的另一种方式? – sutoL 2011-05-24 04:10:52

+0

@kyrogue:请参阅上面我的回答中的编辑。 – 2011-05-24 04:19:01

+0

我读过bufferedImage构造函数将采取图像类型?然而,我的JPanel图纸不是图像,它只是绘制了手绘线条,它如何链接起来 – sutoL 2011-05-24 04:30:17

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

}