Matlab-Java interface using a static control

I would like to welcome guest blogger Karthik Ponudurai. Today, Karthik will introduce an interesting technique for interfacing Java GUI to a Matlab application.

The current method of interfacing Java GUI controls and Matlab is by retrieving the underlying Java callback and assigning it to a Matlab callback, as shown in the following example:

% Create a Java button
jButton = javacomponent(javax.swing.JButton('click me'), [20,20,60,20], gcf);
 
% Assign a Matlab callback
hButton = handle(jButton, 'CallbackProperties');
set(hButton, 'ActionPerformedCallback', @myCallback);
 
% Matlab callback function
function myCallback(hObject, hEventData)
    % Insert your code here
end

This approach works fine for simple pure-Java GUI created using an IDE (for example, NetBeans or Eclipse) that only have a small number of controls. You can retrieve all the Java controls in Matlab and set the callbacks as shown in the above example.

Unfortunately, practical GUIs often contain numerous controls. Assigning each control a different Matlab callback can be quite tedious.

Using a callback switchyard function

A workaround to this problem can be achieved using an invisible/hidden static Java JButton. During Matlab initialization, assign a single callback for the static Java JButton:

% Return a reference to the GUI's static trigger button
triggerButton = statictrigger.triggerCls.getTrigger();
 
% Assign Matlab switchyard callback for triggerButton
buttonProps = handle(triggerButton, 'callbackproperties');
set(triggerButton, 'ActionPerformedCallback',@TriggerCallback);

When an event is triggered by any monitored control in the Java GUI, then within the Java code set the static button’s action command string to the desired Matlab callback name (a String) and invoke the static button’s doClick() method to trigger the Matlab TriggerCallback callback. Based on the action command string, this callback invokes the appropriate Matlab function. In this manner, Matlab’s TriggerCallback() acts as a switchyard function to the actual callback functions:

function TriggerCallback(hObject, hEventData)
   actionCmd = char( hObject.getActionCommand() );
   hgfeval(actionCmd, hObject, hEventData);
end

Note how the char function converts the Java action command (a java.lang.String object) into Matlab char array. The requested Matlab function is then dynamically invoked using Matlab’s semi-documented hgfeval function, which Yair will describe in another article later this month.

The next few sections will look into the sample application in more detail. This application can be downloaded from here.

Java GUI

Firstly, let’s look into the Java GUI:

Main Java GUI

Main Java GUI

When the “Show Result in Matlab Dialog Box” button is clicked, the form information’s (Name, Age, Sex etc…) is saved in a hash map. This hash map is then serialized to a local file (C:\streamdata). Next, the static button’s action command string is set to ‘show’ and finally its doClick() method is invoked.

Below is the Java code corresponding to button click event:

private void showActionPerformed(java.awt.event.ActionEvent evt)
{
    // Add form values to hash map
    hMap.put(name.getName(), name.getText());
    hMap.put(age.getName(), age.getValue());
    hMap.put(sex.getName(), (String)sex.getSelectedItem());
    hMap.put(address.getName(), address.getText());
    hMap.put(email.getName(), email.getText());
 
    // Serialize hash map
    WriteObject(hMap);
 
    // Set trigger
    triggerCls.setTrigger(evt.getActionCommand());
}

Matlab callbacks

The Java GUI sources are compiled and packaged in the statictrigger.jar file. The Matlab StaticButtonTriggerExample.m source file adds the Java library to the dynamic Java classpath:

% Add dynamic java class path
javaclasspath([pwd '\javalib\statictrigger.jar']);

The main.m function contains the code for creating the Java GUI and assigning the static button callback:

% create the statictrigger object
app = statictrigger.app();
 
% Set static trigger button listener
triggerButton = statictrigger.triggerCls.getTrigger();
buttonProps = handle(triggerButton,'callbackproperties');
set(buttonProps,'ActionPerformedCallback', {@StaticButtonTriggerCallback, app}); 
 
% Show the Java Frame 
app.setVisible(1);

statictrigger.triggerCls.getTrigger() is a static Java public method that returns the static button object, for which we assign our callback switchyard function.

The following is the StaticButtonTriggerCallback.m code, which displays the information in a Matlab message-box:

Matlab message-box triggered by the Java GUI

Matlab message-box triggered by the Java GUI

% Get action command string  
actionCommand = src.getActionCommand();
 
% Read in serialized hash map
hashMap = app.ReadObject();
 
% Convert hash map to Matlab structure     
data = Hash2Struct(hashMap);
 
% Display data in Matlab dialog box
msg = ['Name: ' char(hashMap.get('name')) ...
       ', Age: ' num2str(hashMap.get('age')) ...
       ', Sex: ' char(hashMap.get('sex')) ...
       ', Address: ' char(hashMap.get('address')) ...
       ', Email: ' char(hashMap.get('email')) ];
uiwait(helpdlg(msg, 'Form Details'));

You can download the example’s files from here. Extract the zip file, cd to the newly-generated StaticButtonTrigger folder, then invoke the StaticButtonTriggerExample.m function to run the example.

Categories: Guest bloggers, GUI, Java, Low risk of breaking in future versions

Tags: , , ,

Bookmark and SharePrint Print

