Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中临时存储JPanel或PaintComponent的图像?_Java_Image_Swing_Paintcomponent_Repaint - Fatal编程技术网

如何在Java中临时存储JPanel或PaintComponent的图像?

如何在Java中临时存储JPanel或PaintComponent的图像?,java,image,swing,paintcomponent,repaint,Java,Image,Swing,Paintcomponent,Repaint,我正在尝试制作一个画图程序,这个类是你拖动鼠标画图的主要区域。问题是剪辑必须是矩形的,因此该剪辑矩形内的任何其他线(剪辑越大,移动越快)都将被新剪辑覆盖,但是新剪辑并不都是必需的 我的解决方案是: 以某种方式将片段设置为一条线(但我认为该片段必须在repaint方法中设置,而不是在paint组件中设置setClip()) 保存当前绘制组件上的图像并将其设置为背景 可能在没有线的区域将剪辑的眼力设置得更低 感谢您的阅读,下面是代码(有些部分留作简单阅读),如果您知道一个解决方案,我很想听听。谢谢

我正在尝试制作一个画图程序,这个类是你拖动鼠标画图的主要区域。问题是剪辑必须是矩形的,因此该剪辑矩形内的任何其他线(剪辑越大,移动越快)都将被新剪辑覆盖,但是新剪辑并不都是必需的

我的解决方案是:

以某种方式将片段设置为一条线(但我认为该片段必须在repaint方法中设置,而不是在paint组件中设置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;


}

我不知道你为什么要麻烦。每次绘制系统调用
paintComponent
,您都需要重新绘制整个组件

相反,只需绘制您需要绘制的内容,然后在其顶部绘制所选内容

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

中在其顶部绘制所选内容或其他动态部分?您的问题非常令人困惑,至少对我来说是如此。我不知道什么是
“…但是新的剪辑并不是所有需要的。”
的意思就是说。你又想干什么?请告诉我们更多的细节。请发表一篇文章来说明你的问题。我只是把头绕在脖子上,空气从耳朵里穿过,把你的问题读3-4遍,然后。。。。不走运,我被困在中间了!