2013-10-23 18 views
-1

我正在尝试制作一个绘画程序,并且此类是拖动鼠标进行绘制的主要区域。问题是剪辑必须是矩形,所以剪辑矩形内的任何其他行(剪辑越大,移动得越快)将被新剪辑覆盖,但是并不需要新剪辑。我如何临时存储Java中的JPanel或PaintComponent的图像?

我的解决方案的思路是:

要剪辑莫名其妙定置到线(但我认为剪辑将不得不在涂料成分重绘方法,而不是setClip的()进行设置)

要将当前图像保存在绘画组件中并将其设置为背景

可能将剪辑的占用设置在没有线条的区域中较低?

感谢您阅读本文,这里是代码(为了简化阅读,省略了部分内容),如果您知道解决方案,我很乐意听到它。谢谢!

public class Canvas extends JPanel implements MouseMotionListener, MouseListener{ 

    int sizeX, sizeY; 
    String title; 
    int[] backColor = new int[3]; 
    int brushSize=20; 
    Point currentP = new Point(); 
    Point pastP = new Point(); 
    Point paintP = new Point(); 
    int diffX, diffY; 
    boolean initialize=true; 
    boolean initClip=true; 




    Canvas(){ 
     backColor[0] = newProject.colorA; 
     backColor[1] = newProject.colorB; 
     backColor[2] = newProject.colorC; 


     if(backColor[0]>=255){ 
      backColor[0]=255; 
     } 
     if(backColor[1]>=255){ 
      backColor[1]=255; 
     } 
     if(backColor[2]>=255){ 
      backColor[2]=255; 
     } 
     sizeX = newProject.sizeX; 
     sizeY = newProject.sizeY; 

     //System.out.println(sizeX + " " + sizeY); 
     setSize(sizeX,sizeY); 
     setBackground(Color.white); 
    } 

public void paintComponent(Graphics g){ 

     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setStroke(new BasicStroke(brushSize)); 
     if(initialize){ 
     g.setColor(new Color(backColor[0], backColor[1], backColor[2])); 
     g.fillRect(0, 0, sizeX, sizeY); 
     g.setColor(Color.red); 
     g.drawRect(0,0,50,50); 
     System.out.println("Initialize"); 

     } 
     else{ 

     g2.drawLine(currentP.x, currentP.y, pastP.x,pastP.y); 
     } 

     //System.out.println("Paint"); 
} 
@Override 
public void mouseDragged(MouseEvent e) { 
    if(initClip)      //if mouse has been released since last dragged 
     currentP = e.getPoint(); //This causes PastP and CurrentP to be equal 
     initClip=false;   //since pastP is set equal to CurrentP afterward 
    pastP = currentP; 
    currentP = e.getPoint(); 
    diffX=Math.abs(currentP.x-pastP.x); //find the differences to find how big of 
    diffY=Math.abs(currentP.y-pastP.y); //a clip it needs 
    if(diffX==0){      //if no movement, set it to brush size so the 
     diffX=brushSize;    //clip shows up 
    } 
    if(diffY==0){ 
     diffY=brushSize; 
    } 
    initialize=false; 


    if(currentP.x-pastP.x>0){ //figures out which direction it moved 
     paintP.x=pastP.x; //sets the clip variable to the correct corner 
    } 
    else{ 
     paintP.x=currentP.x; 
    } 

    if(currentP.y-pastP.y>0){ 
     paintP.y=pastP.y; 
    } 
    else{ 
     paintP.y=currentP.y; 
    } 
    System.out.println(paintP); 
    repaint(paintP.x, paintP.y, diffX, diffY); //repaint with point PaintP and the 
               //difference it moved 

} 

@Override 
public void mouseReleased(MouseEvent arg0) { 
    initClip=true; 


} 
+2

你的问题很混乱,至少对我来说。我不知道是什么......“但是新剪辑并不是全部需要的。”你又想做什么?请告诉我们更多的细节。请发布证明你的问题的[sscce](http://sscce.org)。 –

+0

我只是在我的脖子上滚动我的头,空气通过耳朵,阅读你的问题3-4次,....没有运气,我卡在中间! – Sage

回答

2

我不知道为什么你会打扰。每次由绘图系统调用paintComponent时,无论如何您都需要重新绘制整个组件。

相反,只是画你需要油漆,涂料,然后在它上面的选择是什么?

enter image description here

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class DrawSelection { 

    public static void main(String[] args) { 
     new DrawSelection(); 
    } 

    public DrawSelection() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage background; 
     private Rectangle clipRect; 

     public TestPane() { 
      try { 
       background = ImageIO.read(new File("/path/to/your/image")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

      MouseAdapter ma = new MouseAdapter() { 

       private Point cp; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        cp = e.getPoint(); 
        clipRect = null; 
        repaint(); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        cp = null; 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        Point p = e.getPoint(); 
        int x = Math.min(p.x, cp.x); 
        int y = Math.min(p.y, cp.y); 
        int width = Math.max(p.x, cp.x) - x; 
        int height = Math.max(p.y, cp.y) - y; 
        clipRect = new Rectangle(x, y, width, height); 
        repaint(); 
       } 


      }; 

      addMouseListener(ma); 
      addMouseMotionListener(ma); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (background != null) { 
       int x = (getWidth() - background.getWidth())/2; 
       int y = (getHeight() - background.getHeight())/2; 
       g2d.drawImage(background, x, y, this); 
      } 
      if (clipRect != null) { 

       g2d.setColor(UIManager.getColor("List.selectionBackground")); 
       g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
       g2d.fill(clipRect); 

      } 
      g2d.dispose(); 
     } 
    } 

} 

如果你想优化烤漆工艺,为什么不画部分图像添加到背景缓冲区,并简单地绘制缓冲区,然后在paintComponent内将选区或其他动态部分绘制在顶部?

相关问题