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 JComponent
s, 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()));
}
}
}
}
CodePudding user response:
In the code in your question, you are adding a JPanel
to a JPanel
since MouseMotionEvents
is a JPanel
(since it extends class JPanel
). The default
This is because a JPanel
has zero (preferred) size because its size is determined by the components that it contains but in your code MouseMotionEvents
contains 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 paintComponent
and not method paint
. Refer to Performing Custom Painting.
Here is the code.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MouseMotionEvents extends JPanel implements MouseListener, MouseMotionListener {
Point p;
Point r;
public MouseMotionEvents() {
addMouseListener(this);
addMouseMotionListener(this);
setBorder(BorderFactory.createLineBorder(Color.red));
setPreferredSize(new Dimension(300, 300));
}
public void mouseClicked(MouseEvent me) {
// p = me.getPoint();
// repaint();
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
System.out.println("mousePressed");
p = me.getPoint();
// repaint();
}
public void mouseReleased(MouseEvent me) {
System.out.println("mouseReleased");
r = me.getPoint();
repaint();
}
public void mouseDragged(MouseEvent me) {
r = me.getPoint();
repaint();
}
public void mouseMoved(MouseEvent me) {
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (p != null && r != null) {
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
if (p.x - r.x > 0 && p.y - r.y > 0) {
g.drawRect(p.x, p.y, (p.x - r.x), (p.y - r.y));
}
if (p.x - r.x > 0 && p.y - r.y < 0) {
g.drawRect(p.x, p.y, (p.x - r.x), (-p.y r.y));
}
if (p.x - r.x < 0 && p.y - r.y > 0) {
g.drawRect(p.x, p.y, (-p.x r.x), (p.y - r.y));
}
if (p.x - r.x < 0 && p.y - r.y < 0) {
g.drawRect(p.x, p.y, (-p.x r.x), (-p.y r.y));
}
}
}
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);
}
}
Note that x
and y
are public members of class Point
so no need to use methods getX
and getY
and therefore no need for casting.
When you added MouseMotionEvents
directly to the JFrame
you were adding MouseMotionEvents
to a JPanel
with BorderLayout
and you were adding it to the CENTER. Since you gave your JFrame
and explicit size, the BorderLayout
made sure that the size of MouseMotionEvents
took up as much space as possible in the JFrame
. Hence MouseMotionEvents
was large enough that you could drag the mouse inside it.
CodePudding user response:
To add a MouseMotionListener to a JPanel, you have to use
myPanel.setMouseMotionListener ( myMouseListener );
and call that directly on your panel, as you did in the mouseMotionEvents class. Tht's why it's working, when you add this directly to your JFrame.
After fixing your code I got this, which should work perfectly fine. I splitted it in two classes, one main class with JFrame and one for the JPanel (content).
Main class:
public class MouseMotionListenerTest {
public static void main ( String[] args ) {
JFrame aWindow = new JFrame();
aWindow.setBounds( 600, 600, 600, 600 );
aWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
ContentPanel content = new ContentPanel();
aWindow.add( content );
aWindow.setVisible( true );
}
}
Panel class:
public class ContentPanel extends JPanel {
private Point p;
private Point r;
public ContentPanel () {
MouseMotionEvents mme = new MouseMotionEvents();
addMouseListener( mme );
addMouseMotionListener( mme );
}
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() ) );
}
}
}
private class MouseMotionEvents extends MouseAdapter {
public void mouseClicked ( MouseEvent me ) {
// p = me.getPoint();
// repaint();
}
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();
}
}
}