Rafał Prominski
Rafał Prominski

Reputation: 3

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

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.

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. Can somebody explain me why paintComponent method is not called?

Upvotes: 0

Views: 431

Answers (2)

Arnaud
Arnaud

Reputation: 17524

You are registering a new instance of PaintingField as the mouse listener, instead of your previously created object.

Replace :

addMouseMotionListener(new PaintingField());

With :

addMouseMotionListener(paintingField);

Also your paintComponent method should call the parent method, to ensure that everything gets cleared correctly.

super.paintComponent(g);

As a last note, to avoid components coordinates problems, you should rather register the mouse listener on the PaintingField panel directly.

So try putting the following in the PaintingField 's constructor

addMouseMotionListener(this);

And remove addMouseMotionListener(paintingField) from PatternCreator .

Upvotes: 2

Itai Zelther
Itai Zelther

Reputation: 82

The paintingField you’re using for the actual frame and for the mouse listeners aren’t the same. That means, when you call the repaint in the paintingField method of the mouseListener, you’re actually repainting a different, invisible frame. To fix it you should use the same object. So change the mouseListener line to:

addMouseMotionListener(paintingField);

Upvotes: 1

Related Questions