This question is to help me solve my other question. I have a JPanel
that is completely covered by JLabels
. I have added a MotionListener
to the panel but it is never called since the labels are in the way. If I remove the labels my MotionnListener is called properly.
Is there a way I can have the covered panel see the motion events?
public class ChangesAttempt extends JPanel {
private static final long serialVersionUID = -8031881678612431401L;
static JFrame frame;
static JPanel grid;
static JLabel[][] squares;
static boolean[][] litSquares;
static int size, boardSize;
MouseEvent listener = new MouseEvent();
MotionListener mListerner = new MotionListener();
Color backGround = Color.BLUE;
Color selected = Color.PINK;
public ChangesAttempt(int size) {
ChangesAttempt.size = size;
squares = new JLabel[size][size];
litSquares = new boolean[size][size];
grid = new JPanel(new GridLayout(size, size));
grid.addMouseMotionListener(mListerner);
/*Coment out setBoard(); below to see the mousedDragged method actually being called
since the JLabels will not be in the way.*/
setBoard();
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(grid, BorderLayout.CENTER);
frame.setTitle("ChangedLife");
if (25 * size < 525)
boardSize = 525;
else
boardSize = 25 * size;
frame.setSize(boardSize, boardSize);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class MouseEvent implements MouseListener {
@Override
public void mousePressed(java.awt.event.MouseEvent e) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (e.getSource() == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
}
@Override
public void mouseEntered(java.awt.event.MouseEvent e) {
}
@Override
public void mouseExited(java.awt.event.MouseEvent e) {
}
@Override
public void mouseReleased(java.awt.event.MouseEvent e) {
}
}
class MotionListener implements MouseMotionListener {
@Override
public void mouseDragged(java.awt.event.MouseEvent e) {
Point p = e.getPoint();
System.out.println("mouse Dragged to " + p);
}
@Override
public void mouseMoved(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub
}
}
public void setBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
squares[i][j] = new JLabel();
squares[i][j].addMouseListener(listener);
squares[i][j].setOpaque(true);
squares[i][j].setBackground(backGround);
grid.add(squares[i][j]);
}
}
}
class MyLabel extends JLabel {
private static final long serialVersionUID = -1414933339546989142L;
}
public static void main(String args[]) {
new ChangesAttempt(20);
}
}
There's no "easy" way to achieve this, it might be better to move all you mouse listeners to the panel instead.
This would require you to look up the component (that's within the parent component) at the specified click point, for example...
@Override
public void mousePressed(java.awt.event.MouseEvent e) {
Component component = e.getComponent();
Component source = component.getComponentAt(e.getPoint());
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (source == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}
This will work, if you remove the MouseListener
from the labels and instead, add it to the grid
, allowing with your MouseMotionListener