Results 1 to 8 of 8
  1. #1
    Zambash is offline Member
    Join Date
    Aug 2011
    Posts
    6
    Rep Power
    0

    Default Retrieving mouse location inside a thread relative to an external JPanel.

    Okay guys, so here is my problem, I am using making an object follow the mouse, but only when the mouse is pressed, then stop following the mouse when it is released. To do this I of course had to use a separate thread for the movement so the main thread could track when the mouse is released and then stop the separate thread. My problem however, is that I want the movement thread to use coordinates based on the JPanel that the main thread is running, but I don't know how to pass that info on. Right now I am using MouseInfo in the separate thread, but this is only good for finding the mouse location on your whole screen, rather than just within your frame/panel. For example, I want to make it so when my side thread is moving the object, it treats the coordinate 0,0 as the top left corner of the panel that am using, rather than the top left corner of my monitor. So I am wondering if anyone knows a way to pass on the panel info to the side-thread so that it can correctly place the object on the mouse based on where the mouse is in the panel.

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,883
    Rep Power
    25

    Default

    What is contained in the MouseEvent object?

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Zambash View Post
    I am using making an object follow the mouse, but only when the mouse is pressed, then stop following the mouse when it is released. To do this I of course had to use a separate thread for the movement so the main thread could track when the mouse is released and then stop the separate thread.
    So far all you've described should be in one and the same thread, the Swing event dispatch thread or EDT. You have not justified need for more than one thread, and so far it would seem dangerous to try to to this in this situation (of course this recommendation could change if you give us a valid justification).

    My problem however, is that I want the movement thread to use coordinates based on the JPanel that the main thread is running, but I don't know how to pass that info on.
    This statement is very confusing -- can you please clarify this?


    Right now I am using MouseInfo in the separate thread, but this is only good for finding the mouse location on your whole screen, rather than just within your frame/panel. For example, I want to make it so when my side thread is moving the object, it treats the coordinate 0,0 as the top left corner of the panel that am using, rather than the top left corner of my monitor. So I am wondering if anyone knows a way to pass on the panel info to the side-thread so that it can correctly place the object on the mouse based on where the mouse is in the panel.
    Again, this is very confusing, and again I see nothing above justifying the use of multiple threads. Please provide us with more pertinent details and best of all a small working program that demonstrates compiles, runs, and your problem and has no code unrelated to the problem, an SSCCE.

  4. #4
    Zambash is offline Member
    Join Date
    Aug 2011
    Posts
    6
    Rep Power
    0

    Default

    Here is what I am working on:
    Java Code:
    public class Panel extends JPanel implements MouseListener, MouseMotionListener {
    
        private ImageIcon axe;
        private JLabel axeLabel;
        boolean MousePressed = false;
        AxeThread tester;
        
        public Panel()
        {
            axe = new ImageIcon(getClass().getResource("ThrowingAxe.gif"));
            axeLabel = new JLabel(axe);
            axeLabel.setSize(75, 75);
            addMouseListener(this);
            addMouseMotionListener(this);
            this.add(axeLabel);
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
            tester = new AxeThread();
            tester.start();
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            tester.interrupt();
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            
        }
    
        @Override
        public void mouseMoved(MouseEvent e) {
            
        }
    
        public class AxeThread extends Thread {
    
            @Override
            public void run()
            {
                while(true)
                {
                    
                   axeLabel.setLocation(MouseInfo.getPointerInfo().getLocation());
                   if(this.isInterrupted())
                   {
                       return;
                   }
                }
            }
        }
    }
    This is just a very simple test idea I am working on, because I am going to make a game and I need to work some stuff out before I jump into that.

    So, this code makes it so when you press your mouse button down, the JLabel follows your mouse around as you move it, then when you release the mouse button, it stops following the mouse.

    The problem is that, as you can see, I am using MouseInfo in my second thread, so the mouse is way off because it is using coordinates relative to the whole screen rather than coordinates relative to the panel that the label is in.

    I am wondering how to get the coordinates that I would get if I did e.getX() or e.getY() inside one of my MouseListener methods, and pass those coordinates into the thread that actually does the moving of the label.

    You said there may be a way to accomplish what I am doing without even making another thread, which would eliminate the problem of coordinates all together, and I would love to know how! However, in my game I will need to use threads because I will have lots of axes flying across the screen using different time delays, so they can't be in the same thread. So I would like to know how to deal with mouse press/release events with and without the use of another thread.

    I hope it was a little more clear this time.

    EDIT: Okay I found out I could do what I wanted in this little test just by putting a axeLabel.setLocation(e.getX(0),e.getY()) in the mouse dragged listener, so I guess that was the easy way. But the problem still stands that in my game I will have lots of flying from someone who is throwing them, so I will need to at the very least be able to pass the coordinate where the player was standing when they threw the axe so I can determine how far the axe will go, and for this I will need to pass coordinates within my JPanel into multiple threads. So how would I do that?

    EDIT AGAIN: What I am trying to explain is hard to express in words and I think I may still be being vague, so I made a picture:

    The whole white area is my computer screen, and the red area is my panel. To my panel, point #2 is the coordinate (0,0), but to my other thread point #1 is the coordinate (0,0). My question is how can I get my thread to see point #2 as (0,0) like my panel does?
    Last edited by Zambash; 08-25-2011 at 03:21 AM.

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    I would simply use the mouse listener / motion listener that you have, and again, do not see the need for threads as yet. For e.g.,

    Java Code:
    import java.awt.Dimension;
    import java.awt.Point;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    import javax.swing.*;
    
    public class ZambashPanel extends JPanel {
       private static final String AXE_IMAGE_URL = "http://upload.wikimedia.org/wikipedia/commons/" +
       		"thumb/b/b2/Hatchet_firefighter.png/120px-Hatchet_firefighter.png";
       private static final int ZP_WIDTH = 400;
       private static final int ZP_HEIGHT = ZP_WIDTH;
       private JLabel axeLabel = new JLabel();
       boolean MousePressed = false;
       AxeThread tester = new AxeThread(this);
    
       public ZambashPanel() {
          super(null);
          try {
             URL imageUrl = new URL(AXE_IMAGE_URL);
             BufferedImage image = ImageIO.read(imageUrl);
             ImageIcon icon = new ImageIcon(image);
             axeLabel.setIcon(icon);
          } catch (MalformedURLException e) {
             e.printStackTrace();
          } catch (IOException e) {
             e.printStackTrace();
          }
          axeLabel.setSize(axeLabel.getPreferredSize());
          axeLabel.setLocation(-1000, -1000);
          MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
          addMouseListener(myMouseAdapter);
          addMouseMotionListener(myMouseAdapter);
          this.add(axeLabel);
       }
       
       @Override
       public Dimension getPreferredSize() {
          return new Dimension(ZP_WIDTH, ZP_HEIGHT);
       }
       
       public void setAxeLocation(Point p) {
          p.x = p.x - axeLabel.getWidth()/2;
          p.y = p.y - axeLabel.getHeight()/2;
          axeLabel.setLocation(p);
          repaint();
       }
    
       private class MyMouseAdapter extends MouseAdapter {
          @Override
          public void mousePressed(MouseEvent e) {
             tester.start(e.getPoint());
          }
    
          @Override
          public void mouseReleased(MouseEvent e) {
             tester.stop();
          }
    
          @Override
          public void mouseDragged(MouseEvent e) {
             tester.move(e.getPoint());
          }
       }
    
       public class AxeThread {
          private Point location = null;
          private ZambashPanel zambashPanel;
    
          public AxeThread(ZambashPanel zambashPanel) {
             this.zambashPanel = zambashPanel;
          }
    
          public void start(Point point) {
             setLocation(point);
          }
    
          public void move(Point point) {
             setLocation(point);
          }
    
          public void stop() {
             setLocation(null);
          }
    
          public void setLocation(Point location) {
             if (this.location == null) {
                System.out.println("started");
             }
             
             this.location = location;
             
             if (location != null) {
                zambashPanel.setAxeLocation(location);
             } else {
                System.out.println("stopped");
             }
          }
       }
    
       private static void createAndShowUI() {
          JFrame frame = new JFrame("ZambashPanel");
          frame.getContentPane().add(new ZambashPanel());
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }
    Last edited by Fubarable; 08-25-2011 at 03:53 AM. Reason: show with image

  6. #6
    Zambash is offline Member
    Join Date
    Aug 2011
    Posts
    6
    Rep Power
    0

    Default

    So you made an instance of the panel within the movement thread so that it could have its own set of Mouse related functions that would be identical to those in the main panel that you added to the frame?

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Zambash View Post
    So you made an instance of the panel within the movement thread so that it could have its own set of Mouse related functions that would be identical to those in the main panel that you added to the frame?
    There is no "movement thread" as all code in my example program is run in a single thread, the EDT. I passed an instance of the main GUI (here subclassing JPanel, but that's irrelevant), so that the second class could call public methods of the main GUI.

  8. #8
    Zambash is offline Member
    Join Date
    Aug 2011
    Posts
    6
    Rep Power
    0

Similar Threads

  1. Location of Mouse/JRadioButton Problem
    By PorgrammingNoob117 in forum AWT / Swing
    Replies: 3
    Last Post: 05-10-2011, 11:01 PM
  2. external mouse actions
    By nest17 in forum Advanced Java
    Replies: 5
    Last Post: 02-10-2011, 06:07 AM
  3. Thread location problem?
    By AMaineJR in forum Threads and Synchronization
    Replies: 1
    Last Post: 10-01-2010, 04:38 AM
  4. Replies: 8
    Last Post: 08-25-2010, 05:22 PM
  5. How do you set the mouse curser location?
    By noobgrammer in forum New To Java
    Replies: 1
    Last Post: 07-20-2010, 02:44 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •