简体   繁体   English

为什么此Java Paint程序不能绘制多个椭圆形?

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

I have a Java paint program that uses a custom JPanel to paint on. 我有一个Java绘画程序,它使用自定义的JPanel进行绘画。 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. 当单击JPanel时,会绘制一个小的椭圆形(或圆形,如果您愿意的话),则每次单击另一个位置时,椭圆形都会消失。 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: 坐标也会更新,但是椭圆形不会停留,它会移动到用户接下来单击的位置。这是自定义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? 我该如何解决?

Only one oval is drawn as there is only one fillOval statement drawing a single oval in the paintComponent method so the statement 仅绘制一个椭圆,因为在paintComponent方法中只有一个fillOval语句绘制了一个椭圆,因此该语句

super.paintComponent(g);

causes any previous painting to be cleared once repaint is called. 一旦调用repaint画,将清除以前的任何画。

To paint multiple ovals, you can paint components from a List<Point> as outlined in Custom Painting Approaches 要绘制多个椭圆,可以按照自定义绘制方法中的概述从List<Point>绘制组件

Don't call repaint from within paintComponent . 不要在paintComponent内调用repaint This creates an infinite loop and degrades performance. 这将导致无限循环并降低性能。 If periodic updates are required invoke repaint from the ActionListener of a Swing Timer instead. 如果需要定期更新,请从Swing TimerActionListener调用repaint

这是因为组件会重新绘制自身,以使更改永久生效,因此,每次完成绘制后,都应该拍摄jpanel的图像并将其设置为背景...

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


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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