简体   繁体   中英

The lines that I draw get removed when another line is drawn

The lines that I draw get removed when another line is drawn. I am using mouse event to draw lines but when ever i draw the second line the first one get removed. I believe it has something to do with my points which keep changing the location of the coordinates where i want to draw the line as my click keep changing the points but i am not sure that's the reason; please help thanks in advance

public class DrawOnComponent

{

public static void main(String args[]) throws Exception {

JFrame f = new JFrame("Draw a Red Line");

f.setSize(300, 300);

f.setLocation(300, 300);

f.setResizable(false);

JPanel p = new JPanel() {

    Point pointStart = null;

    Point pointEnd   = null;

    {
        addMouseListener(new MouseAdapter() {

            public void mousePressed(MouseEvent e) {

                pointStart = e.getPoint();

            }

            public void mouseReleased(MouseEvent e) {
                pointStart = null;
            }
        });
        addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent e) {
                pointEnd = e.getPoint();
            }

            public void mouseDragged(MouseEvent e) {
                pointEnd = e.getPoint();
                repaint();
            }
        });
    }
    public void paint(Graphics g) {
        super.paint(g);
        if (pointStart != null) {
            g.setColor(Color.RED);
            g.drawLine(pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
        }
    }
};
f.add(p);
f.setVisible(true); 

} }

If you want lines to persist, then you need to draw all the lines that need to be seen. This is often done in one of two ways:

  • Create an ArrayList of something to hold line data, such as an ArrayList<Line2D> , add to it when you want to add a new line, and then in paintComponent, iterate through the list drawing each line.
  • Or drawing each line to a BufferedImage, and drawing the BufferedImage in paintComponent using Graphics#drawImage(...) .

For example -- using a BufferedImage, we'd get the Graphics object from the BufferedImage, draw onto the image using it, dispose of the object, and then call repaint() to ask the GUI to repaint itself. The JPanel's paintComponent method would draw the image:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class DrawLines extends JPanel {
    // size of things
    private static final int BI_W = 600;
    private static final int BI_H = BI_W;
    private static final Color BACKGROUND_COLOR = Color.WHITE;

    // properties of the temporary and permanent lines
    private static final Color LINE_COLOR = new Color(200, 200, 255);
    public static final Color SAVED_LINES_COLOR = Color.BLUE;
    public static final Stroke SAVED_LINES_STROKE = new BasicStroke(5f);

    // image to hold permanent lines
    private BufferedImage img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);

    // of true, draw temporary line
    private boolean drawTempLine = false;
    private int x1 = 0;
    private int y1 = 0;
    private int x2 = 0;
    private int y2 = 0;

    public DrawLines() {
        setBackground(BACKGROUND_COLOR);

        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, this);

        if (drawTempLine) {
            g.setColor(LINE_COLOR);
            g.drawLine(x1, y1, x2, y2);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        int w = img.getWidth();
        int h = img.getHeight();
        return new Dimension(w, h);
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            x1 = e.getX();
            y1 = e.getY();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            x2 = e.getX();
            y2 = e.getY();
            drawTempLine = true;
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            x2 = e.getX();
            y2 = e.getY();

            // draw to buffered image with its graphics object
            Graphics2D g2 = img.createGraphics();
            // for smoother drawing
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // set the color and thickness of the saved line
            g2.setColor(SAVED_LINES_COLOR);
            g2.setStroke(SAVED_LINES_STROKE);

            // draw the saved line
            g2.drawLine(x1, y1, x2, y2);

            // we're done with this Graphics object -- dispose of it
            g2.dispose();

            // tell gui not to draw the temporary drawing line
            drawTempLine = false;

            // ask GUI to repaint itself
            repaint();
        }

    }

    private static void createAndShowGui() {
        DrawLines mainPanel = new DrawLines();

        JFrame frame = new JFrame("Draw Lines");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Check out Custom Painting Approaches .

It has working examples of the two common ways to do incremental painting:

  1. paint from a List of objects

  2. draw on a BufferedImage.

Which approach you use depends on your exact requirement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM