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

}