So my latest project is an adaption of Conway's Game of Life, which I've successfully knocked together in an hour or two.
For drawing the "pixels" on the grid I use a MouseAdapter which the custom panel listens to.
Wouldn't life be great if this just worked?
But what I'm finding is that if I'm selecting squares and the mouse moves even the tiniest amount, which happens quite a lot if I'm trying to draw a line quickly, for example, the click doesn't register. I suppose this is because Swing now considers this a "drag" event.
Now what would be quite good would be if I could actually draw a line by dragging the mouse from one square to another. So I try:and don't expect this to work properly, because multiple mouseDragged events would toggle the square repeatedly. However when I tried it, dragging the mouse doesn't seem to do anything at all. I debugged and mouseDragged is never entered... even when I most definitely drag my mouse over the panel... not sure why?
Anyway, can anyone think of a good solution to this, i.e. getting the application to interpret mini-drags as clicks?
EDIT to say: good heavens! This is on the front page of Google search for "swing mousedragged" already!
mouseDragged does not come from MouseListener but from MouseMotionListener. You'll need to add your listener class twice, once using addMouseListener and once using addMouseMotionListener.
A possible different approach may be to not use a panel to draw on but use a grid (using GridLayout) of JLabels. These need their opacity to be set correctly. You can then add a MouseListener to each JLabel, and listen to the mouseEntered event. Check if the mouse button is pressed or you're also going to catch mouse movements without the mouse pressed.
Thanks Rob, that did the trick for recognizing drags.
I've changed my listener class so that dragging works as you might expect, i.e. only changes state if this square hasn't just been changed (prevents repeated toggling), and if you're changing to the same state as the first click (prevents erasing lines you cross, or drawing if you're erasing). Maybe not the most elegant but seems to work:
A mouseClicked event is generated when a mousePressed and mouseReleased event is generated at the same location. So I would suggest you only need to handle either mousePressed or mouseReleased and not worry about dragging of the mouse. This way only one square is toggled at a time event if the mouse moves a pixel by mistake.
Yeah, I sort of realised that after posting, but actually I've found being able to drag is a great benefit in this application. It's great fun setting it going and adding lines in while it's running. If you just add individual squares they disappear within an iteration.
Here's source code if anyone's interested (still a work in progress - thinking of adding serialization and preset shapes you can drag in, like the ones shown on Wikipedia)