Home > Software engineering >  MouseListener & MouseMotionListener don't work for JPanel with JComponents inside
MouseListener & MouseMotionListener don't work for JPanel with JComponents inside

Time:09-16

I'm trying to drag JComponents which are inside a JPanel on a JFrame or better on the rootPane of the JFrame.

The JPanel which contains the components is using a horizontal BoxLayout.

When I run the code below I observed the following issues:

  1. The MouseListener & MouseMotionListener are only working for the JLabel
  2. The JLabel seems to be not visible
  3. On trying to drag, the JPanel with the JComponents inside the JTextfield & JButton disapper once I hover over the location where the JButton was dragged it becomes visible again.

What am I doing wrong here? Such a little code and so many unexpected issues.

Please help!

Code to reproduce the issues:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class Main extends JFrame implements MouseListener, MouseMotionListener {
    private volatile int screenX = 0;
    private volatile int screenY = 0;
    private volatile int myX = 0;
    private volatile int myY = 0;
    private JPanel myPane;

public Main() {
    setSize(500,500);
    myPane = new JPanel();
    //myPane.setLayout(new BoxLayout(myPane, BoxLayout.X_AXIS));

    JTextField tf = new JTextField("Some text");
    tf.setEnabled(false);
    tf.setSize(110,20);
    JLabel l = new JLabel("°C");
    l.setSize(40,20);
    JButton b = new JButton("Button");

    myPane.setSize(new Dimension(tf.getWidth() l.getWidth(), tf.getHeight()));

    myPane.add(tf);
    myPane.add(l);
    myPane.add(b);
    rootPane.add(myPane);

    myPane.addMouseListener(this);
    myPane.addMouseMotionListener(this);
}
public static void main(String[] args) {
    Main f = new Main();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mousePressed(MouseEvent e) {
    screenX = e.getXOnScreen();
    screenY = e.getYOnScreen();
    myX = myPane.getX();
    myY = myPane.getY();
}

@Override
public void mouseReleased(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {
    System.out.println("Entered");
}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mouseDragged(MouseEvent e) {
    // only move when edit mode selected
    System.out.println("Dragged");
    int deltaX = e.getXOnScreen() - screenX;
    int deltaY = e.getYOnScreen() - screenY;

    myPane.setLocation(myX   deltaX, myY   deltaY);

    revalidate();
}

@Override
public void mouseMoved(MouseEvent e) {

}
}

CodePudding user response:

Don't add components to the root pane. There are other components that will be added on top and cover your components.

The panel should be added to the content pane and the content pane needs to use a null layout when dragging components.

Read the section from the Swing tutorial on Using Top Level Containers. There is also a link that goes into more detail on the root pane. As you will see the content pane covers the root pane.

You can also check out Moving Windows the Basic Dragging section provides a simple reusable class that can be used to drag any component so you don't need to hardcode variable names in the class.

  • Related