27 Responses to Matlab-Java interface using a static control

  1. Mikhail says:

    I have tried similar technique

    http://mathforum.org/kb/thread.jspa?forumID=80&threadID=1639114&messageID=5950848

    in a more general scenario, not directly bound to UI events to replace this older JMI-based approach


    http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html

    But somehow it has not worked for me …

    • Welcome aboard Mikhail :-)
      Haven’t seen you around CSSM in a very long time – you’ve been missed…

      Funny that the MathForum link you posted doesn’t appear on CSSM – I was under the impression that MathForum was a simple CSSM mirror

      -Yair

    • Karthik Ponudurai says:

      Hi Mikhail,

      I have also tried the JMI solution from

      http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html

      and I realise quickly how complicated it is to get it working, and running MATLAB as a server is not a good option for us.

      We code and deploy MATLAB application to users, and the above solution enable us to develop a nice looking front end with a simple communication protocol.

      Thanks.
      Karthik

    • Mikhail says:

      @Karthik: you misunderstood me. See my first link – the solution I tried three years ago very is similar to yours! Bur I encountered problems with it and had to stay with JMI which works fine. I will try your solution on this weekend!

    • Karthik Ponudurai says:

      Hi Mikhail, got you now. Let me know how it goes. Good luck!

  2. Eric Klumpp says:

    Very nice example !
    Is it possible to have also the java source code, to see all interactions between java and matlab ?

    Thanks
    Eric

  3. Suganya says:

    Hi Karthik

    I am working in a project similar to what you have said above . We are using NetBeans to create our own web application and we need to interface Matlab with JSP and servlets. Since servlets is the Java code, will we be able to interface it with Matlab in the way you have said above?

    Regards
    Suganya

    • Karthik Ponudurai says:

      Hi Suganya,

      I personally have not worked with Servlets or web application. I don’t think MATLAB includes the java libraries for servlets in the static library path, but you could add the libraries to the dynamic path during runtime and then access all the classes within MATLAB.

      Sorry for the late reply as I did not receive a notification email. If you have any further question, email me at karthik.ponudurai@gmail.com

      Karthik

  4. Anubhav Jain says:

    Hi,
    I want to enquire about the events generated upon opening or closing a dialog box(e.g-Function Block Parameters or Source Block Parameters). Is there any way I can get these events and register their listeners.
    Thanks & Regards
    Anubhav Jain

  5. Anubhav Jain says:

    Hi,
    Thanks a lot for your immediate response.
    Actually I wanted to get the name of an event associated with closing of function parameter dialog box for example if I change threshold value of a switch block and apply it then I should be able to listen to the event of closing of that parameter box. Can you please help me out with this.
    Thanks & Regards
    Anubhav Jain.

    • @Anubhav – you can perhaps trap the dialog figure’s DeleteFcn callback.

    • Donn Shull says:

      @Anubhav – This is a complicated area and you will have to do a lot of reasearch on your own to accomplish what you are looking for. The first thing to know is that the Simulink editor is not java based so none of the java techniques are going to be of use to you. Simulink to a certian extent is UDD based. There are two primary UDD packages you will need to study using the techniques from the series of articles on UDD. The first package is the ‘DAStudio’ package. The second is the ‘Simulink’ Package. DAStudio to a certian extent is the base package as it contains an object called DAStudio.Object which is the Superclass for Simulink.Object which in turn is the Superclass for most of the rest of the Simulink classes in the Simulink package. To a certian extent the uses for these packages can be divided as follows. Models are built from classes in the Simulink Package while Dialogs come from the DAStudio package. The parameter dialogs you are looking at are of tyoe DAStudio.Dialog. They do not generate any events on their own. They are however hierarchical children of DAStudio.ToolRoot. So in theory you can monitor an instance of DAStudio.ToolRoot for the events ‘ObjectsChildAdded’ and ‘ObjectChildRemoved’ using the methods in the Hiearchical Systems with UDD and UDD events posts.

      Good Luck,

      Donn

  6. Rob Cranfill says:

    I think there’s a typo in the original code – in the 2nd code block, the first one after the heading “Using a callback switchyard function”. It says

    get(triggerButton, 'ActionPerformedCallback',@TriggerCallback);

    but I’m pretty sure that should be

    set(triggerButton, 'ActionPerformedCallback',@TriggerCallback);  % set, not get

    At least, the first one doesn’t work for me, and the second one does. (I’m using Matlab 2012a, but I don’t think that’s the issue.)

    Thanks for lots of great Matlab help!

    /rob

  7. George Brennan says:

    Well done.

    I would add that as you are passing the Matlab instantiated app object around couldn’t you change the hMap to public and access it without the file I/O?

    Although getters/setters are probably a more acceptable route.

  8. nikhil says:

    Hello,

    I am trying to open a UI created in Java SWT through Matlab.
    But I am getting following error..

    Java exception occurred:
    java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
    	no swt-win32-3833 in java.library.path
    	no swt-win32 in java.library.path
    	Native Library C:\Users\x_shirod\.swt\lib\win32\x86_64\swt-win32-3833.dll already loaded in another classloader
    	Can't load library: C:\Users\x_shirod\.swt\lib\win32\x86_64\swt-win32.dll

    Can any one help me in this…

    thanking you in advance.


    Nikhil

  9. Jai Naresh says:

    Hi,
    I am trying to launch matlab model and control its execution through Java Interface. Please let me know if their are any ways to do this.

    Any response will help.

    Thanks,
    jai Naresh

  10. Abdullah says:

    So, I am trying the following:

    I added a listener to a Simulink block.

    When trying to execute a public function of my JAR file within the listener, I get an error.

    I tried to use a timer to see if that would solve the issue. However, it didn’t work.

    Any clues?

  11. Tom says:

    Why you getting a handle if you don´t use it?

    % Assign a Matlab callback
    hButton = handle(jButton, 'CallbackProperties');
    set(jButton, 'ActionPerformedCallback', @myCallback);

Leave a Reply

Your email address will not be published. Required fields are marked *