0

Before you read this I just want to say that any help would help me very much, right now. I'm very desperate. I've spent at least a week trying to get this work in Eclipse, I think I'm missing something obvious, I really need your help.

Right now my mouse listener contains if-statements for each 'room' and a double for-loop within those if-statements that tells the JFrame if the mouse is clicked within a certain region of the JFrame to repaint the corresponding 'room'.

Now let's say room #4 can lead to either #5 or #6. Going from #4 > #6 shows no issues. Now from #5 > #4 there is a problem. For some reason the event regions for room #4 show up in #5 (it should not) so now I can go to either #4 or #6 when I click on previous event regions.

I've tried this for other 'rooms' and the issue doesn't appear in them. I've concluded that it might have to do something with going back and forward between rooms that are connected with more than one path. I've attached a visual pathway and the isolated code to make things easier (The numbers are just the room #'s).

MouseAdapter mouseHandler = new MouseAdapter()
      {
          public void mouseClicked(MouseEvent e)
          {
             //System.out.println(e.getPoint());
            if(n==6)//R6
             {
                for(int i = 116;i<132;i++)//3a
              {
                  if(e.getX() == i)
                  {
                      for(int j = 388;j<404;j++)
                      {
                          if(e.getY() == j)
                          {
                            n = 7;//3b
                              return;
                          }
                      }
                  }
              }
                 for(int i = 116;i<132;i++)//2b
                  {
                      if(e.getX() == i)
                      {
                          for(int j = 308;j<324;j++)
                          {
                              if(e.getY() == j)
                              {
                                 n = 4;//2a
                                  return;
                              }
                          }
                      }
                  }
                 for(int i = 580;i<596;i++)//8a
              {
                  if(e.getX() == i)
                  {
                      for(int j = 372;j<388;j++)
                      {
                          if(e.getY() == j)
                          {
                             n = 2;//8b
                              return;
                          }
                      }
                  }
              }
             }
            if(n==5)//R5
             {
                 for(int i = 220;i<268;i++)//1b
                  {
                      if(e.getX() == i)
                      {
                          for(int j = 437;j<485;j++)
                          {
                              if(e.getY() == j)
                              {
                                  n = 4;//1a
                                  return;
                              }
                          }
                      }
                  }
             }
            if(n==4)//R4
             {
                 for(int i = 179;i<244;i++)//2a
                  {
                      if(e.getX() == i)
                      {
                          for(int j = 403;j<468;j++)
                          {
                              if(e.getY() == j)
                              {
                                 n = 6;//2b
                                  return;
                              }
                          }
                      }
                  }
                 for(int i = 436;i<500;i++)//1a
                      {
                          if(e.getX() == i)
                          {
                              for(int j = 403;j<468;j++)
                              {
                                  if(e.getY() == j)
                                  {
                                     n = 5;//1b
                                      return;
                                  }
                              }
                          }
                      }
                 for(int i = 274;i<406;i++)//A2
                  {
                      if(e.getX() == i)
                      {
                          for(int j = 193;j<276;j++)
                          {
                              if(e.getY() == j)
                              {
                                  n = 0;//A1
                                  return;
                              }
                          }
                      }
                  }
             }
            if(n==0)//R0
             {
                 for(int i = 459;i<493;i++)//A1
              {
                  if(e.getX() == i)
                  {
                      for(int j = 110;j<133;j++)
                      {
                          if(e.getY() == j)
                          {
                              n = 4;//A2
                              return;
                          }
                      }
                  }
              }
             }
            repaint();
             //http://stackoverflow.com/questions/5654208/making-a-jbutton-invisible-but-clickable
          }
          public void mouseMoved(MouseEvent e)
          {
              // = e.getPoint();
              //repaint();
          }
      };

      addMouseMotionListener(mouseHandler);
      addMouseListener(mouseHandler);

enter image description here

SelfDeceit
  • 107
  • 1
  • 2
  • 13
  • 2
    You've got a bug in your code. How we can help you is beyond me since you don't show any code. I know we're smart, but not that smart. – Hovercraft Full Of Eels Apr 08 '13 at 01:55
  • 1
    Give me a second, I'll add the code quickly. EDIT: Okay, I've added, it would help me a lot if you could see what I'm doing wrong. – SelfDeceit Apr 08 '13 at 01:56
  • 2
    Before posting code you should do some *serious* debugging. I would either use a debugger or `println(...)` statements that show the state of your program's variables in an attempt to try to find out why things are not working right. Else you could be posting code that has no relevance to your problem. – Hovercraft Full Of Eels Apr 08 '13 at 01:59
  • I've isolated the problem manually, I'm 98% sure that the problem relies in the mouse listener as this is where all the connections between the images rely in. – SelfDeceit Apr 08 '13 at 02:01
  • 3
    Let me introduce you to my friend [`Rectangle`](http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html) and it's wounderful method [`contains`](http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html#contains%28java.awt.Point%29) which would reduce your loops and ifs down to a few lines... – MadProgrammer Apr 08 '13 at 02:02
  • @MadProgrammer: you posted this as I was typing... arg! beaten by a comment! – Hovercraft Full Of Eels Apr 08 '13 at 02:02

2 Answers2

4

This is designed to demonstrate the use of Rectangle and a self contained concept of a Room.

Each Room can have 1 or more exists, each exit leads to another room. This is essentially a type of linked list.

The Rectangle for position for each is calculated dynamically, making easier to render and control. This example basically will only show the active room and it's connected rooms. Each time you click on a room, that room becomes the active room (in the center) and renders it's linked exists.

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Rooms {

    public static void main(String[] args) {
        new Rooms();
    }

    public Rooms() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new RoomsPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RoomsPane extends JPanel {

        private Room currentRoom;

        public RoomsPane() {

            currentRoom = new Room("0", new Dimension(100, 100), null, null);
            currentRoom.addExit(ExitPoint.East, createRoom(1, currentRoom, ExitPoint.West));

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (getBounds(currentRoom).contains(e.getPoint())) {
                        // current room
                    } else {
                        for (Room room : currentRoom.getRooms()) {
                            if (getBounds(room).contains(e.getPoint())) {
                                currentRoom = room;
                                repaint();
                                break;
                            }
                        }
                    }
                }
            });

        }

        protected boolean chance() {
            return Math.round(Math.random() * 1) == 0 ? false : true;
        }

        public Room createRoom(int count, Room parent, ExitPoint entryPoint) {
            int width = (int) Math.round(Math.random() * 90) + 10;
            int height = (int) Math.round(Math.random() * 90) + 10;
            Room room = new Room(String.valueOf(count), new Dimension(width, height), parent, entryPoint);
            if (count < 10) {
                count++;

                if (chance() && !room.hasExit(ExitPoint.North)) {
                    room.addExit(ExitPoint.North, createRoom(count, room, ExitPoint.South));
                }
                if (chance() && !room.hasExit(ExitPoint.East)) {
                    room.addExit(ExitPoint.East, createRoom(count, room, ExitPoint.West));
                }
                if (chance() && !room.hasExit(ExitPoint.South)) {
                    room.addExit(ExitPoint.South, createRoom(count, room, ExitPoint.North));
                }
                if (chance() && !room.hasExit(ExitPoint.West)) {
                    room.addExit(ExitPoint.West, createRoom(count, room, ExitPoint.West));
                }

            }
            return room;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public Rectangle getBounds(Room room) {

            Rectangle bounds = null;
            // Can't get the bounds for a room not linked to current room
            if (currentRoom.isLinkedTo(room) || currentRoom == room) {
                Dimension size = currentRoom.getSize();
                int width = getWidth() - 1;
                int height = getHeight() - 1;
                int x = (width - size.width) / 2;
                int y = (height - size.height) / 2;
                if (currentRoom != room) {

                    switch (currentRoom.getExit(room)) {
                        case North:
                            y -= room.getSize().height;
                            x = (width - room.getSize().width) / 2;
                            break;
                        case South:
                            y += size.height;
                            x = (width - room.getSize().width) / 2;
                            break;
                        case East:
                            x += size.width;
                            y = (height - room.getSize().height) / 2;
                            break;
                        case West:
                            x -= room.getSize().width;
                            y = (height - room.getSize().height) / 2;
                            break;
                    }

                    size = room.getSize();

                }
                bounds = new Rectangle(x, y, size.width, size.height);
            }
            return bounds;

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            FontMetrics fm = g2d.getFontMetrics();

            g2d.setColor(Color.GRAY);
            for (Room room : currentRoom.getRooms()) {
                Rectangle bounds = getBounds(room);
                g2d.draw(bounds);
                g2d.drawString(
                        room.getName(),
                        bounds.x + ((bounds.width - fm.stringWidth(room.getName())) / 2),
                        bounds.y + ((bounds.height - fm.getHeight()) / 2) + fm.getAscent());
            }

            Rectangle bounds = getBounds(currentRoom);
            g2d.setColor(Color.BLUE);
            g2d.draw(bounds);
            g2d.drawString(
                    currentRoom.getName(),
                    bounds.x + ((bounds.width - fm.stringWidth(currentRoom.getName())) / 2),
                    bounds.y + ((bounds.height - fm.getHeight()) / 2) + fm.getAscent());

            g2d.dispose();
        }
    }

    public enum ExitPoint {

        North,
        South,
        East,
        West
    }

    public class Room {

        private Dimension size;
        private Map<ExitPoint, Room> exists;
        private String name;

        public Room(String name, Dimension dim, Room parent, ExitPoint entryPoint) {
            size = new Dimension(dim);
            exists = new HashMap<>(4);
            this.name = name;
            if (parent != null) {
                addExit(entryPoint, parent);
            }
        }

        public String getName() {
            return name;
        }

        public Dimension getSize() {
            return size;
        }

        public void addExit(ExitPoint point, Room room) {
            exists.put(point, room);
        }

        public boolean isLinkedTo(Room room) {
            return exists.values().contains(room);
        }

        public Room[] getRooms() {
            return exists.values().toArray(new Room[exists.size()]);
        }

        public boolean hasExit(ExitPoint ep) {
            return exists.containsKey(ep);
        }

        public ExitPoint getExit(Room room) {
            ExitPoint ep = null;
            for (ExitPoint exit : exists.keySet()) {
                if (exists.get(exit) == room) {
                    ep = exit;
                    break;
                }
            }
            return ep;
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
3

You appear to be trying to see if the mouse has clicked inside of a region and you appear to be trying to do this with nested for loops. Don't use for loops for this purpose. Instead use if blocks. Simplest would be to create Rectangles and see if the Mouse has clicked inside of it using its contains(Point p) method.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • @MadProgrammer: yeah, but you'll probably create and post some beautiful code. And that's a good thing. – Hovercraft Full Of Eels Apr 08 '13 at 02:04
  • I took one look at the if/loops and quickly closed the tab ;) – MadProgrammer Apr 08 '13 at 02:05
  • Is it possible to 'disable' the Rectangles after a new image has been repainted? This way there won't be overlapping Rectangles that would lead the user to different rooms. – SelfDeceit Apr 08 '13 at 02:05
  • @SelfDeceit That would be up to you. You could maintain the `Rectangle` as part of a room class that had the ability to "hide" each one as required – MadProgrammer Apr 08 '13 at 02:06
  • @SelfDeceit I'd basically create a `Room` class that had 4 slots (one for each edge) which had links to the next room (if available). That way you would be able to easily check in what direction the user can move... – MadProgrammer Apr 08 '13 at 02:08
  • I'm fairly new to Swing, that's why I was using for-loops because they only showed up upon a repaint and the program knows that. Is there a simpler way to hide it rather than adding more classes? EDIT: The game is just mouse input so I don't think direction would matter. What the user clicks are these portals that are drawn in the image. Are these rectangles translucent btw? – SelfDeceit Apr 08 '13 at 02:09