Java paintComponent方法只调用一次

Java paintComponent方法只调用一次,java,swing,Java,Swing,我正试图编写一个简单的程序,当鼠标被拖动时绘制圆圈,但是paintComponent方法只被调用一次(启动后) 在这个类中,我有几个在拖动鼠标时绘制圆圈的方法 import javax.swing.*; import java.awt.*; import java.awt.Color; import java.awt.event.*; import java.awt.geom.Line2D; public class PaintingField extends JPanel implement

我正试图编写一个简单的程序,当鼠标被拖动时绘制圆圈,但是paintComponent方法只被调用一次(启动后)

在这个类中,我有几个在拖动鼠标时绘制圆圈的方法

import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.event.*;
import java.awt.geom.Line2D;

public class PaintingField extends JPanel implements MouseMotionListener {
    int x,y;

    public PaintingField(){
        setPreferredSize((new Dimension(500,500)));
        x = -1;
        y = -1;
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        x = e.getX();
        y = e.getY();
        System.out.println(x + " " + y);
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void paintComponent(Graphics g) {
        System.out.println("painting");
        if(x == -1 || y == -1)
            return;

        g.drawOval(x, y, 10, 10);
    }
}
在这里,我创建了我的paiting类的一个对象,并将其添加到我的主框架类中

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import static javax.swing.GroupLayout.Alignment.CENTER;

public class PatternCreator extends JFrame {

    JButton save = new JButton("save");
    JButton load = new JButton("load");
    JButton clear = new JButton("clear");
    JButton chooseFolder = new JButton("choose folder");
    JTextField path = new JTextField("");
    PaintingField paintingField = new PaintingField();

    public PatternCreator(){
        createLayout();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
        addMouseMotionListener(new PaintingField());
    }

    public void createLayout(){
        JPanel pane = (JPanel) getContentPane();
        GroupLayout groupLayout = new GroupLayout(pane);
        pane.setLayout(groupLayout);

        groupLayout.setAutoCreateContainerGaps(true);
        groupLayout.setAutoCreateGaps(true);

        groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(CENTER)
                .addGroup(groupLayout.createSequentialGroup()
                        .addComponent(save)
                        .addComponent(load)
                        .addComponent(clear)
                        .addComponent(chooseFolder))
                .addGroup(groupLayout.createSequentialGroup()
                        .addComponent(paintingField,GroupLayout.PREFERRED_SIZE,GroupLayout.PREFERRED_SIZE,GroupLayout.PREFERRED_SIZE))
                .addGroup(groupLayout.createSequentialGroup()
                        .addComponent(path))
        );
        groupLayout.setVerticalGroup(groupLayout.createSequentialGroup()
                .addGroup(groupLayout.createParallelGroup()
                        .addComponent(save)
                        .addComponent(load)
                        .addComponent(clear)
                        .addComponent(chooseFolder))
                .addGroup(groupLayout.createParallelGroup()
                        .addComponent(paintingField,GroupLayout.PREFERRED_SIZE,GroupLayout.PREFERRED_SIZE,GroupLayout.PREFERRED_SIZE))
                .addGroup(groupLayout.createParallelGroup()
                        .addComponent(path))
        );

        pack();
    }

}
以及主要的方法

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;

public class TextRecognition {

    public static void main(String args[]) {
        EventQueue.invokeLater(() -> {
            PatternCreator patternCreator = new PatternCreator();
        });
    }

}

之所以调用mouseDragged方法,是因为还调用了打印光标的位置以便重新绘制。有人能解释一下为什么不调用paintComponent方法吗?

您正在注册一个
PaintingField
的新实例作为鼠标侦听器,而不是以前创建的对象

替换:

addMouseMotionListener(new PaintingField());
与:

addMouseMotionListener(paintingField);
addMouseMotionListener(paintingField);
另外,您的
paintComponent
方法应该调用父方法,以确保正确清除所有内容

super.paintComponent(g);
最后,为了避免组件坐标问题,您应该直接在
PaintingField
面板上注册鼠标侦听器

因此,请尝试将以下内容放入
PaintingField
的构造函数中

addMouseMotionListener(this);

并从
PatternCreator
中删除
addMouseMotionListener(paintingField)
,您正在注册一个
paintingField
的新实例作为鼠标侦听器,而不是以前创建的对象

替换:

addMouseMotionListener(new PaintingField());
与:

addMouseMotionListener(paintingField);
addMouseMotionListener(paintingField);
另外,您的
paintComponent
方法应该调用父方法,以确保正确清除所有内容

super.paintComponent(g);
最后,为了避免组件坐标问题,您应该直接在
PaintingField
面板上注册鼠标侦听器

因此,请尝试将以下内容放入
PaintingField
的构造函数中

addMouseMotionListener(this);

并从
PatternCreator
中删除
addMouseMotionListener(paintingField)
,用于实际帧和鼠标侦听器的
paintingField
不相同。这意味着,当您在鼠标侦听器的
paintingField
方法中调用重新绘制时,实际上是在重新绘制一个不同的、不可见的帧。要修复它,您应该使用相同的对象。因此,将mouseListener行更改为:


用于实际帧和鼠标侦听器的
paintingField
不相同。这意味着,当您在鼠标侦听器的
paintingField
方法中调用重新绘制时,实际上是在重新绘制一个不同的、不可见的帧。要修复它,您应该使用相同的对象。因此,将mouseListener行更改为: