pattivacek
pattivacek

Reputation: 5833

How to capture key press in Matlab uipanel

How can one capture keyboard entry inside a uipanel, i.e. when anything in the panel has focus? I've found that uipanel does not have the KeyPressFcn property. I've read this post from Undocumented Matlab about Java callbacks, but I also can't get KeyPressedCallback to work. For example, if I try to this:

set(h_panel, 'KeyPressFcn', @(src, event)key_press(obj, src, event));

I get this error:

The name 'KeyPressFcn' is not an accessible property for an instance of class 'uicontrol'.

The same thing occurs if I try KeyPressedCallback. I'm afraid I'll have to resort to some sort of hack involving the parent figure, which I would like to avoid if possible.

Upvotes: 2

Views: 1173

Answers (3)

Yair Altman
Yair Altman

Reputation: 5722

KeyPressedCallback is a property of the underlying Java object, not the original Matlab uicontrol object. To access the underlying Java control of a Matlab uicontrol, you need to use the findjobj utility, as I believe that I explained in my blog post that you referenced (you probably missed that crucial step):

jPanel = findjobj(hPanel);
jPanel.KeyPressedCallback = @myMatlabCallbackFunc;

Note that Matlab panels only became Java-based objects in HG2 (R2014b, see here). So on R2014a and earlier Matlab releases you will not be able to use this technique, only on one of the newer releases.

Upvotes: 2

pattivacek
pattivacek

Reputation: 5833

Ultimately, I have found there are two reasonable solutions to this problem, both involving what I originally described as "some sort of hack involving the parent figure". Both of them require some sort of concept of an "active" panel or object within the figure in question.

Solution 1

Rely on the last-clicked object to direct keyboard input in the figure to that object. Use ButtonDownFcn for every object in the figure that needs keyboard input. In the callback, store the handle of the object in the appdata of the figure as the "active" object. (Something like setappdata(h_fig, 'active_obj', h_obj.) Then set KeyPressFcn in the figure to a function that will get that handle out of the appdata and branch accordingly.

Solution 2

Use some sort of keypress scheme to decide which object to direct further input to. This works well if you have a number of similar objects that merely need disambiguation. For example, set the KeyPressFcn of the figure to a function that uses keys 1-9 to indicate the correspondingly numbered object. Direct further keyboard input to that object or a related function.

Neither method is perfect, and I wish there was a way to avoid going through the figure, but in practice these aren't very complicated to implement. I'm actually using both simultaneously.

Upvotes: 0

chappjc
chappjc

Reputation: 30589

I don't see any callback properties that you can use or events to which you can attach a listener.

>> events(h_panel)
Events for class matlab.ui.container.Panel:
    ObjectBeingDestroyed
    LocationChanged
    SizeChanged
    ButtonDown
    Reset
    PropertyAdded
    PropertyRemoved

Just the mouse event (ButtonDown) and the ButtonDownFcn callback. Perhaps there are other tricks. Ask Yair Altman!

Upvotes: 0

Related Questions