繁体   English   中英

paintComponent方法仅被调用一次

[英]paintComponent method is called only once

我正在尝试编写简单的程序,该程序在拖动鼠标时会画圆,但是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);
    }
}

在这里,我创建了一个绘画类的对象,并将其添加到我的主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();
    }

}

和主要方法。

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

同样,您的paintComponent方法应调用父方法,以确保正确清除所有内容。

super.paintComponent(g);

最后,为避免组件协调问题,您应该直接在PaintingField面板上注册鼠标侦听器。

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

addMouseMotionListener(this);

并从PatternCreator删除addMouseMotionListener(paintingField)

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

addMouseMotionListener(paintingField);

暂无
暂无

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

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