I'm trying to make minesweeper with a basic GUI as a summer project and want to be able to shade the surrounding tiles when you click and hold a tile using Java Swing's MouseAdapter
@Override
public void mousePressed(MouseEvent e){ // shades surrounding tiles
for (int rowOff = tileLoc.row() - 1; rowOff < tileLoc.row() 2; rowOff ) {
for (int colOff = (tileLoc.col() - 1); colOff < tileLoc.col() 2; colOff ) {
// TODO add validTile()
allTiles[rowOff][colOff].setBackground(Color.GRAY);
}
}
}
@override
public void mouseReleased(MouseEvent e){
// undoes shading & clicks tile
}
(TileLoc is a Record with 2 values, row and col)
This code works the way I want it to but the issue is that it's also getting called on the mouseClicked()
@Override
public void mouseClicked(MouseEvent e){ // 1 is left click, 3 is right click
switch (e.getButton()){
case 1:
//does board.leftClick()
case 3:
//does board.rightClick()
break;
default:
break;
}
}
How can I make the mouseClicked() not shade and unshade the tiles?
CodePudding user response:
The best way to do this is with a timer variable. When the mouse is pressed save the current time to a class variable pressedTime = System.currentTimeMillis();
:
long pressedTime = -1;
public void mousePressed(MouseEvent e){ // shades surrounding tiles
pressedTime = System.currentTimeMillis();
//Your code here...
//...
}
Now we can change the behaviour of the mouseReleased and mouseClicked methods to account for this timer, and take action accordingly:
@override
public void mouseReleased(MouseEvent e){
//Find the time difference
long timeDifference = System.currentTimeMillis() - pressedTime;
//If the held time is long enough do the held action
if(timeDifferenec > yourRequiredTime){
//Do something
}
//Else if the click was shorter than your hold time then manage your click like normal:
else{
switch (e.getButton()){
case 1:
//does board.leftClick()
case 3:
//does board.rightClick()
break;
default:
break;
}
}
//Do nothing in the mouseClicked event, we can manage this entirely in the mouse released event
public void mouseClicked(MouseEvent e){
//Nothing here
}
Note that depending on the situation that you use this in, and if you share the variable with multiple functions/buttons, then you might want to reset the value of pressedTime
to -1 after clicks, and check for a -1 value before taking any actions.
CodePudding user response:
A mouseclick consists of pressing and releasing the button on the same location. You want to react on mouseclicked - at this point in time you do not know when the user releases the button.
So make up your mind: Do you want to react immediately? I think that's what you already have. Do you want to react delayed? (That's what sorifiend suggests.) And what happens if the user releases the button after a long time but at the same location: Was that a slow click, or does it mean something different?
All solutions work to the requirement that the adjoining fields are highlighted when the user presses the mouse button.