Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Matlab callbacks for Java events

November 30, 2010 88 Comments

A few days ago, a user posted a question on StackOverflow asking whether it is possible to trap a Java-based event in a Matlab callback.IB-Matlab connectivity (Matlab and TWS may be on separate computers)
It so happens that only a few weeks ago I completed a consulting project which required exactly this. The project was to integrate a Matlab computational engine with a Java interface to Interactive Brokers (IB) – a well-known online brokerage firm. The idea was to use the Java interface to fetch real-time data about securities (stocks, bonds, options etc.), use a Matlab processing utility, then use the Java interface again to send Buy or Sell orders back to IB.
If you are interested in the final result (IB-Matlab, a complete and field-tested Matlab-IB interface), look here.

The challenge

A big challenge in this project (aside from handling quite a few IB interface quirks), was to propagate events from the Java interface to the Matlab application. This had to be done asynchronously, since events such as order execution can occur at any time following the order placement. Moreover, even simple requests such as retrieving security information (bid/ask prices for example) is handled by IB via Java events, not as simple function return values.
Handling Java-based events in Matlab is not a trivial task. Not only merely undocumented, but it is also not intuitive. I have spent quite a few hours trying to crack this issue. In fact, I believe it was one of my more challenging tasks in figuring out the undocumented aspects of the Matlab-Java interface. Few other challenges were as difficult, yet with a happy ending (Drag & Drop is a similar issue – I will describe it in another article sometime).

The solution

Fast-forward all the fruitless attempted variations, here is the bottom line. Refer to the following simple Java class example:

public class EventTest
{
    private java.util.Vector data = new java.util.Vector();
    public synchronized void addMyTestListener(MyTestListener lis) {
        data.addElement(lis);
    }
    public synchronized void removeMyTestListener(MyTestListener lis) {
        data.removeElement(lis);
    }
    public interface MyTestListener extends java.util.EventListener {
        void testEvent(MyTestEvent event);
    }
    public class MyTestEvent extends java.util.EventObject {
        private static final long serialVersionUID = 1L;
        public float oldValue,newValue;
        MyTestEvent(Object obj, float oldValue, float newValue) {
            super(obj);
            this.oldValue = oldValue;
            this.newValue = newValue;
        }
    }
    public void notifyMyTest() {
        java.util.Vector dataCopy;
        synchronized(this) {
            dataCopy = (java.util.Vector)data.clone();
        }
        for (int i=0; i < dataCopy.size(); i++) {
            MyTestEvent event = new MyTestEvent(this, 0, 1);
            ((MyTestListener)dataCopy.elementAt(i)).testEvent(event);
        }
    }
}

public class EventTest { private java.util.Vector data = new java.util.Vector(); public synchronized void addMyTestListener(MyTestListener lis) { data.addElement(lis); } public synchronized void removeMyTestListener(MyTestListener lis) { data.removeElement(lis); } public interface MyTestListener extends java.util.EventListener { void testEvent(MyTestEvent event); } public class MyTestEvent extends java.util.EventObject { private static final long serialVersionUID = 1L; public float oldValue,newValue; MyTestEvent(Object obj, float oldValue, float newValue) { super(obj); this.oldValue = oldValue; this.newValue = newValue; } } public void notifyMyTest() { java.util.Vector dataCopy; synchronized(this) { dataCopy = (java.util.Vector)data.clone(); } for (int i=0; i < dataCopy.size(); i++) { MyTestEvent event = new MyTestEvent(this, 0, 1); ((MyTestListener)dataCopy.elementAt(i)).testEvent(event); } } }

When compiling EventTest.java, three class files are created: EventTest.class, EventTest$MyTestEvent.class and EventTest$MyTestListener.class. Place them on Matlab’s Java static classpath, using edit(‘classpath.txt’) (using the dynamic classpath causes many problems that using the static classpath solves). They can now be accessed as follows:

>> which EventTest
EventTest is a Java method  % EventTest constructor
>> evt = EventTest
evt =
EventTest@16166fc
>> evt.get
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback =
	TestEventCallbackData = []
	BeingDeleted = off
	ButtonDownFcn =
	Children = []
	Clipping = on
	CreateFcn =
	DeleteFcn =
	BusyAction = queue
	HandleVisibility = on
	HitTest = on
	Interruptible = on
	Parent = []
	Selected = off
	SelectionHighlight = on
	Tag =
	Type = EventTest
	UIContextMenu = []
	UserData = []
	Visible = on
>> set(evt)
	Class
	TestEventCallback: string -or- function handle -or- cell array
	...
>> set(evt,'TestEventCallback',@(h,e)disp(h))
>> get(evt)
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback = [ (1 by 1) function_handle array]    % < = ok
	TestEventCallbackData = []
	...
>> evt.notifyMyTest   % invoke Java event
              0.0009765625   % < = Matlab callback

>> which EventTest EventTest is a Java method % EventTest constructor >> evt = EventTest evt = EventTest@16166fc >> evt.get Class = [ (1 by 1) java.lang.Class array] TestEventCallback = TestEventCallbackData = [] BeingDeleted = off ButtonDownFcn = Children = [] Clipping = on CreateFcn = DeleteFcn = BusyAction = queue HandleVisibility = on HitTest = on Interruptible = on Parent = [] Selected = off SelectionHighlight = on Tag = Type = EventTest UIContextMenu = [] UserData = [] Visible = on >> set(evt) Class TestEventCallback: string -or- function handle -or- cell array ... >> set(evt,'TestEventCallback',@(h,e)disp(h)) >> get(evt) Class = [ (1 by 1) java.lang.Class array] TestEventCallback = [ (1 by 1) function_handle array] % < = ok TestEventCallbackData = [] ... >> evt.notifyMyTest % invoke Java event 0.0009765625 % < = Matlab callback

Note how Matlab automatically converted the Java event testEvent, declared in interface MyTestListener, into a Matlab callback TestEventCallback (the first character is always capitalized). All Java events are automatically converted in this fashion, by appending a ‘Callback’ suffix. Here is a code snippet from R2008a’s \toolbox\matlab\uitools\@opaque\addlistener.m that shows this (slightly edited):

hSrc = handle(jobj,'callbackproperties');
allfields = sortrows(fields(set(hSrc)));
for i = 1:length(allfields)
   fn = allfields{i};
   if ~isempty(findstr('Callback',fn))
      disp(strrep(fn,'Callback',''));
   end
end
callback = @(o,e) cbBridge(o,e,response);
hdl = handle.listener(handle(jobj), eventName, callback);
function cbBridge(o,e,response)
   hgfeval(response, java(o), e.JavaEvent)
end

hSrc = handle(jobj,'callbackproperties'); allfields = sortrows(fields(set(hSrc))); for i = 1:length(allfields) fn = allfields{i}; if ~isempty(findstr('Callback',fn)) disp(strrep(fn,'Callback','')); end end callback = @(o,e) cbBridge(o,e,response); hdl = handle.listener(handle(jobj), eventName, callback); function cbBridge(o,e,response) hgfeval(response, java(o), e.JavaEvent) end

Note that hgfeval, which is used within the cbBridge callback function, is a semi-documented pure-Matlab built-in function, which I described a few weeks ago.
If several events have the same case-insensitive name, then the additional callbacks will have an appended underscore character (e.g., ‘TestEventCallback_’):

// In the Java class:
public interface MyTestListener extends java.util.EventListener
{
    void testEvent(MyTestEvent e);
    void testevent(TestEvent2 e);
}

// In the Java class: public interface MyTestListener extends java.util.EventListener { void testEvent(MyTestEvent e); void testevent(TestEvent2 e); }

% …and back in Matlab:
>> evt=EventTest; evt.get
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback =
	TestEventCallbackData = []
	TestEventCallback_ =
	TestEventCallback_Data = []
	...

% …and back in Matlab: >> evt=EventTest; evt.get Class = [ (1 by 1) java.lang.Class array] TestEventCallback = TestEventCallbackData = [] TestEventCallback_ = TestEventCallback_Data = [] ...

To complete this discussion, it should be noted that Matlab also automatically defines corresponding Events in the Java object’s classhandle. Unfortunately, classhandle events are not differentiated in a similar manner – in this case only a single event is created, named Testevent. classhandle events, and their relationship to the preceding discussion, will be described in Donn Scull’s upcoming series on UDD.
An alternative to using callbacks on Java events, as shown above, is to use undocumented handle.listeners:

hListener = handle.listener(handle(evt),'TestEvent',callback);

hListener = handle.listener(handle(evt),'TestEvent',callback);

