Mouse Events taking random number of clicks in java - java

The object of the code so far is the trade turns back and forth between player 1 and player 2 and allow the player whoose turn it is to turn one of their pieces invisible (Set icon to null). It works right now, turns trade back and forth and pieces turn invisible on click, but sometimes it is not the first click. It might take 3 or 4 clicks on a correct piece before it changes to null. Is there a reason this would be happening?
Robo2 is the icon for the first players pieces, robo1 is the icon for the second players pieces. The pieces are stored in an array of JButtons in the program with the icon set as the image of player 1 or player 2 piece.
public void mouseClicked(MouseEvent me) {
JButton clicked = (JButton)me.getSource();
if (player1) {
if (clicked.getIcon() == Robo2) {
clicked.setIcon(null);
player1 = false;
player2 = true;
}
else {
}
}
else if (player2) {
if (clicked.getIcon() == Robo1) {
clicked.setIcon(null);
player1 = true;
player2 = false;
}
else {
}
}
}

Figured out a solution, changing the mouse listener to an action listener solved the missing clicks problems. Using the events sent when the button gets clicked rather than detecting clicks themselves on the button. Thanks for the help.

when you double-click (or triple-click, or quadruple-click) something in Java you get this:
1st click: MouseEvent, clickCount = 1
2nd click: MouseEvent, clickCount = 2
3rd click: MouseEvent, clickCount = 3
etc.
so imagine you're double clicking the button by player1. The first event would change the player to player 2; the second event would change it right back to player1!
To remedy this situation - check clickCount (me.getClickCount()) and ignore the event if it isn't 1. Like
if (me.getClickCount() > 1) {
return;
}
// or else proceed as you do now

Related

Mouse cursor not changing possition after being moved

