Why doesn't this Java paint program paint more than one oval?

蓝咒 提交于 2019-12-12 02:56:59

问题


I have a Java paint program that uses a custom JPanel to paint on. While when clicking on the JPanel paints a small oval (or circle, if you will), the oval disappears each time you click on another place. The coordinates also get updated, but the oval does not stay, it moves to wherever the user clicks next... Here's the code for the custom JPanel:

int xCord, yCord;

    public class PaintPanel extends JPanel implements MouseListener {
        // default serial whatever...
        private static final long serialVersionUID = -6514297510194472060L;

        // initial values
        int xCord = -10;
        int yCord = -10;

        public PaintPanel() {
            addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(ProgramUI.currentColor);
            g.fillOval(xCord, yCord, 8, 8);
            repaint();
        }

        @Override
        public void mouseClicked(MouseEvent m) {
        }

        @Override
        public void mouseEntered(MouseEvent m) {
        }

        @Override
        public void mouseExited(MouseEvent m) {
        }

        @Override
        public void mousePressed(MouseEvent m) {
            if (paintPanel.contains(m.getPoint())) {
                xCord = m.getX();
                yCord = m.getY();
                System.out.println("x: " + xCord + " y: " + yCord);
            }
        }

        @Override
        public void mouseReleased(MouseEvent m) {
        }

    }

I need the holding of a mouse to continuously paint an oval until the mouse button is let go. The only problem here is that the mouse oval updates, but does not save it's original position. How do I fix this?


回答1:


Only one oval is drawn as there is only one fillOval statement drawing a single oval in the paintComponent method so the statement

super.paintComponent(g);

causes any previous painting to be cleared once repaint is called.

To paint multiple ovals, you can paint components from a List<Point> as outlined in Custom Painting Approaches

Don't call repaint from within paintComponent. This creates an infinite loop and degrades performance. If periodic updates are required invoke repaint from the ActionListener of a Swing Timer instead.




回答2:


that is because the component repaints itself, to make the change permanent you should take the image of the jpanel and set it as background once you finish drawing each time...




回答3:


You are only painting the last place the user clicked each time. Instead, you need to collect the past clicks and paint them all each time.

This code will do what you want:

package com.sandbox;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

public class SwingSandbox {


    public static void main(String[] args) {

        JFrame frame = buildFrame();
        frame.add(new PaintPanel());
    }

    public static class PaintPanel extends JPanel implements MouseListener {
        // default serial whatever...
        private static final long serialVersionUID = -6514297510194472060L;

        ArrayList<Point> points = new ArrayList<Point>();

        public PaintPanel() {
            addMouseListener(this);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(new Color(250));
            for (Point point : points) {
                g.fillOval(point.x, point.y, 8, 8);
            }
            repaint();
        }

        @Override
        public void mouseClicked(MouseEvent m) {
        }

        @Override
        public void mouseEntered(MouseEvent m) {
        }

        @Override
        public void mouseExited(MouseEvent m) {
        }

        @Override
        public void mousePressed(MouseEvent m) {
            if (this.contains(m.getPoint())) {
                points.add(m.getPoint());
            }
        }

        @Override
        public void mouseReleased(MouseEvent m) {
        }

    }


    private static JFrame buildFrame() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(200, 200);
        frame.setVisible(true);
        return frame;
    }


}


来源:https://stackoverflow.com/questions/16904768/why-doesnt-this-java-paint-program-paint-more-than-one-oval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!