Reputation: 3
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
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
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