JOptionPane Infinite Loop - java

I have a program that accepts a user's mouse click and uses the coordinates of the mouse to draw a series of hexagons. I have drawn on my JPanel a red rectangle that is supposed to represent the bounds the user is allowed to click in, so to make sure the user does, I've included a warning message that pops up whenever the user clicks out of bounds. It says, "Cannot click outside red rectangle. Try again."
After the message pops up, I want the user to be able to dismiss the message and try again, but whenever the user clicks "OK" or "X" in the upper-right corner, the message appears again, and I can't seem to close the pop-up box. Is there another way I can inform the user while letting them try again?
Below is my code for a MouseListener I've implemented for my JPanel, hexPanel.
hexPanel.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
boolean clicked = false;
int left = HexDrawingPanel.iX(-rWidth/2), right = HexDrawingPanel.iX(rWidth/2);
int top = HexDrawingPanel.iY(rHeight/2), bot = HexDrawingPanel.iY(-rHeight/2);
while(!clicked) {
if(!(e.getX() > right || e.getX() < left ||
e.getY() < top || e.getY() > bot))
clicked = true;
else
JOptionPane.showMessageDialog(frame, "Must click inside red rectangle. Try again.");
}
HexDrawingPanel.radius = (float)Math.sqrt(Math.pow(e.getX() - left, 2) + Math.pow(e.getY() - top, 2));
hexPanel.repaint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
});

Your while-loop is blocking the Event Dispatching Thread, meaning that's impossible for any new mouse clicks from ever occurring...
It might be better to do something more like...
if(!(e.getX() > right || e.getX() < left ||
e.getY() < top || e.getY() > bot)) {
HexDrawingPanel.radius = (float)Math.sqrt(Math.pow(e.getX() - left, 2) + Math.pow(e.getY() - top, 2));
hexPanel.repaint();
} else
JOptionPane.showMessageDialog(frame, "Must click inside red rectangle. Try again.");
}

There are a couple of ways to do this:
You could make the listener stateful, setting a global flag before the option pane is displayed and ignoring mouse clicks until the flag is unset.
You could put a JLabel above the box and show (colored?) status messages there instead of using a dialog.

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" );
}
}

MouseEvent.Moved, detection stops working when mouse button is being pressed

I have a program that tracks the mouse with MouseEvent.MOVED in javafx and whenever i press and hold the mouse button the tracking stops.
I have tried to switch events from addEventFilter to addEventHandler. Adding another Event, MouseEvent.DRAGED. But it wont even register an event until i disable the code from MouseEvent.Moved. I have tried to combine these but nothing seems to work. Help is very much appreciated.
EventHandler<MouseEvent> tracking = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e){
double x = e.getSceneX();
double y = e.getSceneY();
if((x + size < 400) && (y - circle.getRadius() > 1)){
switch (value){
case 0 :
circle.setCenterX(x);
circle.setCenterY(y);
break;
case 1 :
rec.setLayoutX(x);
rec.setLayoutY(y);
break;
case 2 :
pol.getPoints().clear();
pol.getPoints().addAll(new Double[]{x - size, y, x + size, y, x, y + size});
break;
}
}
}
};
EventHandler<MouseEvent> test = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e){
System.out.print("test: ");
}
};
pane1.addEventHandler(MouseEvent.MOUSE_MOVED, tracking);
pane1.addEventFilter(MouseEvent.MOUSE_DRAGGED, test);
Okey i found why it diden´t work. The MouseEvent was actually being activated on the object that was tracking the mouse. So when i clicked the mouse it created a drag event on that object that woulden´t end until i released the mouse button, thanks for the help :)
edit: I still dont get why it dident work from the beginning. Shouldent the eventHandler method capture the event when it bubbles up?

How do I remove an overidden mouseListener?

I have a JInternalFrame, where I wanted to display a JOptionPane when my JTable was double clicked. I looked around in the internet and found that the only way of doing it was to override mousePressed() method and this is how I did it:
tblJobs.addMouseListener (new MouseAdapter() {
#Override
public void mousePressed (MouseEvent e) {
JTable tbl = (JTable)e.getSource();
int row = tbl.rowAtPoint(e.getPoint());
if (e.getButton() == MouseEvent.BUTTON1 && row != -1) {
if (e.getClickCount() == 2) {
JOptionPane.showMessageDialog(null, "Double click detected");
}
}
}
});
The thing is, I also have a button to hide the frame, and when the frame was hidden and re-shown, I found that upon double clicking my JTable, the JOptionPane got displayed twice. The number of times the JOptionPane got displayed seemed to increase along with the number of times I hid and show the frame. My guess is, the mouseListener got called again and again when I hide and re-show my frame. Is there a way of removing the mouseListener that was added in this way? Or is there another way to stop the JOptionPane from displaying more than once? And also, if what my code was stupid in any way, feel free to tell me! :) Thanks in advance!
How about setting a Boolean calss variable hidden = true when you hide, hidden = false when you unhide ?
Set the first line in mousePressed() to if(hidden) return;

JTextField - Moving cursor using a button

I'm really struggling to find the functionality (if it even exists),
to move a JTextFields cursor by clicking a Button, instead of using the mouse.
For instance, I have my text field with a string added.
By clicking a back button, the cursor will move back through the string, 1 position at a time or forward depending on which button is pressed.
I can do it with the mouse, just click and type, but I actually need to have it button based so that the user can choose to use the keypad to enter a name or just click into the JTextArea and type away.
Is it possible? What methods should I look for if so.
Thank you.
These are sample buttons that are doing what you're asking for:
btnMoveLeft = new JButton("-");
btnMoveLeft.setFocusable(false);
btnMoveLeft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
txtAbc.setCaretPosition(txtAbc.getCaretPosition() - 1); // move the carot one position to the left
}
});
// omitted jpanel stuff
btnmoveRight = new JButton("+");
btnmoveRight.setFocusable(false);
btnmoveRight.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
txtAbc.setCaretPosition(txtAbc.getCaretPosition() + 1); // move the carot one position to the right
}
});
// omitted jpanel stuff
They are moving the carot in the textfield txtAbc with 1 position per click. Notice, that you need to disable the focusable flag for both buttons, or the focus of your textfield will be gone if you click one of these buttons and you can't see the carot anymore.
To avoid exceptions if you're trying to move the carot out of the textfield boundaries (-1 or larger than the text length), you should check the new values (for example in dedicated methods):
private void moveLeft(int amount) {
int newPosition = txtAbc.getCaretPosition() - amount;
txtAbc.setCaretPosition(newPosition < 0 ? 0 : newPosition);
}
private void moveRight(int amount) {
int newPosition = txtAbc.getCaretPosition() + amount;
txtAbc.setCaretPosition(newPosition > txtAbc.getText().length() ? txtAbc.getText().length() : newPosition);
}

Mouse Events taking random number of clicks in 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

Categories