paintComponent方法只被调用一次

时间:2018-05-23 11:59:51

标签: 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 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类的对象,并将其添加到我的主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方法吗?

2 个答案:

答案 0 :(得分:2)

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

替换:

addMouseMotionListener(new PaintingField());

使用:

addMouseMotionListener(paintingField);

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

super.paintComponent(g);

作为最后一点,为了避免组件坐标问题,您应该直接在PaintingField面板上注册鼠标监听器。

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

addMouseMotionListener(this);

addMouseMotionListener(paintingField)移除PatternCreator

答案 1 :(得分:1)

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

addMouseMotionListener(paintingField);