3
$\begingroup$
Manipulate[EventHandler[
  Row[{TableForm[Map[NumberForm[#, {6, 2}] &, {{x, y}, dir}, {2}], 
     TableHeadings -> {{"{x,y}", "dir"}, {"X", "Y"}}]
    , Graphics[{Thick, Green, PointSize[.02], Point[{x, y}], 
      Line[{{x, y}, {x, y} + dir}]}
     , ImageSize -> {200, 200}, PlotRange -> {{0, 10}, {0, 10}}, 
     Background -> Gray]}]
  , {"LeftArrowKeyDown" :> (dir = RotationTransform[.1][dir])
   , "RightArrowKeyDown" :> (dir = RotationTransform[-.1][dir])
   , "UpArrowKeyDown" :> (If[0 < x + dir[[1]] < 10, x += dir[[1]]]; 
     If[0 < y + dir[[2]] < 10, y += dir[[2]]])
   , "DownArrowKeyDown" :> (If[0 < x - dir[[1]] < 10, x -= dir[[1]]]; 
     If[0 < y - dir[[2]] < 10, y -= dir[[2]]])}]
 , {{x, 3.2}, ControlType -> None}, {{y, 4.8}, 
  ControlType -> None}, {{dir, {0, 1}}, ControlType -> None}
 ]

When I hit the direction key in the right graphic area a few times, sometimes the right graphic area will lose focus and the focus will run to the left table area. As a result, if you want the right graphic area to continue to respond to the direction key, you have to click the right graphic area with the mouse. The action is very discontinuous! How can we make the right graphic area not lose focus? Looking forward to the answer, thank you.

$\endgroup$
2
$\begingroup$

Please send a bug report to Wolfram Research (support@wolfram.com). Until you get a patch for your Mathematica version you could the following code ( I only tested it on Windows, but it should work on Mac and Linux, too, I think ):

    Manipulate[
      EventHandler[
        Grid[{{Pane[#, Alignment -> Center, ImageSize -> 222]& @ 
               TableForm[Map[NumberForm[#, {6, 2}]&, {{x, y}, dir}, {2}], 
               TableHeadings -> {{"{x,y}", "dir"}, {"X", "Y"}}, TableAlignments -> Right], 
               (*Deploy @ *)Graphics[{Thick, Green, PointSize[.02], Point[{x, y}], Line[{{x, y}, {x, y} + dir}]}, 
               ImageSize -> {200, 200}, PlotRange -> {{0, 10}, {0, 10}}, Background -> Gray]
               }}, Spacings -> 1, Alignment -> {Left, Right}, Dividers -> None
        ], {"LeftArrowKeyDown" :> (dir = RotationTransform[.1][dir];
        
        click[])
        , 
        "RightArrowKeyDown" :> (dir = RotationTransform[-.1][dir];
        
        click[])
        , "UpArrowKeyDown" :> (If[0 < x + dir[[1]] < 10,
            x += dir[[1]]
          ];      
          If[0 < y + dir[[2]] < 10,
            y += dir[[2]]
          ];     
          click[]
        ), "DownArrowKeyDown" :> (If[0 < x - dir[[1]] < 10,
            x -= dir[[1]]
          ];
          
          If[0 < y - dir[[2]] < 10,
            y -= dir[[2]]
          ];     
          click[]
        )
      }
    ], {{x, 3.2}, ControlType -> None}, 
       {{y, 4.8}, ControlType -> None}, 
       {{dir, {0, 1}}, ControlType -> None}, 
       Initialization :> (click[] := (
        Needs["JLink`"];   
        JLink`InstallJava[];
        JLink`LoadJavaClass["java.awt.event.InputEvent"];
        robot = JLink`JavaNew["java.awt.Robot"];
        robot @ mousePress[InputEvent`BUTTON1UMASK];
        robot @ mouseRelease[InputEvent`BUTTON1UMASK];
        Pause[.01]
      );
    )
]
$\endgroup$
1
  • $\begingroup$ Most of the time, it's works what you want, but when the length of the left table item changes, it still loses focus. Thank you for your example of "JLINK", which helps me eliminate the psychological barriers to JLINK. thank you. $\endgroup$ – xingzheshengcun Jan 29 at 1:18
2
$\begingroup$

Your Manipulate's body (first argument) depends on x, y and dir. If any of them changes the whole body is reevaluated and rendered which means the EventHandler after the arrow key press is a new EventHandler, Graphics is also new so it is not surprising that the selection is lost and not restored sometimes.

You can avoid this by making sure that only the essential part is refreshed. Just put Dynamics here and there. It is called 'nesting Dynamics' and explained in tutorial/AdvancedDynamicFunctionality and various threads here:

   EventHandler[
 Row[{Dynamic@
    TableForm[Map[NumberForm[#, {6, 2}] &, {{x, y}, dir}, {2}], 
     TableHeadings -> {{"{x,y}", "dir"}, {"X", "Y"}}], 
   Graphics[{Thick, Green, PointSize[.02], Point[Dynamic@{x, y}], 
     Line[Dynamic@{{x, y}, {x, y} + dir}]}, ImageSize -> {200, 200}, 
    PlotRange -> {{0, 10}, {0, 10}}, 
    Background -> Gray]}], {"LeftArrowKeyDown" :> (dir = 
     RotationTransform[.1][dir]), 
  "RightArrowKeyDown" :> (dir = RotationTransform[-.1][dir]), 
  "UpArrowKeyDown" :> (If[0 < x + dir[[1]] < 10, x += dir[[1]]];
    If[0 < y + dir[[2]] < 10, y += dir[[2]]]), 
  "DownArrowKeyDown" :> (If[0 < x - dir[[1]] < 10, x -= dir[[1]]];
    If[0 < y - dir[[2]] < 10, y -= dir[[2]]])}]
$\endgroup$
2
  • $\begingroup$ It works. thx very much. $\endgroup$ – xingzheshengcun Jan 29 at 1:12
  • $\begingroup$ @xingzheshengcun great, then vote up $\endgroup$ – Kuba Jan 29 at 8:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.