简体   繁体   English

paintComponent方法仅被调用一次

[英]paintComponent method is called only once

I am trying to write simple programm which draws circle when mouse is dragged, but the paintComponent method is called only once (after start). 我正在尝试编写简单的程序,该程序在拖动鼠标时会画圆,但是paintComponent方法仅被调用一次(启动后)。

In this class class I have few methods which paints circle when mouse is dragged. 在此类课程中,我只有几种方法可以在拖动鼠标时绘制圆圈。

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

Here I create an object of my paiting class and add it to my main Frame class. 在这里,我创建了一个绘画类的对象,并将其添加到我的主Frame类。

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

}

And the main method. 和主要方法。

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

}

The mouseDragged method is called, because printing position of cursor so repaint is called too. 之所以调用mouseDragged方法,是因为还调用了光标的打印位置,因此也重新绘制。 Can somebody explain me why paintComponent method is not called? 有人可以解释为什么为什么不调用paintComponent方法吗?

You are registering a new instance of PaintingField as the mouse listener, instead of your previously created object. 您正在将一个PaintingField的新实例注册为鼠标侦听器,而不是先前创建的对象。

Replace : 更换:

addMouseMotionListener(new PaintingField());

With : 与:

addMouseMotionListener(paintingField);

Also your paintComponent method should call the parent method, to ensure that everything gets cleared correctly. 同样,您的paintComponent方法应调用父方法,以确保正确清除所有内容。

super.paintComponent(g);

As a last note, to avoid components coordinates problems, you should rather register the mouse listener on the PaintingField panel directly. 最后,为避免组件协调问题,您应该直接在PaintingField面板上注册鼠标侦听器。

So try putting the following in the PaintingField 's constructor 因此,尝试将以下内容放入PaintingField的构造函数中

addMouseMotionListener(this);

And remove addMouseMotionListener(paintingField) from PatternCreator . 并从PatternCreator删除addMouseMotionListener(paintingField)

The paintingField you're using for the actual frame and for the mouse listeners aren't the same. 您用于实际帧和鼠标侦听器的paintingField是不同的。 That means, when you call the repaint in the paintingField method of the mouseListener, you're actually repainting a different, invisible frame. 这意味着,当您在mouseListener的paintingField方法中调用重绘时,实际上是在重绘另一个不可见的帧。 To fix it you should use the same object. 要修复它,您应该使用相同的对象。 So change the mouseListener line to: 因此,将mouseListener行更改为:

addMouseMotionListener(paintingField);

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

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