I wrote a MouseMotionListener for JPanel, but I get confused on how to use it.
The listener class works well when added to the frame using aWindow.add(new MouseMotionEvents()), but when I try to add it to the panel using content.add(new MouseMotionEvents()), it doesn't work. I am new to Swing and JComponents, could someone give me some hints?
public class test {
public static void main(String[] args) {
JFrame aWindow = new JFrame();
aWindow.setBounds(600, 600, 600, 600);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel();
content.add(new MouseMotionEvents());
aWindow.add(content);
aWindow.setVisible(true);
}
}
class MouseMotionEvents extends JPanel implements MouseListener,
MouseMotionListener {
Point p;
Point r;
public MouseMotionEvents() {
addMouseListener(this);
addMouseMotionListener(this);
}
public void mouseClicked(MouseEvent me) {
// p = me.getPoint();
// repaint();
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
p = me.getPoint();
// repaint();
}
public void mouseReleased(MouseEvent me) {
r = me.getPoint();
repaint();
}
public void mouseDragged(MouseEvent me) {
r = me.getPoint();
repaint();
}
public void mouseMoved(MouseEvent me) {
}
public void paint(Graphics g) {
if (p != null && r != null) {
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
if(p.getX()-r.getX()>0 && p.getY()-r.getY()>0){
g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(p.getY()-r.getY()));
}
if(p.getX()-r.getX()>0 && p.getY()-r.getY()<0){
g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(-p.getY()+r.getY()));
}
if(p.getX()-r.getX()<0 && p.getY()-r.getY()>0){
g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(p.getY()-r.getY()));
}
if(p.getX()-r.getX()<0 && p.getY()-r.getY()<0){
g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(-p.getY()+r.getY()));
}
}
}
}
In the code in your question, you are adding a
JPanelto aJPanelsinceMouseMotionEventsis aJPanel(since it extends classJPanel). The default layout manager forJPanelisFlowLayoutwhich tries to display its contained components at their preferred size. So when you run your GUI, you cannot really see whereMouseMotionEventsappears. You can add a border to it by adding the following (in the constructor of classMouseMotionEvents)Now when you run the GUI, it looks like this
This is because a
JPanelhas zero (preferred) size because its size is determined by the components that it contains but in your codeMouseMotionEventscontains no components. You can fix this by explicitly setting a preferred size. This is how it looks after setting an appropriate preferred size.Now you can drag the mouse inside the red border and rectangles will be drawn.
Also, you should override method
paintComponentand not methodpaint. Refer to Performing Custom Painting.Here is the code.
Note that
xandyare public members of classPointso no need to use methodsgetXandgetYand therefore no need for casting.When you added
MouseMotionEventsdirectly to theJFrameyou were addingMouseMotionEventsto aJPanelwithBorderLayoutand you were adding it to the CENTER. Since you gave yourJFrameand explicit size, theBorderLayoutmade sure that the size ofMouseMotionEventstook up as much space as possible in theJFrame. HenceMouseMotionEventswas large enough that you could drag the mouse inside it.