So, I am trying to make a program, and for it to start, i need the user to click on a start button, which is a square on the upper left-hand side of the screen, my way of seeing if the cursor is in the button is: checking the mouse's coordinates, seeing if those coordinates are inside the button, and reacting accordingly (starting the program or not), but, when I start the program, it just takes the mouse's coordinates and doesn't change them when i move them, so, for example, if the mouse starts on x:0 y:0, and i move it to x:100 y:100 and then click, the program thinks it's on 0,0 and doesn't do anything even though the cursor is in the button, and, as far as I can see, there's not much I can do (that's why I am asking here) The code that makes this happen is this: (the button doesn't start anything yet, it just changes the text on screen)
public class MouseHandler implements MouseListener
{
#Override
public void mouseClicked(MouseEvent e)
{
if(mX < 200 && mY < 200 && mX > 100 && mY > 100)
{
textLabel.setText("button pressed");
} else {
textLabel.setText("You're not pressing the button" );
}
}

How to keep this skip in memory GoTo Next Iteration in For Loop in java

I am wondering how can you keep this iteration in memory.
I forgot to say that player one can choose any of the five button
I was just using button 1 as a example for player 1.
this is where my problem is cause I can't figure out a way to keep this chosen button which can be any to stay disable(false) after player 2 as chosen is button.
It works if I don't disable all button after player 1 chose is, but the other 4 are enable and if player 1 press one of those button when its player 2 turns everything is mess up.
that's what I'm trying to fix. Help please.
I have 5 button for player 1 and 5 button for player 2.
Let's say button 1 is press for player 1, after its press all the other button is deactivated for player 1 and the others are activated for player 2
When player 2 press it chooses is button, all other of his is deactivated
Here is the tricky part, after player 2 press his button, player 1 button reactivate minus button 1 which was already chosen. This means only 2,3,4 and 5 are activated.
and so on. This must alternate until all 5 button was chosen.
I just can't seem to find, its the tricky part that I can't figure out.
Can anyone help me solve this or any suggestion.
Thanks.
here is the code
//The 2 first for loop are for just showing the 10 buttons
for(int i=0;i<5;i++)
{
x=100*i;
jbChoixJun[i]=new JButton(String.valueOf("Choisir"));
jbChoixJun[i].setBounds(x+30,160,80,30);
add(jbChoixJun[i]);
jbChoixJun[i].addActionListener(this);
jbChoixJun[i].setEnabled(false);
}
for(int i=0;i<5;i++)
{
x=100*i;
jbChoixJdeux[i]=new JButton(String.valueOf("Choisir"));
jbChoixJdeux[i].setBounds(x+30,390,80,30);
add(jbChoixJdeux[i]);
jbChoixJdeux[i].addActionListener(this);
jbChoixJdeux[i].setEnabled(false);
}
//The next 2 for loop, when the player its the button it becomes false and
// stay false until the end, this works ok
for(i=0;i<5;i++)
{
if(source==jbChoixJun[i])
{
mainJoueur1.getCarte(compteurI1);
jbChoixJun[i].setEnabled(false);
compteur1=1;
compteurI1=i;
comparaison1=true;
System.out.println("compteur des images");
System.out.println("compteurI1="+compteurI1);
comparaisonBataille1=true;
}
//This turn all button off after the player chose is
if(jbChoixJun[compteurI1].isEnabled()==false)
jbChoixJun[i].setEnabled(false);
}
for(int i=0;i<5;i++)
{
if(source==jbChoixJdeux[i])
{
mainJoueur2.getCarte(compteurI2);
jbChoixJdeux[i].setEnabled(false);
compteur2=1;
compteurI2=i;
comparaison2=true;
comparaisonBataille2=true;
jbChoixJun[compteurI1].setEnabled(false);
}
if(jbChoixJdeux[compteurI1].isEnabled()==false)
jbChoixJdeux[i].setEnabled(false);
if(i==compteurI1)
continue;
else
jbChoixJun[i].setEnabled(true);
The problem, is that the first button chosen by player comes active and only the second one that becomes disable.
Can of hard to explain
Hope you guys can help me
As asked by the OP here is how you can extend JButton and use it according to your needs by adding new properties, this gives you more flexibility
public class ExtendedJButton extends JButton{
private static final long serialVersionUID = 1L;
/**
* We use this boolean for some case and set it to true or false according to out need
*/
private boolean someCheck;
//Add more propterties according to your need and create conditions to enable and disable them accordingly
public boolean isSomeCheck() {
return someCheck;
}
public void setSomeCheck(boolean someCheck) {
this.someCheck = someCheck;
}
public static void main(String[] args) {
JFrame frameForExample = new JFrame();
ExtendedJButton button = new ExtendedJButton();
frameForExample.add(button);
//Now you can access properties of JButton class as well as new properties of your extended class
button.setEnabled(false);
////.........
//An example case
if(button.isSomeCheck()){
//Do what you want to
//if you want to disable the button when this case is true do it,
}
}
This is not an answer but more a guidance on how you can proceed.

JButton already selected when window loads - infinite loop

I have an array of JButtons which are displayed on a window when it is loaded up.
For some reason, when the window loads, the first button seems to be already selected and so puts my programme into an infinite loop.
I know that to stop this infinite loop I should change the condition in my while(true) loop, but am unsure what conditions to put in.
So I thought another way round would be to figure out why one of the buttons is already selected.
actionPerformed method - this gets the name of the button selected which I made to be a string to represent co-ordinates. It then turns the co-ordinates into integers which can be obtained by the HumanPlayer class with the getXInt and getYInt methods. The board and pieces are already set up in other classes, I know it all works because i've already created a text version, this is now the GUI version I am working on.
It's just a case of enabling the user to select a button without the while(true) loop getting stuck.
The Screen class:
public void actionPerformed(ActionEvent e) {
JButton piece = (JButton) e.getSource();
String xy = piece.getName();
String x = xy.substring(0,1);
String y = xy.substring(2,3);
xInt = Integer.parseInt(x);
yInt = Integer.parseInt(y);
}
public int getXInt() {
return xInt;
}
public int getYInt() {
return yInt;
}
HumanPlayer class which gets the information of the piece selected and checks whether it can be moved.
//Sets up new instance of Screen class which is where the window displaying the buttons is set up (this contains the getXInt and getYInt methods are- so the HumanPlayer class can retrieve the piece which has been selected.
Screen s = new Screen(board);
public boolean makeMove() {
int fromXCo , fromYCo, toXCo, toYCo;
Piece p;
ArrayList<Move> moves = null;
while (true){
//reads x and y co-ordinate
System.out.println("Click on a piece to move");
//takes information from which button is clicked from other class
fromXCo = s.getXInt();
fromYCo = s.getYInt();
p = board.getPiece(fromXCo, fromYCo);
System.out.println("Your selected piece is " + p.getChar());
//looks through available moves for piece
moves = p.availableMoves();
//if no moves available, asks for new co-ordinates.
if (moves == null)
{
System.out.println("No moves available for this piece \n");
continue;
}
break;
}
So the output is a continuous:
Click on a piece to move
Your selected piece is r
There are no available moves for this piece...

LWJGL: detecting left/right clicks when getButtonCount returns 0

On the Dell Inspiron 15 3000, the touchpad doesn't have any physical left/right buttons. Instead, it is one giant touchpad that is pressure sensitive. I'm assuming it detects right/left clicks based off of hand position on the trackpad.
In my LWJGL application, I detect mouse button clicks with Mouse.isButtonDown(0). This works fine on computers with a mouse with physical buttons, but doesn't work on touchpads that lack physical buttons. Mouse.getButtonCount() returns 0.
Has anybody had any success in detecting if a mouse button is pressed, should the user be using a trackpad that doesn't have physical buttons?
I think, instead of using
org.lwjgl.input.Mouse
This class could be what you are searching for:
org.lwjgl.input.Controllers
http://legacy.lwjgl.org/javadoc/org/lwjgl/input/Controllers.html
Im not entirely sure though since I only have a mouse and no way to test this with a touchpad.
For those who find this in the future, I did find a fix:
You cannot, should there be no physical buttons, use the Mouse.isButtonDown() method. Instead, you are going to have to read the event buffer. To do so, I wrote my own helper class:
public class Mouse{
private static boolean button_left = false, button_right = false;
public static boolean isButtonDown(int button){
if(button == 0) return button_left;
if(button == 1) return button_right;
return false;
}
public static void update(){
while(org.lwjgl.input.Mouse.next()){
if(org.lwjgl.input.Mouse.getEventButton() == 0) button_left = org.lwjgl.input.Mouse.getEventButtonState();
if(org.lwjgl.input.Mouse.getEventButton() == 1) button_right = org.lwjgl.input.Mouse.getEventButtonState();
}
}
}
The update() method is called every tick, and as such I can get button states using Mouse.isButtonDown(button).

How to detect if two mouse buttons were released at the same time?

I am implementing minesweeper and I have a little problem with handling mouse events. I want actions to take place on mouseRelease (not mousePressed), so the user can change his mind after pressing a mouse button. There are three possible actions:
LMB released - reveal current field
RMB released - put a flag in current field
both LMB and RMB released - highlight or reveal adjacent fields
Actions are not really important, what I have problem with is how to trigger them.
In cases 1 and 2 no others buttons are down - this is easy to check.
The problem is that releasing both buttons results in two calls of mouseRelease method. If there is too large delay between both buttons releases I would prefer not to trigger an action. In other words, it should trigger only if both buttons were released at about the same time.
I can easily check that e.g. button 3 is down when button 1 is released, however it is not really helpful.
At the moment I have no other idea then storing a time when first button was released and then comparing it against the time when another button is released - and if the difference is small enough, trigger an action.
I do not really like an idea of playing with System.currentTimeMillis() or System.nanoTime() and I wonder whether there is a better way of doing it?
SOLUTION:
What has extremely simplified the problem was not allowing the user to drag a mouse pointer to another field (and hence changing the "selected" field). Delay between releasing both buttons does not matter. If the mouse pointer goes to another field, everything is cleared. Here is the code snippet:
private static final int B1DM = MouseEvent.BUTTON1_DOWN_MASK;
private static final int B3DM = MouseEvent.BUTTON3_DOWN_MASK;
private boolean bothWereDown = false;
#Override
public void mousePressed(MouseEvent e) {
// action if single button pressed
// in my case this is a sub-action of pressing both buttons
int both = B1DM | B3DM;
bothWereDown = (e.getModifiersEx() & both) == both;
if (bothWereDown) {
// action if both buttons pressed
}
}
#Override
public void mouseDragged(MouseEvent e) {
// some other code
if ( /* if pointer leaves field where mouse was pressed */) {
// some other code
bothWereDown = false;
// some other code
}
}
#Override
public void mouseReleased(MouseEvent e) {
// some other code
if (e.getButton() == MouseEvent.BUTTON1) {
if (bothWereDown) {
if ((e.getModifiersEx() & B3DM) != B3DM) {
// action if both released
}
} else {
// action if left button released
}
} else if (e.getButton() == MouseEvent.BUTTON3) {
if (bothWereDown) {
if ((e.getModifiersEx() & B1DM) != B1DM) {
// action if both released
}
} else {
// action if right button released
}
}
}
Obvious solution is to also track mouse presses. No need to play around with timeouts in this case, I think.
So pressing both buttons, then releasing one, will not count as release of single button. In fact, in your case, it would probably do nothing. Only when also other mouse button gets released, that will then count as releasing both buttons.
Edit: Actually, you do not even need to track mouse presses, though you probably want to give visual indication that button is pressed, and releasing it will have an effect. But when button is released, and you detect other is still pressed, just set a flag that half of two button release has happened, and single release of one button will then complete it. If flag is not set on single button release, then it's not part of two button action, and you do the single button release action instead.

Categories