There are several other odds and ends, but this article should be sufficient for implementing a fully-functional Java event handling mechanism in Matlab. Good luck!
p.s. – if you’re still stuck, consider hiring me for a short consulting project. I’ll be happy to help.

Related posts:

  1. Matlab callbacks for Java events in R2014a – R2014a changed the way in which Java objects expose events as Matlab callbacks. ...
  2. Matlab callbacks for uifigure JavaScript events – Matlab callback code can be attached to JavaScript events in web-based uifigures. ...
  3. UDD and Java – UDD provides built-in convenience methods to facilitate the integration of Matlab UDD objects with Java code - this article explains how...
  4. UDD Events and Listeners – UDD event listeners can be used to listen to property value changes and other important events of Matlab objects...
  5. Enabling user callbacks during zoom/pan – Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...
  6. Waiting for asynchronous events – The Matlab waitfor function can be used to wait for asynchronous Java/ActiveX events, as well as with timeouts. ...
Callbacks Java Listener Semi-documented function Undocumented feature Undocumented function
Print Print
« Previous
Next »
88 Responses
  1. julien vergoz December 3, 2010 at 06:31 Reply

    Once again, a very nice article ! Thanks to you, we can now trigger matlab callbacks from java-events without an advanced knowledge of java… Thank you !
    I have a question about listening to MouseEvents : in a matlab application, I would like to trigger a matlab Callback when the mouse moves over a figure, without using the “WindowButtonMotionFcn”. In a previous article (http://undocumentedmatlab.com/blog/inactive-control-tooltips-event-chaining/), one of your special guests explained that you can do something like that attaching a listener to the “WindowButtonMotionEvent” (with the syntax handle.listener(gcf,’WindowButtonMotionEvent’,@myFigMouseMove)) . This works very well but unfortunately, the only EventData that you can retrieve is the CurrentPoint, which is quite poor. I would prefer to retrieve the MouseEvent java object.
    Do you know if there is a way of retrieving MouseEvent in matlab figures and attach a listener to it ?
    It would also be very useful to retrieve KeyEvent…
    Thank you very much in advance for your help,
    Julien

    • Yair Altman December 4, 2010 at 11:27 Reply

      @Julien – this was answered here: http://undocumentedmatlab.com/blog/uicontrol-callbacks/#comment-22139

      In your case, you need to use the MouseMovedCallback property.

  2. matt dash December 8, 2010 at 13:54 Reply

    Could this method be used to have matlab run a callback when changes are made to a jtable? (I know i should just be able to use a uitable as a jtable, but uitable drives me crazy with everything else it does…)

    • Yair Altman December 8, 2010 at 14:17 Reply

      @Matt – yes, if you attach a Java event and wrap it as described in the article above. However, I think it would be *much* easier to simply attach a handle.listener on the relevant Java event/property, or simpler still – to attach a regular Matlab callback on the events already exposed by the Java object (e.g., DataChangedCallback, which is a callback-able property of the JTable model if I remember correctly).
      – Yair

      • matt dash December 8, 2010 at 14:29

        Oh good, i was hoping there would be a much simpler way 😀 I’m still pretty new to java. I had checked before and didn’t see any relevant callbacks for JTable, but now I see that DefaultTableModel has TableChangedCallback that seems to do what I need it to. I’ll also check out handle.listener… it’s been a while since I looked at Matlab’s listener capabilities. I didn’t realize you could add them to general java objects… i thought they were just for Matlab’s handle graphics stuff. Thanks a lot for the info!

      • Yair Altman December 8, 2010 at 15:07

        @Matt – take a look at this article, which presents three separate ways of accessing Java events using callbacks and handle.listener: http://undocumentedmatlab.com/blog/continuous-slider-callback/

  3. Anonymous December 21, 2010 at 08:15 Reply

    Wow, that is tremendous! Great work. Though I have to say, running a live trading system on matlab and even undocumented matlab features is probably not wise on so many levels.

    • Anonymous June 20, 2012 at 04:32 Reply

      @Anonymous – some of the biggest quant hedge funds in the world would disagree with you on this.

  4. Yunde Zhong February 18, 2011 at 09:56 Reply

    Great work. I have one question: It seems the matlab callback is dynamically (a-synchronously) invoked. Is there any solution to synchronouly invoke the matlab callback in your example? Thanks.

    For example, if we add two lines to the function “notifyMyTest()”

    public void notifyMyTest() {
       java.util.Vector dataCopy;
       synchronized(this) {
          dataCopy = (java.util.Vector)data.clone();
       }
       for (int i=0; i<dataCopy.size(); i++) {
          MyTestEvent event = new MyTestEvent(this, 0, 1);
          System.out.println("Starting calling Callbacks...");
          ((MyTestListener)dataCopy.elementAt(i)).testEvent(event);
          System.out.println("Callbacks called");
       }
    }

    public void notifyMyTest() { java.util.Vector dataCopy; synchronized(this) { dataCopy = (java.util.Vector)data.clone(); } for (int i=0; i<dataCopy.size(); i++) { MyTestEvent event = new MyTestEvent(this, 0, 1); System.out.println("Starting calling Callbacks..."); ((MyTestListener)dataCopy.elementAt(i)).testEvent(event); System.out.println("Callbacks called"); } }

    We will see the prints as following:
    ———–
    Starting calling Callbacks…
    Callbacks called
    9.7656e-004
    ———–
    It looks like the Matlab callabck is invoked after the java code returns. Any suggestions? Thanks.

    • Yair Altman February 19, 2011 at 09:21 Reply

      @Yunde – yes, this is how it works: the Matlab callback function is invoked on a different thread and the threads are not synchronized. In most cases this is exactly how we need it to behave. If you require synchronization, here’s one way to solve this: You could have your Matlab function set some internal Java property when it ends its processing, and have the original Java code wait (sleep) until it detects that the property value has been changed.

  5. Alessio March 8, 2011 at 06:51 Reply

    Well done!!! That’s what I need!!! However, I don’t understand something about Java code, in particular about TestEvent.class:

    1) Why are “addMyTestListener”, “removeMyTestListener” and notifyMyTest() methods declared “synchronized”?

    2) Why does “notifyMyTest()” execute “data.clone()”??

    3) For realizing callback, do I always have to implement an interface that extends java.util.EventListener??? If I don’t make it, for example I use an interface don’t extends java.util.EventListener, does it work???

    Thanks in advance!!!!!

    Alessio

    • Yair Altman March 9, 2011 at 08:52 Reply

      @Alessio –

      1 + 2) this is an attempt to make the code re-entrant, i.e. enable several Java threads to access the class concurrently. Note that only the code surrounding access to data is synchronized.

      3) java.util.EventListener is an interface without any declared fields, properties or methods. It is simply used as a flag to indicate that the object is, well, an EventListener. All of your interface’s internal methods (testEvent() in this case) are user-defined methods. Behind the scenes, Matlab converts all such Java methods into Matlab callbacks, so testEvent() is automatically converted into TestEventCallback. In short – feel free to test variations of my code (it won’t bite you). Now that you have a working base, this should be easy. It was much harder for me when I didn’t have an initial working base…

  6. Dan March 17, 2011 at 05:30 Reply

    Dear Yair, though this request might seem out of topic, I would like to ask you if, referring to your sentence above ” Few other challenges were as difficult, yet with a happy ending (Drag & Drop is a similar issue – I will describe it in another article sometime) “, you could kindly point me to that “happy ending” you mention.

    I am trying to implement a Drag & Drop function that would allow me to rearrange a Matlab listbox rows with a mouse drag & drop technique on the same listbox (that is, by dragging and dropping its rows in the desired position).

    All I have been able to find on the subject (close to), was a discussion by you and others left unfinished on the Mathworks website back in 2009.

    Thank you in advance.

    Dan

    • Erik Koopmans July 27, 2012 at 09:23 Reply

      Hi Dan,

      I recently ran into the exact same problem, and found a solution. I’ve explained the solution over here:
      http://undocumentedmatlab.com/blog/setting-listbox-mouse-actions/#comment-99126

      And I’ve created a utility that creates reorderable lists, available on the Matlab File Exchange:
      http://www.mathworks.com/matlabcentral/fileexchange/37642-reorderable-listbox

      All the best!

      -Erik

  7. iroln March 17, 2011 at 08:07 Reply

    Hi Yair,

    Is it possible to somehow handle the event PaintEvent of Java component in MATLAB (override methods paint and update)?

    For example, I’m creating a JPanel in MATLAB window and want to catch the paint event in a MATLAB function.

    hf = figure; 
    jhp = javacomponent(javax.swing.JPanel, [10 10 200 200], hf);
     
    function paint()
         % this processing of event PaintEvent for jhp
    end

    hf = figure; jhp = javacomponent(javax.swing.JPanel, [10 10 200 200], hf); function paint() % this processing of event PaintEvent for jhp end

    Can I do this? Can I do write a class in Java, which is derived from JPanel with events for the paint()?

    • Yair Altman March 20, 2011 at 15:28 Reply

      @Iroln – this is an interesting idea. I never tried it, but I see no reason (except performance) why you cannot create a new Java class that derives JPanel and have the event delegated to Matlab using the mechanism described in the article above. Note that the paint event needs to receive the correct parameters (Graphics object and whatnot).

      Interesting idea indeed – please do post your findings (or a sample code) here, after you have experimented with it.

  8. Frank March 27, 2011 at 12:07 Reply

    Thanks Yair for this post.
    However, I’m doing everything your way and when I use your last line
    ‘hListener = handle.listener(handle(evt),’TestEvent’,callback) ‘
    I get the error = Undefined function or variable ‘Callback’
    Is there anything missing ?

    • Yair Altman March 27, 2011 at 12:38 Reply

      @Frank – you forgot to define your callback, so of course you get an error when you try to use it in your listener. In my code I used the following callback definition:

      callback = @(o,e) cbBridge(o,e,response);

      callback = @(o,e) cbBridge(o,e,response);

      • Frank March 28, 2011 at 17:59

        Thanks for the answer Yair. I’m still struggling a bit. How can I get the oldValue and newValue in Matlab on every event ? May be with the hgfeval but I still don’t see how. Does a getvalue in the class myTestEvent would allow this and how would be the optimal way to get it from hgfeval ?

      • Yair Altman March 29, 2011 at 00:43

        @Frank – since both oldValue and newValue were declared as public, you can access them in your callback function as follows:

        function myCallbackFcn(hObject, eventData)
          oldVal = eventData.oldValue;
          newVal = eventData.newValue;
          ...
        end  %myCallbackFcn

        function myCallbackFcn(hObject, eventData) oldVal = eventData.oldValue; newVal = eventData.newValue; ... end %myCallbackFcn

        Of course, a better way would be to declare oldValue and newValue as private in the Java class, and to have only public accessor methods. For example:

        public class MyTestEvent extends java.util.EventObject {
          private static final long serialVersionUID = 1L;
          private float oldValue, newValue;
          public float getOldValue() { return oldValue; }
          public float getNewValue() { return newValue; }
          MyTestEvent(Object obj, float oldValue, float newValue) {
            super(obj);
            this.oldValue = oldValue;
            this.newValue = newValue;
          }
        }

        public class MyTestEvent extends java.util.EventObject { private static final long serialVersionUID = 1L; private float oldValue, newValue; public float getOldValue() { return oldValue; } public float getNewValue() { return newValue; } MyTestEvent(Object obj, float oldValue, float newValue) { super(obj); this.oldValue = oldValue; this.newValue = newValue; } }

        You would then access these values in the Matlab callback as follows:

        function myCallbackFcn(hObject, eventData)
          oldVal = eventData.getOldValue;  % alternative #1
          oldVal = get(eventData,'OldValue');  % alternative #2
          ...
        end  %myCallbackFcn

        function myCallbackFcn(hObject, eventData) oldVal = eventData.getOldValue; % alternative #1 oldVal = get(eventData,'OldValue'); % alternative #2 ... end %myCallbackFcn

  9. Alessio March 29, 2011 at 07:55 Reply

    Hi,

    Using the callback mechanism shown above, I realized a simple MATLAB + JAVA application that, from a “Java Layer”, generates Java event handled by Matlab function. In the software developed, Java code was inserted in a ‘.jar’ file (jar_app.jar). If I test the JAVA + MATLAB application developed using MATLAB, it works fine, but if I create an executable with MATLAB Compiler for it using the command

    mcc -m Demo_ Matlab_Java_App.m

    and then execute it from command prompt, I have the following error:

    java.lang.NullPointerException 
    at com.mathworks.jmi.bean.MatlabBeanInterface.addCallback(MatlabBeanInterface.java:765) 
    at com.mathworks.jmi.bean.MatlabCallbackInterface.addCallback(MatlabCallbackInterface.java:128)

    java.lang.NullPointerException at com.mathworks.jmi.bean.MatlabBeanInterface.addCallback(MatlabBeanInterface.java:765) at com.mathworks.jmi.bean.MatlabCallbackInterface.addCallback(MatlabCallbackInterface.java:128)

    Reading other posts regarding this exception, it seems (but I’m not sure…) that ‘.jar’ file with java code isn’t detected; Probably, executable doesn’t access to the MATLAB “classpath.txt” file.
    Also, in Matlab code, I add this instruction:

    javaaddpath('C:Alessioworkspace_matlabnew_appjar_app.jar');

    javaaddpath('C:Alessioworkspace_matlabnew_appjar_app.jar');

    but I think that it is unuseless; executable dosen’t work… How can I do to resolve this problem and realize a working executable??
    I hope that problem is clear… If it isn’t clear, please tell me, thank you…

    greetings

    • Yair Altman March 29, 2011 at 08:18 Reply

      @Alessio – your theory is correct: the error that you see is exactly the error that can be seen in a regular Matlab desktop when trying to set callbacks to Java classes that were added using the dynamic (rather than the static) Java classpath.

      Try to place a classpath.txt file that contains your JAR file in your compiled application’s start-up folder. If my hunch is correct, this could solve your problem.

      • Alessio March 30, 2011 at 01:12

        Thanks Yair for your suggest…Finally, now all works fine ;-)!!!!!!!!!!!

        Again, Thanks a lot for all!!!!

  10. Alessio June 17, 2011 at 07:21 Reply

    Hi Yair,

    I just realized a new Java + Matlab application using Matlab Callback for Java Events mechanism that you suggest in this article. Java-side, I have a net-application containing a Server Thread and a Client Thread; Server Thread, after opening a ServerSocket, acquires a value (randomly generated at the moment) every 50 msec (“production value” rate), places it in a byte array (length 2) together with a sequence number (generated value in array position 1 seqNo in array position 2), and send it to the Java Client Thread through socket. Client Thread receives byte array (value + seqNo), puts it in a java event and finally notifies Matlab application using testEvent(event) method. The Matlab function invoked after the call of ‘testEvent(event)’ processes the value contained in the event and writes it in a ‘.txt’ file.

    After executing some test, I noticed that sometimes prints on file realized from Matlab after testEvent(event) invocations aren’t executed in the correct order; For example, if Java Client Thread receives byte arrays in the order , , , , , could be that Matlab printing (and processing) function writes this sequence (for example) in this order: , , , , even if the invocation of eventTest(event) are the following: eventTest(event()), eventTest(event()), eventTest(event()), eventTest(event()), eventTest(event()), eventTest(event())…

    Is testEvent(event) a synchronous method? If it isn’t, how can I do to have synchronous called of testEvent(event) method???

    Certainly, it isn’t a Matlab ‘printf’ problem. Infact, during debugging, I print on screen the event received from Matlab printing and processing function, the “call order” isn’t respected….

    I hope that my problem is clear….If it isn’t, please tell me, thank you!!

    Thanks a lot!!!

    • Alessio June 17, 2011 at 07:53 Reply

      I have a problem in posting the message….I repeat the second part of message here…

      After executing some test, I noticed that sometimes prints on file realized from Matlab after testEvent(event) invocations aren’t executed in the correct order; For example, if Java Client Thread receives byte arrays in the order, {val0, 50}, {val1, 51}, {val2, 52}, {val3, 53}, {val4, 54} could be that Matlab printing (and processing) function writes this sequence (for example) in this order: {val2, 52}, {val3, 53}, {val4, 54}, {val0, 50}, {val1, 51}, even if the invocation of eventTest(event) are the following: eventTest(event({val0, 50})), eventTest(event({val1, 51})), eventTest(event({val2, 52})), eventTest(event({val3, 53})), eventTest(event({val4, 54}))…

    • michele August 12, 2011 at 09:59 Reply

      Hey guys, any luck regarding this? I’m observing the same behavior and I was wondering if you found a way to capture events in the same order as they’ve been dispatched.

      Thanks

  11. matlab September 5, 2011 at 02:33 Reply

    well done !!!!!!!! that’s it vat I need…..!

  12. Matlab-Java memory leaks, performance | Undocumented Matlab January 20, 2012 at 07:31 Reply

    […] Each time the Matlab callback function is invoked, it reads the event information from the Java object […]

  13. Lex February 9, 2012 at 08:43 Reply

    Hi,

    I try to start your example, but maybe don’t understand something.

     evt.notifyMyTest

    evt.notifyMyTest

    doesn’t show any result as in your case.

    I tried to debug it, but

    java.util.Vector data

    java.util.Vector data

    is empty, so it won’t be notified any of listeners. What do I do wrong?

    Here is my code in matlab:

    evt = package.EventTest
    set(evt)
    set(evt,'TestEventCallback',@(h,e)disp(h))
    evt.notifyMyTest

    evt = package.EventTest set(evt) set(evt,'TestEventCallback',@(h,e)disp(h)) evt.notifyMyTest

    Should set(evt,’TestEventCallback’,@(h,e)disp(h)) add a listener? Or were do I add a listener?

    Thanks

  14. Mike January 24, 2013 at 10:20 Reply

    I tried doing this simple example, but it didn’t work as expected.

    I copied and pasted the EventTest class into a .java file and compiled it. As expected, it generated the 3 .class files. I put them on the static path and restarted Matlab. Matlab 2012b complained about the $ characters in the class file names, so I created a jar file and put that on the static path, again restarting Matlab. After that, I could run

    import EventTest.*

    import EventTest.*

    successfully. I could create evt as in the example, and get its properties. When I ran

    set(evt,'TestEventCallback',@(h,e)disp(h))

    set(evt,'TestEventCallback',@(h,e)disp(h))

    I ran into an error:

    java.lang.NullPointerException
    	at com.mathworks.jmi.bean.MatlabBeanInterface.addCallback(MatlabBeanInterface.java:765)
    	at com.mathworks.jmi.bean.MatlabCallbackInterface.addCallback(MatlabCallbackInterface.java:130)

    java.lang.NullPointerException at com.mathworks.jmi.bean.MatlabBeanInterface.addCallback(MatlabBeanInterface.java:765) at com.mathworks.jmi.bean.MatlabCallbackInterface.addCallback(MatlabCallbackInterface.java:130)

    Checking that it did get set with

    get(evt,'TestEventCallback')

    get(evt,'TestEventCallback')

    yielded the result:

    ans = 
        @(h,e)disp(h)

    ans = @(h,e)disp(h)

    That looked like the callback was correctly set, so I went ahead and ventured to try

    evt.notifyMyTest

    evt.notifyMyTest

    but nothing was returned. Matlab just went right back to the next command line.

    Should it actually display a value as shown in the example? If not, how do I know it actually did what it should do?

    • Yair Altman January 24, 2013 at 10:25 Reply

      @Mike – this is a symptom that happens when Matlab is not loading the JAR file properly in the static path. Check your classpath.txt file again, then restart Matlab and retest. Ensure that you are not using javaaddpath anywhere in your code to load the Java classes.

      • Mike January 24, 2013 at 12:18

        Thanks for responding so quickly. I checked my classpath.txt and decided to change file separators. javaclasspath produced results with Windows-style backslashes while classpath.txt had *nix-style slashes. I went with the Windows-style this time, and now it seems to work as advertised. I don’t know why that should make a difference — Matlab is typically happy to work with either file separator, but that seems to be the difference.

  15. Przemek Lach January 31, 2013 at 20:35 Reply

    Hi,

    I tried running your example in Matlab 2012b but I get the following error when I try to do a ‘which’ or ‘import’ on the Matlab command line:

    Warning: A Java exception occurred trying to load the EventTest class:
    Java exception occurred:
    java.lang.UnsupportedClassVersionError: EventTest : Unsupported major.minor version 51.0
    	at java.lang.ClassLoader.defineClass1(Native Method)
    	at java.lang.ClassLoader.defineClass(Unknown Source)
    	at java.security.SecureClassLoader.defineClass(Unknown Source)
    	at java.net.URLClassLoader.defineClass(Unknown Source)
    	at java.net.URLClassLoader.access$000(Unknown Source)
    	at java.net.URLClassLoader$1.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(Unknown Source)
    	at java.lang.ClassLoader.loadClass(Unknown Source)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    	at java.lang.ClassLoader.loadClass(Unknown Source)
    	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    	at java.lang.Class.forName0(Native Method)
    	at java.lang.Class.forName(Unknown Source)
    	at com.mathworks.jmi.OpaqueJavaInterface.findClass(OpaqueJavaInterface.java:470)

    Warning: A Java exception occurred trying to load the EventTest class: Java exception occurred: java.lang.UnsupportedClassVersionError: EventTest : Unsupported major.minor version 51.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at com.mathworks.jmi.OpaqueJavaInterface.findClass(OpaqueJavaInterface.java:470)

    I tried adding the .class files using the way you said originally in your example but also using a .jar file as someone else mentioned earlier. I have no idea where to begin looking here. I’m running Matlab on Scientific Linux 6.3 although that shouldn’t matter since Matlab has its own JVM as far as I understand it.

    • Yair Altman February 1, 2013 at 01:35 Reply

      @Przemek – this happens because you compiled your Java code with a Java-7 compiler, while Matlab still only supports Java 6. Modify your Java compiler’s settings to use Java 6. For even better compatibility, to also run on Matlab versions 7.0.4 (R14SP2) to 7.4 (R2007a), compile using Java 5.

    • Przemek Lach February 1, 2013 at 09:45 Reply

      Thanks for your reply. I keep forgetting about this Java version thing in Matlab. This problem has plagued me in the past.

  16. Przemek Lach February 1, 2013 at 13:17 Reply

    Some more confusion on my side; some quick background. I’m using RabbitMQ, more specifically, I’m using a RabbitMQ callback function in Java that will received messages from outside the system asynchronously. So, a callback in my Java will get the message and that message needs to be passed into matlab via an event. My idea is to use your code to pass this event. The payload will be a JSON so just a string. Here is the Java code that I’ve slightly modified:

    public class Java2MatlabEvent {
    	private java.util.Vector data = new java.util.Vector();
     
    	public synchronized void addJ2MListener(J2MListener lis) {
    		data.addElement(lis);
    	}
     
    	public synchronized void removeJ2MListener(J2MListener lis) {
    		data.removeElement(lis);
    	}
     
    	public interface J2MListener extends java.util.EventListener {
    		void javaEvent(J2MEvent event);
    	}
     
    	public class J2MEvent extends java.util.EventObject {
    		private static final long serialVersionUID = 1L;
    		public String message;
     
    		J2MEvent(Object obj, String inMessage) {
    			super(obj);
    			this.message = inMessage;
    		}
    	}
     
    	public void notifyMyTest() {
    		java.util.Vector dataCopy;
    		synchronized (this) {
    			dataCopy = (java.util.Vector) data.clone();
    		}
    		for (int i = 0; i < dataCopy.size(); i++) {
    			J2MEvent event = new J2MEvent(this, "Hello World");
    			dataCopy.elementAt(i).javaEvent(event);
    		}
    	}
    }

    public class Java2MatlabEvent { private java.util.Vector data = new java.util.Vector(); public synchronized void addJ2MListener(J2MListener lis) { data.addElement(lis); } public synchronized void removeJ2MListener(J2MListener lis) { data.removeElement(lis); } public interface J2MListener extends java.util.EventListener { void javaEvent(J2MEvent event); } public class J2MEvent extends java.util.EventObject { private static final long serialVersionUID = 1L; public String message; J2MEvent(Object obj, String inMessage) { super(obj); this.message = inMessage; } } public void notifyMyTest() { java.util.Vector dataCopy; synchronized (this) { dataCopy = (java.util.Vector) data.clone(); } for (int i = 0; i < dataCopy.size(); i++) { J2MEvent event = new J2MEvent(this, "Hello World"); dataCopy.elementAt(i).javaEvent(event); } } }

    so my understanding is that this code would return the string “Hello World” to the Matlab event listener. Here is the Matlab code:

    classdef Test < handle
        properties
            event;
            hListener;
        end
     
        methods
            function obj = Test()
                obj.event = Java2MatlabEvent;
                set(obj.event, 'JavaEventCallback', @(h,e)disp(h));
                %obj.hListener = handle.listener(handle(obj.event),'JavaEventCallback', @(h,e)javaCallback(h));
                obj.event.notifyMyTest;
            end
     
            function javaCallback(obj, eventData)
                disp('javaCallback');
                disp(get(eventData, 'message'));
            end
        end
    end

    classdef Test < handle properties event; hListener; end methods function obj = Test() obj.event = Java2MatlabEvent; set(obj.event, 'JavaEventCallback', @(h,e)disp(h)); %obj.hListener = handle.listener(handle(obj.event),'JavaEventCallback', @(h,e)javaCallback(h)); obj.event.notifyMyTest; end function javaCallback(obj, eventData) disp('javaCallback'); disp(get(eventData, 'message')); end end end

    So this code returns a number in scientific notation which makes no sense to me. When I run it several times the numbers change. Here is the output from several runs: R1: 9.7656e-04 R2: 1.0010 R3: 2.0010 R4: 3.0010.

    I’m also uncertain what the ‘h’, ‘e’ variables represent. I also tried doing this using the handle.listener way (commented out code) but in that case the javaCallback was never called. Am a missing something small here or am I completely out to lunch?

    • Przemek Lach February 11, 2013 at 19:06 Reply

      So I’ve been at this for a week now and I have been able to get your example to work. If I understand things correctly, you call evt.notifyMyTest for the sake of this tutorial; in reality the notifMyTest would be called by something in your Java program and the event that gets generated as a result of that would travel up into the Matlab callback for that event?

      • Yair Altman February 12, 2013 at 10:10

        @Przemek – yes, exactly

    • Reza August 13, 2015 at 11:32 Reply

      @Przemek, did you get the RabbitMQ stuff to work in Matlab with events triggering matlab functions?

      I’d appreciate a chat if you have time. mojo2023 at gmail

      thanks.

      /r

  17. Priya March 13, 2013 at 06:29 Reply

    hi,
    I have a matlab script that displays an image. I have also written a java swing program with a button. Now, I need to call the above mentioned script when I click that button. Is it possible to call the matlab script from java using event handling??

    • Yair Altman March 13, 2013 at 06:36 Reply

      @Priya – you can do this using the Matlab Builder for Java toolbox, or via the undocumented COM/JMI/JNI interfaces. Read chapter 9 in my Matlab-Java book, or search this website for matlabcontrol.

      • Priya March 13, 2013 at 07:39

        Thank you. But, it says that i have to run it in the matlab command prompt only. Not possible to run it in the normal command prompt?? Because i don’t want to run it in the matlab command window. Is it possible to run it like a normal java code??

        and i found that the examples are generally mathematical functions. Will you please give an example with an image? It will help me to understand it better.

      • Yair Altman March 13, 2013 at 10:06

        @Priya – I find it difficult to understand what you mean. If you want to run your Matlab function (script file) from Java you can use MatlabControl to simply issue the relevant string for Matlab to execute. You don’t need any command line for this. The examples in the article about using the Matlab command line were only to demonstrate how to use MatlabControl.

        Or you can use JMI/COM/JMI, as I explain in my book with some examples (there is even a specific example that displays a Matlab figure window from Java using JNI).

      • Priya March 13, 2013 at 23:00

        What do you mean by relevant string?? Is it the name of the script file that i have created in matlab??

      • Yair Altman March 14, 2013 at 01:24

        yes

      • Priya March 14, 2013 at 01:26

        thank you so much for your immediate response . i will definitely try it out .

  18. Priya March 19, 2013 at 08:06 Reply
    textSaveName='Enter file name';
    h=uicontrol(FigWin,...
       'Style','pushbutton',...
    	'Position',[0,120,80,20],...
    	'String','save',...
       'Callback',...
       ['W=inputdlg(textSaveName);W=char(W);'...
        'save(W,''image1'',''bmp'');']);

    textSaveName='Enter file name'; h=uicontrol(FigWin,... 'Style','pushbutton',... 'Position',[0,120,80,20],... 'String','save',... 'Callback',... ['W=inputdlg(textSaveName);W=char(W);'... 'save(W,''image1'',''bmp'');']);

    I am getting the image name from user and saving image1 as asbmp image. But i am getting an error.
    Can you please point out the mistake i have made.

    • Priya March 19, 2013 at 23:13 Reply

      i am sorry but i dont know where to post this question..

       function image1=matchin
      [image1, pathname]= uigetfile('*.bmp','Open An image');
      Directory = fullfile ('F:','matlab','bin');
      D = dir(fullfile(Directory,'*.bmp'));
      imcell = cell(1,numel(D));
      for i = 1:numel(D)
        imcell{i} = imread(fullfile(Directory,D(i).name));
       end
      for j=1:numel(imcell)
          if image1==imcell{j}
            disp('matched');
          else
              disp('not matched');
          end
      end

      function image1=matchin [image1, pathname]= uigetfile('*.bmp','Open An image'); Directory = fullfile ('F:','matlab','bin'); D = dir(fullfile(Directory,'*.bmp')); imcell = cell(1,numel(D)); for i = 1:numel(D) imcell{i} = imread(fullfile(Directory,D(i).name)); end for j=1:numel(imcell) if image1==imcell{j} disp('matched'); else disp('not matched'); end end

      I am getting the name of an image from user and checking if it matches with other images..If i use imread() and perform the matching, it is working but,i am unable to compare it if i get it from user.

      • Yair Altman March 20, 2013 at 00:45

        Priya – this is not a general forum for Matlab questions. You can ask these questions in the Matlab newsgroup or the Matlab Answers forum.

        Specifically, you need to use the strcmpi function to compare strings, you cannot use ==

      • Priya March 20, 2013 at 08:08

        Sorry Mr.Yair but i am really in need of the code…sorry and thank you

  19. Will June 11, 2013 at 10:07 Reply

    Hi Yair,

    Thanks for posting this article. Interesting that we are still commenting on it years later 🙂

    I have an interesting problem. When I compiled this and instantiate the object in Matlab (r2012b) I never can see any events via events(jObj). I have tried many variations of the code, using static/dynamic class path, etc. But I am always faced with the same problem: “no events for class com.blah.TestClass”

    I have also looked at a few other guides along this same line for pure Java, so I mostly understand what is going on with the interface and the interaction between the different functions in the event generation class.

    If you would like I will post my code. But it is essentially identical to yours. Maybe you came across this in your testing and know what to look for?

    Thanks,
    Will

    • Yair Altman June 11, 2013 at 13:44 Reply

      @Will – it’s probably a static classpath issue. If you’d like my consulting help on your project, please contact me offline (via email)

    • Will June 12, 2013 at 09:32 Reply

      Hi Yair,

      You were right. A while after writing, I was forced to shut down my Matlab instance, which I had been running since working on this project.

      Just in case this helps anyone else, even when using the dynamic class path, you can instantiate the event producer class, but any changes made to the interface section (the part where you define the event callback names) will NOT be updated until you restart Matlab.

      Also, I could see the events when I restarted Matlab and loaded the event producer class from the dynamic path, but then I got that NullPointerException error so many others have seen when trying to hookup a Matlab listener to a custom Java event.

      So my problem was ultimately not in the Java code, but Matlab’s bad behavior with the dynamic java class path!

      I was misled in this regard as I have built an extensive Java gui which I have working just fine using the dynamic class path. Lesson learned. Custom events = static class path or else!

      Thanks for your help, Yair.

  20. Donn Shull June 12, 2013 at 09:48 Reply

    It is important to remember that UDD and MCOS are separate object systems. The command events(obj) displays the events for MCOS objects but does not display the events for UDD/java objects.

  21. Florian Franzen July 27, 2013 at 13:15 Reply

    Hello Yair,

    I was able to use this trick to run Matlab code in the EDT by calling javaMethodEDT(‘notifyMyListener’, evt) after assigning the function I want to run as the TestEventCallback.

    While this solves my problem well, I was wondering if you do know an easier way to do this?

    Greetings,
    Florian Franzen

    • Yair Altman July 27, 2013 at 13:35 Reply

      @Florian – if you use javaObjectEDT(evt) then all methods that you call on evt from then on in Matlab will use the EDT. You could then simply use evt.notifyMyListener().

    • Florian Franzen August 5, 2013 at 06:59 Reply

      @Yair: I know, but this still requires me to have a Java class file similar to your EventTest in my static class path.

      All I want to do is run matlab code on the EDT (to get around some timer digital i/o limitation of the stupid new session-based interface).

      Is there a way to archive this (and by this I mean run a matlab java callback in EDT) without using any custom java code?

      Thank you,
      Florian

    • Jim Hokanson February 5, 2018 at 06:21 Reply

      See http://undocumentedmatlab.com/blog/matlab-and-the-event-dispatch-thread-edt

      Specifically the callbackOnEDTQueue at the end.

  22. Eric Faust October 15, 2013 at 15:46 Reply

    I’m curious if this could help with a message pipeline to stop the execution of a function (i.e. help set a global variable that would be examined at intervals, and execution would cease in the function if necessary). My scenario:
    – I want to wrap a GUI around a series of student-developed functions (some take 30+ minutes to execute)
    – Would like to make as few changes as possible to their code
    – Need a way to fire off one of these functions, but still get GUI events so I can respond

    I’m calling ‘drawnow’ and have a semi-responsive interface (I can move the window, usually), but still not getting any GUI events like a click on the close box. I’m a new to the Matlab GUI side of things, and I’m mostly a C++/pthreads guy so this is all foreign territory for me..

    Cheers,
    -Eric

    • Yair Altman October 15, 2013 at 16:15 Reply

      Matlab’s main processing is single threaded. I can’t think of any solution except modifying your scripts to include pause() or some condition checks (maybe there is, I just can’t think of any other solution).

  23. Daniel Malmquist April 24, 2014 at 01:55 Reply

    This method to hook up java events seems to be broken in 2014a. Same machine, same configuration. This is result from 2014a:

    >> loadjgraphx
    Hooking up jgraphxcustom
    ans =
    loadjgraphx@7eab0d73
     
    >> get(ans)
              AllowDanglingEdges: 1
                      AllowLoops: 0
        AllowNegativeCoordinates: 1
              AlternateEdgeStyle: ''
                      AutoOrigin: 0
                   AutoSizeCells: 0
                          Border: 0
                   CellsBendable: 1
                  CellsCloneable: 1
                  CellsDeletable: 1
             CellsDisconnectable: 1
                   CellsEditable: 1
                     CellsLocked: 0
                    CellsMovable: 1
                  CellsResizable: 1
                 CellsSelectable: 1
         ChangesRepaintThreshold: 1000
                           Class: [1x1 java.lang.Class]
               CloneInvalidEdges: 0
         CollapseToPreferredSize: 1
                ConnectableEdges: 0
               ConstrainChildren: 1
                     CurrentRoot: []
                DefaultLoopStyle: [1x1 com.mxgraph.view.mxEdgeStyle$2]
                  DefaultOverlap: 0.5000
                   DefaultParent: [1x1 com.mxgraph.model.mxCell]
                DisconnectOnMove: 1
                     DropEnabled: 1
               EdgeLabelsMovable: 1
                         Enabled: 1
                     EventSource: []
                   EventsEnabled: 1
                   ExtendParents: 1
              ExtendParentsOnAdd: 1
                     GraphBounds: [1x1 com.mxgraph.util.mxRectangle]
                     GridEnabled: 1
                        GridSize: 10
                      HtmlLabels: 0
                    ImageBundles: [0 java.util.LinkedList]
           KeepEdgesInBackground: 0
           KeepEdgesInForeground: 0
                   LabelsClipped: 0
                   LabelsVisible: 1
              MaximumGraphBounds: []
                MinimumGraphSize: []
                           Model: [1x1 com.mxgraph.model.mxGraphModel]
                      Multigraph: 1
                  Multiplicities: []
                          Origin: [1x1 com.mxgraph.util.mxPoint]
                    PortsEnabled: 1
             ResetEdgesOnConnect: 1
                ResetEdgesOnMove: 0
              ResetEdgesOnResize: 0
           ResetViewOnRootChange: 1
                   SelectionCell: []
                  SelectionCells: [0x1 java.lang.Object[]]
                  SelectionCount: 0
                  SelectionEmpty: 1
                  SelectionModel: [0 com.mxgraph.view.mxGraphSelectionModel]
                    SplitEnabled: 1
                      Stylesheet: [1x1 com.mxgraph.view.mxStylesheet]
                 SwimlaneNesting: 1
             VertexLabelsMovable: 0
                            View: [1x1 com.mxgraph.view.mxGraphView]

    >> loadjgraphx Hooking up jgraphxcustom ans = loadjgraphx@7eab0d73 >> get(ans) AllowDanglingEdges: 1 AllowLoops: 0 AllowNegativeCoordinates: 1 AlternateEdgeStyle: '' AutoOrigin: 0 AutoSizeCells: 0 Border: 0 CellsBendable: 1 CellsCloneable: 1 CellsDeletable: 1 CellsDisconnectable: 1 CellsEditable: 1 CellsLocked: 0 CellsMovable: 1 CellsResizable: 1 CellsSelectable: 1 ChangesRepaintThreshold: 1000 Class: [1x1 java.lang.Class] CloneInvalidEdges: 0 CollapseToPreferredSize: 1 ConnectableEdges: 0 ConstrainChildren: 1 CurrentRoot: [] DefaultLoopStyle: [1x1 com.mxgraph.view.mxEdgeStyle$2] DefaultOverlap: 0.5000 DefaultParent: [1x1 com.mxgraph.model.mxCell] DisconnectOnMove: 1 DropEnabled: 1 EdgeLabelsMovable: 1 Enabled: 1 EventSource: [] EventsEnabled: 1 ExtendParents: 1 ExtendParentsOnAdd: 1 GraphBounds: [1x1 com.mxgraph.util.mxRectangle] GridEnabled: 1 GridSize: 10 HtmlLabels: 0 ImageBundles: [0 java.util.LinkedList] KeepEdgesInBackground: 0 KeepEdgesInForeground: 0 LabelsClipped: 0 LabelsVisible: 1 MaximumGraphBounds: [] MinimumGraphSize: [] Model: [1x1 com.mxgraph.model.mxGraphModel] Multigraph: 1 Multiplicities: [] Origin: [1x1 com.mxgraph.util.mxPoint] PortsEnabled: 1 ResetEdgesOnConnect: 1 ResetEdgesOnMove: 0 ResetEdgesOnResize: 0 ResetViewOnRootChange: 1 SelectionCell: [] SelectionCells: [0x1 java.lang.Object[]] SelectionCount: 0 SelectionEmpty: 1 SelectionModel: [0 com.mxgraph.view.mxGraphSelectionModel] SplitEnabled: 1 Stylesheet: [1x1 com.mxgraph.view.mxStylesheet] SwimlaneNesting: 1 VertexLabelsMovable: 0 View: [1x1 com.mxgraph.view.mxGraphView]

    Result for 2013b looks like expected:

    >> loadjgraphx
    Hooking up jgraphxcustom
    ans =
    loadjgraphx@1d0dc7ac
     
    >> get(ans)
    	AllowDanglingEdges = on
    	AllowLoops = off
    	AllowNegativeCoordinates = on
    	AlternateEdgeStyle = 
    	AutoOrigin = off
    	AutoSizeCells = off
    	Border = [0]
    	CellsBendable = on
    	CellsCloneable = on
    	CellsDeletable = on
    	CellsDisconnectable = on
    	CellsEditable = on
    	CellsLocked = off
    	CellsMovable = on
    	CellsResizable = on
    	CellsSelectable = on
    	ChangesRepaintThreshold = [1000]
    	Class = [ (1 by 1) java.lang.Class array]
    	CloneInvalidEdges = off
    	CollapseToPreferredSize = on
    	ConnectableEdges = off
    	ConstrainChildren = on
    	CurrentRoot = []
    	DefaultLoopStyle = [ (1 by 1) com.mxgraph.view.mxEdgeStyle$2 array]
    	DefaultOverlap = [0.5]
    	DefaultParent = [ (1 by 1) com.mxgraph.model.mxCell array]
    	DisconnectOnMove = on
    	DropEnabled = on
    	EdgeLabelsMovable = on
    	Enabled = on
    	EventSource = []
    	EventsEnabled = on
    	ExtendParents = on
    	ExtendParentsOnAdd = on
    	GraphBounds = [ (1 by 1) com.mxgraph.util.mxRectangle array]
    	GridEnabled = on
    	GridSize = [10]
    	HtmlLabels = off
    	ImageBundles = [ (1 by 1) java.util.LinkedList array]
    	KeepEdgesInBackground = off
    	KeepEdgesInForeground = off
    	LabelsClipped = off
    	LabelsVisible = on
    	MaximumGraphBounds = []
    	MinimumGraphSize = []
    	Model = [ (1 by 1) com.mxgraph.model.mxGraphModel array]
    	Multigraph = on
    	Multiplicities = []
    	Origin = [ (1 by 1) com.mxgraph.util.mxPoint array]
    	PortsEnabled = on
    	ResetEdgesOnConnect = on
    	ResetEdgesOnMove = off
    	ResetEdgesOnResize = off
    	ResetViewOnRootChange = on
    	SelectionCell = []
    	SelectionCells = [ (0 by 1) java.lang.Object[] array]
    	SelectionCount = [0]
    	SelectionEmpty = on
    	SelectionModel = [ (1 by 1) com.mxgraph.view.mxGraphSelectionModel array]
    	SplitEnabled = on
    	Stylesheet = [ (1 by 1) com.mxgraph.view.mxStylesheet array]
    	SwimlaneNesting = on
    	VertexLabelsMovable = off
    	View = [ (1 by 1) com.mxgraph.view.mxGraphView array]
    	TestEventCallback = 
    	TestEventCallbackData = []
    	PropertyChangeCallback = 
    	PropertyChangeCallbackData = []
     
    	BeingDeleted = off
    	ButtonDownFcn = 
    	Children = []
    	Clipping = on
    	CreateFcn = 
    	DeleteFcn = 
    	BusyAction = queue
    	HandleVisibility = on
    	HitTest = on
    	Interruptible = on
    	Parent = []
    	Selected = off
    	SelectionHighlight = on
    	Tag = 
    	Type = loadjgraphx
    	UIContextMenu = []
    	UserData = []
    	Visible = on

    >> loadjgraphx Hooking up jgraphxcustom ans = loadjgraphx@1d0dc7ac >> get(ans) AllowDanglingEdges = on AllowLoops = off AllowNegativeCoordinates = on AlternateEdgeStyle = AutoOrigin = off AutoSizeCells = off Border = [0] CellsBendable = on CellsCloneable = on CellsDeletable = on CellsDisconnectable = on CellsEditable = on CellsLocked = off CellsMovable = on CellsResizable = on CellsSelectable = on ChangesRepaintThreshold = [1000] Class = [ (1 by 1) java.lang.Class array] CloneInvalidEdges = off CollapseToPreferredSize = on ConnectableEdges = off ConstrainChildren = on CurrentRoot = [] DefaultLoopStyle = [ (1 by 1) com.mxgraph.view.mxEdgeStyle$2 array] DefaultOverlap = [0.5] DefaultParent = [ (1 by 1) com.mxgraph.model.mxCell array] DisconnectOnMove = on DropEnabled = on EdgeLabelsMovable = on Enabled = on EventSource = [] EventsEnabled = on ExtendParents = on ExtendParentsOnAdd = on GraphBounds = [ (1 by 1) com.mxgraph.util.mxRectangle array] GridEnabled = on GridSize = [10] HtmlLabels = off ImageBundles = [ (1 by 1) java.util.LinkedList array] KeepEdgesInBackground = off KeepEdgesInForeground = off LabelsClipped = off LabelsVisible = on MaximumGraphBounds = [] MinimumGraphSize = [] Model = [ (1 by 1) com.mxgraph.model.mxGraphModel array] Multigraph = on Multiplicities = [] Origin = [ (1 by 1) com.mxgraph.util.mxPoint array] PortsEnabled = on ResetEdgesOnConnect = on ResetEdgesOnMove = off ResetEdgesOnResize = off ResetViewOnRootChange = on SelectionCell = [] SelectionCells = [ (0 by 1) java.lang.Object[] array] SelectionCount = [0] SelectionEmpty = on SelectionModel = [ (1 by 1) com.mxgraph.view.mxGraphSelectionModel array] SplitEnabled = on Stylesheet = [ (1 by 1) com.mxgraph.view.mxStylesheet array] SwimlaneNesting = on VertexLabelsMovable = off View = [ (1 by 1) com.mxgraph.view.mxGraphView array] TestEventCallback = TestEventCallbackData = [] PropertyChangeCallback = PropertyChangeCallbackData = [] BeingDeleted = off ButtonDownFcn = Children = [] Clipping = on CreateFcn = DeleteFcn = BusyAction = queue HandleVisibility = on HitTest = on Interruptible = on Parent = [] Selected = off SelectionHighlight = on Tag = Type = loadjgraphx UIContextMenu = [] UserData = [] Visible = on

    Note the missing testeventcallback in the 2014a output compared to the 2013b one. The jar is in the static path in both cases. Any ideas?

    • Yair Altman April 24, 2014 at 08:18 Reply

      @Daniel – use the handle wrapper as described here

      jObject = handle(loadjgraphx, 'CallbackProperties');

      jObject = handle(loadjgraphx, 'CallbackProperties');

  24. janaachen May 7, 2014 at 23:32 Reply

    Hey,
    this approach does not seem to work with matlab 2014a anymore.
    The Java Object does not expose the callbacks anymore.

    Jan

    • janaachen May 7, 2014 at 23:34 Reply

      ok.. i just saw the comment above.. thanks

  25. Matlab callbacks for Java events in R2014a | Undocumented Matlab May 8, 2014 at 03:27 Reply

    […] than Matlab’s standard uicontrols. Three years ago I wrote a related article showing how to trap any Java events as simple Matlab callbacks, even those from custom Java classes. This worked very well over the years, until now.Over the past […]

  26. sameh March 9, 2015 at 12:37 Reply

    Can the Matlab callback assigned to the java event return a value to java ?

    • Yair Altman March 9, 2015 at 12:43 Reply

      @Sameh – the Matlab callback can call a Java method of the Java object and pass one or more values to this method as input arguments.

  27. Dave March 16, 2015 at 13:55 Reply

    If the class in interest does not embed the interface and only provides a method to add a listener can this still be hooked into Matlab? E.g. I am trying to add a ChangeEventListener and hook the event into Matlab. Is this possible?

    • Dave March 16, 2015 at 14:06 Reply

      Figured it out! Thanks for the great posts.

      • Yair Altman March 17, 2015 at 06:04

        @Dave – just saying that you “figured it out” is not helpful to anyone. Post your solution for the benefit of other readers. Otherwise why should anyone take the time to answer you in the future?

  28. Interfacing C# and MATLAB Using Events | A Place of Memory June 10, 2015 at 22:48 Reply

    […] looking to implement events and listeners like I am it is slightly a bit more difficult. This blog has a pretty detailed guide of how to do this along with some other neat tricks that’s not […]

  29. Sathish July 25, 2015 at 06:39 Reply

    Hi,

    Thanks for the life saving tutorial. I tried to follow the steps mentioned above but when i say evt.get am getting below response.

    evt.get
        Class: [1x1 java.lang.Class]
    set(evt)
    struct with no fields.

    evt.get Class: [1x1 java.lang.Class] set(evt) struct with no fields.

    Because of it am not able to add any of call back. Kindly help

    PS – Classes are compiled using jdk1.5, matlab version – R2014a 32 bit

    • Sathish July 25, 2015 at 07:02 Reply

      Sorry to bother before reading the above comments properly. Just adding h = handle(evt,'CallbackProperties'); worked like a charm 🙂

      >> h = handle(evt,'CallbackProperties');
      >> set(evt,'TestEventCallback',@(h,e)myCallbackFcn(h,e))
      >> get(evt)
                          Class: [1x1 java.lang.Class]
              TestEventCallback: @(h,e)myCallbackFcn(h,e)
          TestEventCallbackData: []

      >> h = handle(evt,'CallbackProperties'); >> set(evt,'TestEventCallback',@(h,e)myCallbackFcn(h,e)) >> get(evt) Class: [1x1 java.lang.Class] TestEventCallback: @(h,e)myCallbackFcn(h,e) TestEventCallbackData: []

      Thanks

  30. Jan October 23, 2015 at 00:13 Reply

    Hi,
    the workaround with the handle(h,’CallbackProperties’); call does not work in matlab 2015b anymore.

    is there another way to solve this?

    thanks

    Jan

    • Yair Altman October 23, 2015 at 03:08 Reply

      @Jan – I believe that you are mistaken. It still works well in R2015b. Perhaps you have a bug in your code.

  31. Rainer March 11, 2016 at 15:51 Reply

    Hi,
    also thank you for providing this very helpful tutorial, which works very well. In my application I use the event call back (here ‘process_message’) to receive data from a java class and to update a GUIDE gui, respectively.

    set(evt,'TestEventCallback',@(h,e)process_message(h,e))

    set(evt,'TestEventCallback',@(h,e)process_message(h,e))

    However, I encounter the problem that the event callback / data update rate is very high and completely blocks other processing in MATLAB. Is there any option to run ‘process_message’ in a separate thread? I have also read your article regarding async threads via timers, but I am puzzled how I can apply the described technique to this usecase. Any ideas?

    Thanks,
    Rainer

    • Yair Altman March 11, 2016 at 15:56 Reply

      @Rainer – the callbacks fire on the Main Matlab thread (MT) unless you cause your Java control to run on Java’s Event Dispatch Thread (EDT)

  32. Dims March 14, 2016 at 18:20 Reply

    Also no any callbacks added automatically. What can be wrong?

    • Yair Altman April 8, 2016 at 01:23 Reply

      @Dims – see http://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events-in-r2014a

  33. Tianxiao Jiang April 7, 2016 at 22:30 Reply

    Hi Yair
    I have written a customized JTree and planning to forward the tree selection event to matlab. I copied your example but encountered a problem (BTW, there is a typo of datacopy, should be dataCopy):

    >> !javac EventTest.java
    Note: EventTest.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
     
    >> which EventTest
    EventTest is a Java method  % EventTest constructor
     
    >> evet=EventTest
    evet =
    EventTest@684fc515
     
    >> evet.get
        Class: [1x1 java.lang.Class]
     
    >> set(evet)
    ans = 
    struct with no fields.

    >> !javac EventTest.java Note: EventTest.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. >> which EventTest EventTest is a Java method % EventTest constructor >> evet=EventTest evet = EventTest@684fc515 >> evet.get Class: [1x1 java.lang.Class] >> set(evet) ans = struct with no fields.

    I am using Matlab2016a now. Seems like get method no longer returns the interface callbacks. Could you give me a hint ?

    Thanks

    • Yair Altman April 8, 2016 at 01:22 Reply

      @Tianxiao – see http://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events-in-r2014a

      (and thanks for the note on the dataCopy typo – I fixed it)

  34. Adam Gogacz May 3, 2016 at 16:18 Reply

    Hi,
    Yair, can you comment on the memory leakage associated with using “set” on Java objects( http://www.mathworks.com/help/matlab/ref/set.html )? I frequently use “set” on “ActionPerformedCallback” for Java objects, any workarounds?
    KR,
    Adam

    • Adam Gogacz May 3, 2016 at 16:46 Reply

      @mySelf
      The answer is here (http://undocumentedmatlab.com/blog/uicontrol-callbacks#memory_leak) thanks for that post. BTW, I wish Mathworks linked to your articles :).
      Thanks again.

      • Yair Altman May 3, 2016 at 17:34

        @Adam – if TMW linked to my blog it wouldn’t be “undocumented” Matlab any longer, would it? 🙂

    • Adam Gogacz May 3, 2016 at 19:53 Reply

      @Yair
      I just checked that “augmentedmatlab.com” domain name is still available 🙂

  35. Zangdaarr August 15, 2016 at 16:30 Reply

    Hi,

    This class is really great and helpful, thanks for this !
    There are however some issues with types and types checking, so I made a small refactor to adress those issues. Changes are essentially not using raw types, and some changes to the notifyMatlab(Object obj, MatlabAction action) method. Also, I split the sub interface and class in their own files.

    package com.opalrt.efpgasim.gui.matlablistener;
     
    import java.util.Vector;
    import com.opalrt.efpgasim.gui.enumerations.MatlabAction;
    /**
     * 
     * @author http://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events
     */
     
    public class MatlabEvent {
     
    	public interface MatlabListener extends java.util.EventListener {
    		void testEvent(MatlabEventObject event);
    	}
     
    	private Vector data = new Vector();
     
    	public synchronized void addMatlabListener(MatlabListener lis) {
    		data.addElement(lis);
    	}
     
    	public synchronized void removeMatlabListener(MatlabListener lis) {
    		data.removeElement(lis);
    	}
     
    	public synchronized void printMatlabListener()
    	{
    		System.out.println(data.toString());
    		for (int i = 0; i < data.size(); i++) {
    			System.out.println("i = " + i + " is " + data.elementAt(i).toString());
    		}
    	}
     
    	public void notifyMatlab(Object obj, MatlabAction action) {
    		Vector dataCopy;
    		synchronized (this) {
    			dataCopy = new Vector(data);
    		}
     
    		for (int i = 0; i < dataCopy.size(); i++) {
    			MatlabEventObject matlabEvent = new MatlabEventObject(this, obj, action);
    			((MatlabListener) dataCopy.elementAt(i)).testEvent(matlabEvent);
    		}
    	}
     
    	public class MatlabEventObject extends java.util.EventObject {
    		private static final long serialVersionUID = 1L;
    		private Object obj;
    		private MatlabAction action;
     
    		public MatlabEventObject(Object source, Object obj, MatlabAction action) {
    			super(source);
    			this.obj = obj;
    			this.action = action;
    		}
     
    		public Object getObj() {
    			return obj;
    		}
     
    		public void setObj(Object obj) {
    			this.obj = obj;
    		}
     
    		public MatlabAction getAction() {
    			return action;
    		}
     
    		public void setAction(MatlabAction action) {
    			this.action = action;
    		}		
    	}	
    }

    package com.opalrt.efpgasim.gui.matlablistener; import java.util.Vector; import com.opalrt.efpgasim.gui.enumerations.MatlabAction; /** * * @author http://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events */ public class MatlabEvent { public interface MatlabListener extends java.util.EventListener { void testEvent(MatlabEventObject event); } private Vector data = new Vector(); public synchronized void addMatlabListener(MatlabListener lis) { data.addElement(lis); } public synchronized void removeMatlabListener(MatlabListener lis) { data.removeElement(lis); } public synchronized void printMatlabListener() { System.out.println(data.toString()); for (int i = 0; i < data.size(); i++) { System.out.println("i = " + i + " is " + data.elementAt(i).toString()); } } public void notifyMatlab(Object obj, MatlabAction action) { Vector dataCopy; synchronized (this) { dataCopy = new Vector(data); } for (int i = 0; i < dataCopy.size(); i++) { MatlabEventObject matlabEvent = new MatlabEventObject(this, obj, action); ((MatlabListener) dataCopy.elementAt(i)).testEvent(matlabEvent); } } public class MatlabEventObject extends java.util.EventObject { private static final long serialVersionUID = 1L; private Object obj; private MatlabAction action; public MatlabEventObject(Object source, Object obj, MatlabAction action) { super(source); this.obj = obj; this.action = action; } public Object getObj() { return obj; } public void setObj(Object obj) { this.obj = obj; } public MatlabAction getAction() { return action; } public void setAction(MatlabAction action) { this.action = action; } } }

  36. RichardST February 8, 2019 at 16:01 Reply

    Hello Yair,
    Is this still meant to work in later versions of MATLAB?

    With my version of
    MATLAB Version 9.4 (R2018a)
    My results are:

    >> evt = EventTest
    evt =
    EventTest@71652c98
    >> get(evt)
        Class: [1×1 java.lang.Class]
    >> set(evt,'TestEventCallback',@(h,e)disp(h))
    >> evt.notifyMyTest
    	javahandle_withcallbacks.EventTest

    >> evt = EventTest evt = EventTest@71652c98 >> get(evt) Class: [1×1 java.lang.Class] >> set(evt,'TestEventCallback',@(h,e)disp(h)) >> evt.notifyMyTest javahandle_withcallbacks.EventTest

    Have I done something silly?
    Thank you for your help.
    Richard S-T (who owns both ‘Undocumented’ and ‘Accelerating’)

    • RichardST February 8, 2019 at 17:21 Reply

      Hello All,
      Ok, I see that I was doing wrong. I needed to:
      i) wrap the event in a handle, as per the advice above
      ii) change the callback to display the event’s properties

      >> evt = EventTest
      evt =
      EventTest@5d332969
      >> h = handle(evt,'Callbackproperties')
      h =
      	javahandle_withcallbacks.EventTest
      >> set(evt,'TestEventCallback',@(h,e)disp([e.newValue e.oldValue]))
      >> evt.notifyMyTest
           1     0
      >> get(evt)
                          Class: [1×1 java.lang.Class]
              TestEventCallback: @(h,e)disp([e.newValue,e.oldValue])
          TestEventCallbackData: []

      >> evt = EventTest evt = EventTest@5d332969 >> h = handle(evt,'Callbackproperties') h = javahandle_withcallbacks.EventTest >> set(evt,'TestEventCallback',@(h,e)disp([e.newValue e.oldValue])) >> evt.notifyMyTest 1 0 >> get(evt) Class: [1×1 java.lang.Class] TestEventCallback: @(h,e)disp([e.newValue,e.oldValue]) TestEventCallbackData: []

      Thank you for your help, Yair.
      Richard

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top