Delfino
Delfino

Reputation: 1009

JOptionPane Infinite Loop

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

Upvotes: 0

Views: 750

Answers (2)

ThrawnCA
ThrawnCA

Reputation: 1081

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.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347294

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

Upvotes: 2

Related Questions