Right click setIcon() to mark bomb - Minesweeper - java

I am pretty new to programming and am trying to make a Minesweeper GUI. The game worked perfectly right clicking a JToggleButton displayed a "B" for bomb on the button, but when I replaced the setText() with setIcon() in the mouselistener it shows the icon when both left and right clicking occurs. I didn't have this problem when setText().
public void mousePressed(MouseEvent e){
if(e.isMetaDown())
if(btnPresses == 0)
{
startTime = System.currentTimeMillis();
btnPresses++;
}
//if(btn[y][x].getText().equals("B"))
if(btn[y][x].getIcon()==flag)
{
//btn[y][x].setText("");
btn[y][x].setIcon(null);
if(bombs[y][x]!=BOMB)
markers++;
}
else
{
//btn[y][x].setText("B");
btn[y][x].setIcon(flag);
if(bombs[y][x]==BOMB)
markers++;
else
markers--;
}
I added a btn[y][x].setIcon(null) to the actionlistener, which causes the flag icon to appear only briefly when left clicking but I'd rather it not appear at all.

You need to distinguish between a left mouse button click, MouseEvent.BUTTON3, and a right mouse button click, MouseEvent.BUTTON3, and then act accordingly. For example, when I did something like this, I set the "flag" boolean in my model (using MVC) via:
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
model.upDateButtonFlag();
}
}
The MouseListener should be used only to set or unset the flag. Otherwise you should have your JButton respond via its ActionListener for left button clicks.

Add a System.err.println("" + System.currentTimeMillis() + " " + e); to the beginning of your handler. I strongly suspect your code is being called more times than you think - as a single click can generate multiple events. Once you know what is going on, it should be easy to fix.

Related

If statement not executing during ActionPerformed event

Trying to write a Swing GUI. When clicking a button, I want to test if the other button has already been clicked. If it has, then execute the statements in the "if" statements. But it looks like the "if" statements never execute?
private void radSingleBurgerActionPerformed(java.awt.event.ActionEvent evt) {
if(radDoubleBurger.isSelected()){
newItemPrice = Double.parseDouble(lblItemPrice.getText());
newItemPrice -= doublePrice;
lblTest.setText(String.valueOf(newItemPrice));//test to see if working
}
lblItemPrice.setText(String.valueOf(newItemPrice += singlePrice));
}
private void radDoubleBurgerActionPerformed(java.awt.event.ActionEvent evt) {
if(radSingleBurger.isSelected()){
newItemPrice = Double.parseDouble(lblItemPrice.getText());
newItemPrice -= singlePrice;
lblTest.setText(String.valueOf(newItemPrice));//test to see if working
}
lblItemPrice.setText(String.valueOf(newItemPrice += doublePrice));
}
Clicking a JButton does not make it (permanently) selected. Clicking is only a temporary action.
Maybe you want to use a JToggleButton. This allows you to click a button to make it selected and then click it again to make it unselected.
Read the section from the Swing tutorial on How to Use Buttons for more information.
Or if you just want to know if the user has clicked on a regular JButton, then you will need to maintain a Boolean variable yourself that you update in the ActionListener of the button.

How to avoid to work two JButton at the same time

I'm writing a simple paint program with Java. As all paint applications there are buttons for brushTool, sprayTool, sprayTool... This tools have their own class which extends to MouseAdapter. They are working as they should. However, the problem starts when I choose a tool after choose another tool, both buttons and their ActionListeners keep executing and they do what they are written for at the same time. I mean if I choose lineTool(which draws straight line) with rectangleTool I hava a diagonal too. here is example of my two button. What I'm tring to do is stop the current action when I click another button. Can you guys help me
brushBotton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
pen = new PenTool(mainDrawArea);
mainDrawArea.addMouseListener(pen);
mainDrawArea.addMouseMotionListener(pen);
}
});
rectangleButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
shapeToolbar.setVisible(false);
rect = new RectangleTool(mainDrawArea);
rect.setStrokeSize(strokeInt);
mainDrawArea.addMouseListener(rect);
mainDrawArea.addMouseMotionListener(rect);
}
});
You can't keep adding a MouseListener to the drawing area every time you click a button.
Instead you need to keep track of the current MouseListener. Then when you click a button you need to:
remove the current MouseListener
add the new MouseListener
I would replace the button action listener for a set of Toggle Buttons in a group
https://docs.oracle.com/javase/tutorial/uiswing/components/buttongroup.html
Then you move everything in a single mouse listener.
public void mousePressed(MouseEvent e) {
this.drawingState = !this.drawingState
if ( isRightCLick(e) ) resetAllPendingOperation();
if (drawingState) {
this.startPoint = getPointFromEvent(e);
switch(toolbarGetCurrentTool()) {
case "line":
registerMouseLineListener(startPoint);//here you draw live preview
break
case "rectangle":
registerMouseRectangleListener(startPoint); //here you draw live preview
break;
}
} else {
//user clicked the second time, commit changes
//same switch as above
this.endPoint = getPointFromEvent(e);
switch(toolbarGetCurrentTool()) {
case "line":
commitLine(startPoint, endpoint);//here you draw live preview
break
case "rectangle":
commitRectangle(startPoint, endpoint); //here you draw live preview
break;
}
}
}
You are currently binding the listeners to the mainDrawArea, not setting an action for each individual button.
Note that the codes you write within actionPerformed() for each button's actionListener is the action you want to trigger everytime that button is clicked. You do not want to add a new listener to the mainDrawArea everytime we click the buttons.
You can a create a state for your current action, for example:
brushBotton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
state = BRUSH;
}
});
lineBotton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
state = LINE;
}
});
state can be an integer and BRUSH and LINE are constant such as 0 and 1.
Then in the listener (for the mainDrawArea), check the current state
switch (state){
case BRUSH: //trigger action needed for brushing;
break;
case LINE: //trigger action needed for drawing line;
break;
}

