Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  How to differenciate mouse events from the user and those from java.awt.Robot?  (Read 2749 times)
0 Members and 1 Guest are viewing this topic.
Offline gouessej
« Posted 2009-11-09 17:36:00 »

Hi!

I'm looking for a way of making the difference between user mouse events and mouse events generated by java.awt.Robot. In AWTEvent, there is an attribute "isSystemGenerated" but it is always at true in my case Sad Robot uses a peer (WRobotPeer, MRobotPeer, XRobotPeer). I would like to find a way of modifying the events that the robot creates in order to handle them differently in several engines that need a mouse look and that use AWT. Do you have an idea? Best regards. Thank you for your attention.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2009-11-10 00:28:38 »

AFAIK, it can't be done.

Robot hooks into the OS, with the sole purpose of being indistinguishable from real user input.

Therefore you cannot modify the AWTEvents created by the Robot, because the Robot does not create AWTEvents. The Robot is operating at a lower level, and eventually the JVM receives a signal from the OS and creates the AWTEvent. The JRE has no way of figuring out what caused the event.

You can however build heuristics and make assumptions on what is likely and what is not. If you told Robot to move the mouse to X,Y and you receive an event of the mouse being at X,Y you can be fairly sure you caused that event. If the mouse is not exactly at X,Y you can be fairly sure the user moved the mouse. This way you can simulate a grabbed mouse.

But... what are you trying to do? And are you sure Robot is the best way to achieve it?

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline gouessej
« Reply #2 - Posted 2009-11-10 01:35:18 »

But... what are you trying to do? And are you sure Robot is the best way to achieve it?
Some years ago, bienator and you helped me in fixing this bug in TUER. I want to handle the continuous mouse look in Ardor3D without JInput, only with AWT. Currently, when the mouse reaches an edge of the screen, you cannot turn anymore. Your heuristic solution may be a fine solution, thank you very much.

Do you think I could write a RFE in order to ask Sun/Oracle for help? I think it wouldn't be efficient.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DzzD
« Reply #3 - Posted 2009-11-10 01:40:25 »

Some years ago, bienator and you helped me in fixing this bug in TUER. I want to handle the continuous mouse look in Ardor3D without JInput, only with AWT. Currently, when the mouse reaches an edge of the screen, you cannot turn anymore. Your heuristic solution may be a fine solution, thank you very much.

