I want to create a panel that act as an overlay and react to the mouse position (Here represented by drawing a circle at the mouse position)
But when I add a mouseMotionListener to the overlay panel it stops mouse event from being received by the components under the overlay. What would be a solution for that ? I tried with dispatchEvent but it didn't create mouseEntered and mouseExited events.
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class MWE extends JFrame
{
public class LinePanel extends JPanel
{
int mouseX;
int mouseY;
public LinePanel()
{
mouseX = 100;
mouseY = 100;
this.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e)
{
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
};
});
this.setOpaque(false);
this.setLayout(null);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawOval(mouseX - 10, mouseY - 10, 20, 20);
}
}
public MWE()
{
JLayeredPane layeredPane = new JLayeredPane();
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
JButton button = new JButton("Foo");
button.addMouseListener(new MouseInputAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
super.mouseEntered(e);
button.setBackground(Color.red);
}
@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
button.setBackground(null);
}
});
button.setAlignmentX(JButton.CENTER_ALIGNMENT);
buttonPanel.add(Box.createVerticalGlue());
buttonPanel.add(button);
buttonPanel.add(Box.createVerticalGlue());
JPanel linePanel = new LinePanel();
layeredPane.add(buttonPanel, Integer.valueOf(0));
layeredPane.add(linePanel, Integer.valueOf(1));
layeredPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
buttonPanel.setBounds(layeredPane.getBounds());
linePanel.setBounds(layeredPane.getBounds());
buttonPanel.revalidate();
}
});
this.setContentPane(layeredPane);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
MWE frame = new MWE();
frame.setVisible(true);
}
}
I want to create a panel that act as an overlay and react to the mouse position (Here represented by drawing a circle at the mouse position)
But when I add a mouseMotionListener to the overlay panel it stops mouse event from being received by the components under the overlay. What would be a solution for that ? I tried with dispatchEvent but it didn't create mouseEntered and mouseExited events.
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class MWE extends JFrame
{
public class LinePanel extends JPanel
{
int mouseX;
int mouseY;
public LinePanel()
{
mouseX = 100;
mouseY = 100;
this.addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved(MouseEvent e)
{
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
};
});
this.setOpaque(false);
this.setLayout(null);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawOval(mouseX - 10, mouseY - 10, 20, 20);
}
}
public MWE()
{
JLayeredPane layeredPane = new JLayeredPane();
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
JButton button = new JButton("Foo");
button.addMouseListener(new MouseInputAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
super.mouseEntered(e);
button.setBackground(Color.red);
}
@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
button.setBackground(null);
}
});
button.setAlignmentX(JButton.CENTER_ALIGNMENT);
buttonPanel.add(Box.createVerticalGlue());
buttonPanel.add(button);
buttonPanel.add(Box.createVerticalGlue());
JPanel linePanel = new LinePanel();
layeredPane.add(buttonPanel, Integer.valueOf(0));
layeredPane.add(linePanel, Integer.valueOf(1));
layeredPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
buttonPanel.setBounds(layeredPane.getBounds());
linePanel.setBounds(layeredPane.getBounds());
buttonPanel.revalidate();
}
});
this.setContentPane(layeredPane);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
MWE frame = new MWE();
frame.setVisible(true);
}
}
Share
asked Mar 5 at 18:40
SeirynSeiryn
33 bronze badges
8
|
Show 3 more comments
1 Answer
Reset to default 1have you tried to dispatch the event inside the line panel?
linePanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
buttonPanel.dispatchEvent(SwingUtilities.convertMouseEvent(linePanel, e, buttonPanel));
}
});
redispatchMouseEvent()
in the _ GlassPaneDemo_. – trashgod Commented Mar 6 at 14:02JLayer
is designed for such use cases… – Holger Commented Mar 10 at 17:09