How to disable and re-enable label

In the below code, I have a label named card with a mouse click event. I only want the click event to implement once. Meaning it will implement the first time I click the label, but not the following times. How do I do this? I imagine I must disable its Listener.
private void cardMouseClicked(java.awt.event.MouseEvent evt) {
// displays backside of each flashcards when label (flashcard) is clicked
i++;
card.setText(cardB[i]);
}
I think we all would do the same.
It's really simple. Just declare a boolean then change its status when you click the first time.
boolean labelClicked = false;
private void cardMouseClicked(java.awt.event.MouseEvent evt) {
// displays backside of each flashcards when label (flashcard) is clicked
if(!labelClicked){
i++;
card.setText(cardB[i]);
labelClicked=true;
}
else{
//doNothing
}
}

Gridlayout and mouse listeners

hi i am trying to build a grid-layout GUI with mouse listener. SO when a particular cell is clicked in a grid ,information would be displayed. I don't know where to start, any help would be good
thankyou
I believe you have a class that inherits from JPanel or JFrame and there is whole GUI in it. Then, this class should implement mouseListener. Then your class should have similar code:
#override
public void mouseClicked(MouseEvent e){}
#override
public void mousePressed(MouseEvent e){}
#override
public void mouseEntered(MouseEvent e){}
#override
public void mouseReleased(MouseEvent e){
/*This method is being called when you release your click. It's better
then mouseClicked because mouseClicked is only called when you press
and release on the same pixel or Object (not sure about it)
*/
}
#override
public void mouseExiteded(MouseEvent e){}
In each method you can get source of
MouseEvent e
using
Object source = e.getSource();
if (source == button1){
//Do sth
}if (source == button2){
//Do sth else
}if (source == radioButton1){
//Do whatever you want
}
Then you have reference to the source, so you can modify what you want.
In your gridlayout, set all grids with some Component such as Button or Label. You can set listeners on the components added and display information when a component is clicked
To use properly a gridbaglayout, you should first work on the gridbagconstraints. Then, you should use the ActionListener interface to handle the mouse clicks. If the cells are of the type Labels, you coud hide the text by using myLabel.setText("") and putting the text by using myLabel.setText("information to display"). If you need more help, just ask :D and +1 if it helps ^^

mouseDragged not returning appropriate button down

How can I know the button that was pressed from within a mouseDragged event?
I'm having an issue in mouseDragged() because the received MouseEvent returns 0 for getButton(). I have no problem with the mouse location, or even detecting mouse clicks. The mouseClicked() event returns the appropriate button for getButton().
Any suggestions on how I can do this? I assume I could do a work-around using mouseClicked, or mousePressed, but I would prefer to keep this all within mouseDragged.
Thanks for your time and answers.
As pointed out in comments and other answers, SwingUtilities provides three methods for cases like this, which should work for all MouseEvents:
SwingUtilities.isLeftMouseButton(aMouseEvent);
SwingUtilities.isRightMouseButton(aMouseEvent);
SwingUtilities.isMiddleMouseButton(aMouseEvent);
As for what the problem with your approach is, the javadoc of getButton() says:
Returns which, if any, of the mouse buttons has changed state.
Since the state of the button doesn't change while it is being held down, getButton() will usually return NO_BUTTON in mouseDragged. To check the state of buttons and modifiers like Ctrl, Alt, etc. in mouseDragged, you can use getModifiersEx(). As an example, the below code checks that BUTTON1 is down but BUTTON2 is not:
int b1 = MouseEvent.BUTTON1_DOWN_MASK;
int b2 = MouseEvent.BUTTON2_DOWN_MASK;
if ((e.getModifiersEx() & (b1 | b2)) == b1) {
// ...
}
Jacob's right that getButton() doesn't get you the button by design. However, I found a cleaner solution than bit operations on getModifiersEx(), that you can also use within mouseDragged:
if (SwingUtilities.isLeftMouseButton(theMouseEvent)) {
//do something
}
Similar methods exist for the middle button and the right button.
int currentMouseButton = -1;
#Override
public void mousePressed(MouseEvent e) {
currentMouseButton = e.getButton();
}
#Override
public void mouseReleased(MouseEvent e) {
currentMouseButton = -1;
}
#Override
public void mouseDragged(MouseEvent e) {
if (currentMouseButton == 3) {
System.out.println("right button");
}
}
This could be possibly a problem of your java sandbox.
The following code works well all the time (almost, as you can see).
#Override
public void mouseDragged(MouseEvent e) {
e.getButton();
}
Please try your code on a different machine.

Categories