Do you think I could write a RFE in order to ask Sun/Oracle for help? I think it wouldn't be efficient.
ho! I remember I did something like for a FPS demo (http://demo.dzzd.net/FPSSample9/) I will post it if I can found source code Smiley

Offline gouessej
« Reply #4 - Posted 2009-11-10 01:44:37 »

ho! I remember I did something like for a FPS demo (http://demo.dzzd.net/FPSSample9/) I will post it if I can found source code Smiley
I have done it too in TUER but with my own engine, it was less difficult to implement than in other real 3D engines. Maybe you found another more interesting solution Smiley

Offline DzzD
« Reply #5 - Posted 2009-11-10 01:45:55 »

got it ! why do you want to differentiate Robot than other ??

also, I commented the extension loader part as it wont be needed for you (it is only requiered to load from an unsigned applet)

first create an instance (new FPSMouseControler )
second set the wanted canvas to control (setCanvas)

third read dmx & dmy to get mouse delta X and mouse delta Y



1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
   public class FPSMouseControler implements MouseMotionListener 
   {
      int mx=0;
      int my=0;
      int screenX;
      int screenY;
      int screenXDiv2;
      int screenYDiv2;
      public int dmx=0;
      public int dmy=0;
      Canvas c;
     
      Robot robot;
      //IExtensionLoader loader;

      public FPSMouseControler() throws Exception
      {
     
            //if(loader == null)
           //   loader = ExtensionLoader.getLoader(this.getClass());

            robot = new Robot();
            Toolkit t = Toolkit.getDefaultToolkit();
            screenX = t.getScreenSize().width;
            screenY = t.getScreenSize().height;
            screenXDiv2=screenX>>1;
            screenYDiv2=screenY>>1;
           
           
           

           
      }
     
      public void setCanvas(Canvas c)
      {
         if(this.c!=null)
            this.removeCanvas(this.c);
           
         this.c=c;
         c.addMouseMotionListener(this);  
         
            //try to hide cursor using an internet grabbed source code... lazy me :)
           try
            {
           
            int[] pixels = new int[16 * 16];
            Image image = Toolkit.getDefaultToolkit().createImage(
            new MemoryImageSource(16, 16, pixels, 0, 16));
            Cursor transparentCursor =
            Toolkit.getDefaultToolkit().createCustomCursor
                 (image, new Point(0, 0), "invisibleCursor");
             this.c.setCursor(transparentCursor);
             }
             catch(Throwable te)
             {
                te.printStackTrace();
                //dont car if we cant hide it
            }        
      }
     
      public void removeCanvas(Canvas c)
      {
         c.removeMouseMotionListener(this);  
         this.c=null;
         c.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
         
      }
     
     
      public void mouseDragged(MouseEvent e)
      {
         this.mouseMoved(e);
      }
       
      public void mouseMoved(MouseEvent e)  
      {
         mx=e.getXOnScreen();
         my=e.getYOnScreen();
         if(mx!=screenXDiv2 || my!=screenYDiv2)
         {
            dmx+=mx-screenXDiv2;
            dmy+=my-screenYDiv2;  
           
            robot.mouseMove(screenXDiv2, screenYDiv2);
         }
      }


   }



EDIT : pom pom pom

Offline DzzD
« Reply #6 - Posted 2009-11-10 01:46:50 »

I have done it too in TUER but with my own engine, it was less difficult to implement than in other real 3D engines. Maybe you found another more interesting solution Smiley

try the demo, It work pretty well (hit "M")

Offline gouessej
« Reply #7 - Posted 2009-11-10 10:31:52 »

try the demo, It work pretty well (hit "M")
It works pretty well in your demo but the source code looks like my first implementation of mouse look; in some cases, it doesn't work, I don't know why Bienator & Riven's solution has worked better than this for me.

Anyway, if I don't want to rewrite the whole ardor3d-awt module, the most realistic solution is the latest Riven's suggestion, the heuristic one.

Offline DzzD
« Reply #8 - Posted 2009-11-10 10:38:52 »

It works pretty well in your demo but the source code looks like my first implementation of mouse look; in some cases, it doesn't work, I don't know why Bienator & Riven's solution has worked better than this for me.

Anyway, if I don't want to rewrite the whole ardor3d-awt module, the most realistic solution is the latest Riven's suggestion, the heuristic one.
I cant see a case where it wont works ? any sample ? (maybe the aonly problem could be that you have to adjust screenWDiv2 and screenHeightDiv2 to fall in you windows, but dont know let me know what case may cause problems ?

Offline gouessej
« Reply #9 - Posted 2009-11-10 11:01:39 »

I cant see a case where it wont works ? any sample ? (maybe the aonly problem could be that you have to adjust screenWDiv2 and screenHeightDiv2 to fall in you windows, but dont know let me know what case may cause problems ?
The threading of my own engine was strange, I did not need to deactivate DirectDraw on lots of machine under Vista whereas I have used OpenGL for years. Sometimes, the mouse cursor stayed frozen a few milliseconds, look at the TUER thread, we solved this problem in 2007.

In Ardor3D, its architecture does not rely on a delta, it uses the MouseEvent instances. That's why I will have to use Riven's suggestion.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DzzD
« Reply #10 - Posted 2009-11-10 11:24:44 »

The threading of my own engine was strange, I did not need to deactivate DirectDraw on lots of machine under Vista whereas I have used OpenGL for years. Sometimes, the mouse cursor stayed frozen a few milliseconds, look at the TUER thread, we solved this problem in 2007.
I have trouble to understand what you say .... nothing related to DD or openg here I use this class with both standar Java2D & opengl canvas it just worked nice for me

In Ardor3D, its architecture does not rely on a delta, it uses the MouseEvent instances. That's why I will have to use Riven's suggestion.
heu... seems that the implementation I posted follow what Riven's mention in its post above....



Offline Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #11 - Posted 2009-11-10 13:32:47 »

What I suggested, is exactly the same as what DzzD suggests.

The difference in the implementation would be that I take the center of the window, and he takes the center of the screen, which is obviously only reliable in fullscreen mode.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline gouessej
« Reply #12 - Posted 2009-11-10 13:44:47 »

I have trouble to understand what you say .... nothing related to DD or openg here I use this class with both standar Java2D & opengl canvas it just worked nice for me
Yes, I know, but it did not work as expected in my case, I have never really understand the exact reason why this approach did not work, I made some hypothesis.

heu... seems that the implementation I posted follow what Riven's mention in its post above....
You're right, sorry.

I'm going to get the queue with Toolkit.getDefaultToolkit().getSystemEventQueue();
Then, I can use peekEvent(MouseEvent.MOUSE_MOVED) to get the newly created event.
If it is a centering event, I call getNextEvent.
It might be slow Sad

Edit.: cylab told me once that we could directly use the queue. Now I know what he meant.

Offline Markus_Persson

JGO Wizard


Medals: 14
Projects: 19


Mojang Specifications


« Reply #13 - Posted 2009-11-10 18:54:25 »

You don't need to skip an event.

Play Minecraft!
Offline gouessej
« Reply #14 - Posted 2009-11-10 23:22:06 »

You don't need to skip an event.
What do you mean exactly?

Offline Nate

JGO Kernel


Medals: 145
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #15 - Posted 2009-11-11 03:08:19 »

FWIW, on Windows you can check a key event to see if it is injected. Eg, LLKHF_INJECTED. I don't believe this is exposed from Java though.

Offline Markus_Persson

JGO Wizard


Medals: 14
Projects: 19


Mojang Specifications


« Reply #16 - Posted 2009-11-11 14:39:50 »

What do you mean exactly?

1  
2  
3  
4  
5  
6  
7  
8  
public void mouseMoved(MouseEvent mouseEvent) {
    int dx = mouseEvent.getX()-screenCenterX;
    int dy = mouseEvent.getY()-screenCenterY;
    if (dx!=0 || dy!=0) {
        handleMouseMove(dx, dy);
        robot.moveMouse(screenCenterX, screenCenterY);
    }
}

Play Minecraft!
Offline gouessej
« Reply #17 - Posted 2009-11-11 16:38:10 »

Thanks Markus_Persson. Now I do this, I have some things to improve to follow your advice:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
public synchronized void mouseMoved(final MouseEvent e) {
        final int dx = e.getX() - _component.getWidth() / 2;
        final int dy = e.getY() - _component.getHeight() / 2;
        if (dx != 0 || dy != 0) {
            _clickArmed.clear();
            _clicks.clear();

            final MouseEvent me = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), e
                    .getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e
                    .getButton());

            initState(me);

            addNewState(me, _lastState.getButtonStates(), null);
            if (robot == null) {
                try {
                    robot = new Robot();
                } catch (final AWTException ex) {
                    ex.printStackTrace();
                }
            }
            final Point componentCenter = new Point(_component.getWidth() / 2, _component.getHeight() / 2);
            SwingUtilities.convertPointToScreen(componentCenter, _component);
            robot.mouseMove(componentCenter.x, componentCenter.y);
        }
    }

private void initState(final MouseEvent mouseEvent) {
        if (_lastState == null) {
            final int height = (_frame != null && _frame.getComponentCount() > 0) ? _frame.getComponent(0).getHeight()
                    : _component.getHeight();
            _lastState = new MouseState(mouseEvent.getX(), height - mouseEvent.getY(), 0, 0, 0, null, null);
        }
    }

    private void addNewState(final MouseEvent mouseEvent, final EnumMap<MouseButton, ButtonState> enumMap,
            final Multiset<MouseButton> clicks) {
        // changing the y value, since for AWT, y = 0 at the top of the screen
       final int height = (_frame != null && _frame.getComponentCount() > 0) ? _frame.getComponent(0).getHeight()
                : _component.getHeight();
        final int fixedY = height - mouseEvent.getY();

        final MouseState newState = new MouseState(mouseEvent.getX(), fixedY, mouseEvent.getX() - _lastState.getX(),
                fixedY - _lastState.getY(), (mouseEvent instanceof MouseWheelEvent ? ((MouseWheelEvent) mouseEvent)
                        .getWheelRotation() : 0), enumMap, clicks);

        _upcomingEvents.add(newState);
        _lastState = newState;
    }

Offline gouessej
« Reply #18 - Posted 2009-11-11 18:12:35 »

Somebody suggested this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
_logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT),
                new TriggerAction() {
                    public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) {
                        _cursorLock.x = -1;
                        _cursorLock.y = -1;
                        _isGrabbed = false;
                        _canvas.setCursor(null);
                    }
                }));

        _logicalLayer.registerTrigger(new InputTrigger(new MouseMovedCondition(), new TriggerAction() {
            public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) {
                int x, y;
                x = inputState.getCurrent().getMouseState().getX();
                y = inputState.getCurrent().getMouseState().getY();

                if (_cursorLock.x == x && _cursorLock.y == y) {
                    _last.x = x;
                    _last.y = y;
                    return;
                }

                if (_isGrabbed) {
                    _uiRobot.mouseMove(_cursorLock.x, _canvas.getHeight() - _cursorLock.y);

                    final int dx = _last.x - x;
                    final int dy = _last.y - y;

                    _controlHandle.rotate(canvas.getCanvasRenderer().getCamera(), -dx, -dy);
                }
                _last.x = x;
                _last.y = y;
            }
        }));

        _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT),
                new TriggerAction() {
                    public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) {
                        _canvas.setCursor(s_transparentCursor);
                        _isGrabbed = true;
                        _cursorLock.x = inputState.getCurrent().getMouseState().getX();
                        _cursorLock.y = inputState.getCurrent().getMouseState().getY();
                    }
                }));


and it works, it only needs some refactoring  Grin

Offline Markus_Persson

JGO Wizard


Medals: 14
Projects: 19


Mojang Specifications


« Reply #19 - Posted 2009-11-12 15:59:11 »

Sometimes less is more.

Play Minecraft!
Offline DzzD
« Reply #20 - Posted 2009-11-12 18:14:32 »

Sometimes less is more.
Smiley

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (15 views)
2014-07-29 18:09:19

Riven (10 views)
2014-07-29 18:08:52

Dwinin (10 views)
2014-07-29 10:59:34

E.R. Fleming (28 views)
2014-07-29 03:07:13

E.R. Fleming (10 views)
2014-07-29 03:06:25

pw (40 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (27 views)
2014-07-23 21:07:15

Riven (29 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!