What I am trying to do: draw a vertical line and a horizontal line that are perpendicular to each other and meet where the mouse points. A sort of cursor tracker.
My structure: JFrame -> CustomPanel -> other panels/components etc.
CustomPanel inherits from JPanel and it's set as my JFrame's ContentPane.
I tried to use a GlassPane, everything worked perfectly, but I want to keep my events, not disable them. I still want to be able to click buttons etc.
A relevant question is this Painting over the top of components in Swing?. Everything behaves as expected when I move my mouse where there are empty places in my CustomPanel, but it still doesn't paint over the other components.
In the image it should have continued painting over the button, but it stopped when I entered it and then resumed when I exited.
Code below.
public class Painter {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
JFrame frame = new JFrame();
frame.setSize(600, 600);
frame.setPreferredSize(new Dimension(600, 600));
frame.setContentPane(new CustomPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class CustomPanel extends JPanel {
int x = 0;
int y = 0;
public CustomPanel() {
addMouseListener(new AdapterImplementation(this));
addMouseMotionListener(new AdapterImplementation(this));
add(new JButton("TESTBTN"));
setSize(new Dimension(600, 600));
setPreferredSize(new Dimension(600, 600));
setVisible(true);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawLine(0, y, getWidth(), y);
g.drawLine(x, 0, x, getHeight());
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
and my adapter:
public class AdapterImplementation extends MouseAdapter {
CustomPanel pane;
public AdapterImplementation(CustomPanel pane) {
this.pane = pane;
}
@Override
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
pane.setX(x);
pane.setY(y);
pane.repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
System.out.println("MOUSE MOVED");
int x = e.getX();
int y = e.getY();
pane.setX(x);
pane.setY(y);
pane.repaint();
}
}
The problem here is that the MouseListeners
are registered with your CustomPanel
but not with the JButton
so the latter does not process events from the listeners.
Also, as you've seen, events to underlying components will be blocked when using GlassPane.
A JLayeredPane
could be used to as a topmost container to capture the MouseEvents
using your current listeners.
Note: Override paintComponent
instead of paint
for custom painting in Swing and remember to invoke super.paintComponent(g)
.