« Earlier8 items total Later »

Debug Java Objects In Matlab

For Matlab R14+ you can start Matlab as


Alternatively again you can start matlab with some command line flags.

matlab -jdb


And then you can connect to Matlab over port 4444 with any JPDA-supporting debugger (NetBeans, Sun Studio, Eclipse, etc.).

For lower versions of Matlab the following advice may help. First read the below information on the java.opts file.


http://www.mathworks.com/support/solutions/data/28748.shtml



Then add the following parameters to the java.opts file

-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,address=8888,suspend=n


or, alternatively, if you are on Windows system, you could use

-Xdebug
-Xrunjdwp:transport=dt_shmem,address=matlab,server=y,suspend=n


ATTENTION!!! Each option must be on a separate line in the java.opts file, otherwise Java will not initialize properly.

GUI Tables

Here is a simple way to use java tables in matlab. I've wrapped the standard java table model with a matlab data model. Nested functions are taken advantage of to provide data set and get methods, cell rendering and entry validation.

% XTARGETS_UITABLE
%
% t = xtargets_uitable(table, rows, cols, getfun, setfun, labelfun, editfun)
%
% Arguments
%   table     Any instance or subclass instance of javax.swing.JTable
%   rows      numbers of rows
%   cols      number of cols
%   getfun    function handle for aquiring data to the table.
%             val = getfun(row, col)
%   setfun    function handle for setting data to the table.
%             setfun(row, col, val)
%   labelfun  function handle for generating a label in the table
%             string = labelfun(row, col, val)
%   editfun   function handle for validating string input
%             value = editfun(row, col, string)
%             throw an error if the string is invalid
%             to show a dialog box and reset the old value
%             of the cell
%   table    an instance of javax.swing.JTable or a subclass of
%
% Example
%   See xtargets_uitable_test
%

% Copyright Brad Phelan (C) 2005 under the LGPL license
% http://xtargets.com
function t = xtargets_uitable(table, rows, cols, getfun, setfun, labelfun, editfun)


    import javax.swing.*;
    import javax.swing.table.*;
    import ca.odell.renderpack.*;

    tableModel = javax.swing.table.DefaultTableModel(rows,cols);

    % Initialize the table model
    for r = 1:rows
       for c = 1:cols
           tableModel.setValueAt(labelfun(r,c,getfun(r,c)),r-1,c-1);
       end
    end

    table.setModel(tableModel);


    scroller = JScrollPane(table);
    scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);


    [hcom, hg] = javacomponent(scroller);
    hg = handle(hg);
    p = schema.prop(hg,'table','mxArray');
    hg.table = handle(table);
    set(hg,'position',[0 0 200 200]);

    %Fix for JTable focus bug : see http://www.mycgiserver.com/~Kleopatra/swing/table/merlineditfun.html
    table.putClientProperty('terminateEditOnFocusLost', java.lang.Boolean.TRUE);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);


    t = hg;

    % A flag to avoid change handler recursion
    syncchange = false;

    set(tableModel, 'TableChangedCallback', @change_fcn);
    function change_fcn(src, ev)
        if syncchange
            % This change was invoked from this handler
            syncchange = false;
            return
        end
        syncchange = true;

        row = ev.getFirstRow;
        col = ev.getColumn;

        string = tableModel.getValueAt(row,col);

        row = row + 1;
        col = col + 1;
        % Perform validation on the string and convert it to a value
        try
            val = editfun(row, col, string);
            setfun(row,col,val);
            tableModel.setValueAt(labelfun(row,col,val), row-1,col-1);
        catch
            errordlg(lasterr,'Invalid Edit');
            % The value was not valid so reset the cell
            tableModel.setValueAt(labelfun(row,col,getfun(row,col)), row-1,col-1);
        end

    end
end


A test function demonstrates the behaviour of the table with a simple data model and validation.

% xtargets_uitable_test
%
% A simple example of using the table model to modify data in
% a nested function workspace. The data is in double format
% so we use the '%g' sscanf pattern to render and read the
% data from the table cells.

% Copyright Brad Phelan (C) 2005 under the LGPL license
% http://xtargets.com
function xtargets_uitable_test
    close all;

    data = rand(5);

    table = javax.swing.JTable;

    % Create a uitable with a simple matlab data model. Specify
    % that the conversion class will be %g.
    t = xtargets_uitable(table, 5,5, @getfun, @setfun, @labelfun, @editfun);

    function val = getfun( row, col)
       val = data(row,col);
    end

    function setfun( row, col, val)
       data(row,col) = val;
    end

    function val = editfun(row, col, string)
        val = sscanf(string, '%g');
        if isempty(val)
            error([ '''' string ''' is not a valid entry' ]);
        end
    end

    function label = labelfun(row, col, val)
         label = sprintf('%g',val);
    end

    % uicontrol to display the data model on the command line
    uicontrol('string','push me','position',[300 0 100 50], ...
        'callback',@disp_data);

    function disp_data(src,ev)
        disp(data);
    end
end

Adding Callbacks to uitable

The basic uitable object in matlab is just a peer for the true table. To expose all the possible callbacks do the following


>> t = uitable;
>> tj = t.getTable;
>> set(tj)



gives you



ComponentHiddenCallback: string -or- function handle -or- cell array
ComponentMovedCallback: string -or- function handle -or- cell array
ComponentResizedCallback: string -or- function handle -or- cell array
ComponentShownCallback: string -or- function handle -or- cell array
MouseDraggedCallback: string -or- function handle -or- cell array
MouseMovedCallback: string -or- function handle -or- cell array
PropertyChangeCallback: string -or- function handle -or- cell array
FocusGainedCallback: string -or- function handle -or- cell array
FocusLostCallback: string -or- function handle -or- cell array
CaretPositionChangedCallback: string -or- function handle -or- cell array
InputMethodTextChangedCallback: string -or- function handle -or- cell array
KeyPressedCallback: string -or- function handle -or- cell array
KeyReleasedCallback: string -or- function handle -or- cell array
KeyTypedCallback: string -or- function handle -or- cell array
MouseClickedCallback: string -or- function handle -or- cell array
MouseEnteredCallback: string -or- function handle -or- cell array
MouseExitedCallback: string -or- function handle -or- cell array
MousePressedCallback: string -or- function handle -or- cell array
MouseReleasedCallback: string -or- function handle -or- cell array
HierarchyChangedCallback: string -or- function handle -or- cell array
VetoableChangeCallback: string -or- function handle -or- cell array
ComponentAddedCallback: string -or- function handle -or- cell array
ComponentRemovedCallback: string -or- function handle -or- cell array
AncestorMovedCallback: string -or- function handle -or- cell array
AncestorResizedCallback: string -or- function handle -or- cell array
AncestorMovedCallback_: string -or- function handle -or- cell array
AncestorAddedCallback: string -or- function handle -or- cell array
AncestorRemovedCallback: string -or- function handle -or- cell array
MouseWheelMovedCallback: string -or- function handle -or- cell array
ButtonDownFcn: string -or- function handle -or- cell array



You add the callback like

set(tj,'MouseClickedCallback',@(handle,event)disp('hello world'));


The handle is argument to the callback is the handle to the uitable and the event is a subclass of java.awt.event.

Calling Matlab From Java

Here is a class I built as part of my matlab distributed computing tool. It uses Java 1.5 with generics and variable argument lists to create a reasonably simple interface to Matlab functions.

The function object is thread safe and blocks until matlab returns the result.



import com.mathworks.jmi.*;

import java.util.concurrent.*;

/**
 * Represents a blocking matlab function call. Adds the ability to call a matlab
 * function in a thread safe manner. The function call to execute the matlab
 * function takes a variabe length argument list.
 *
 * @author Brad
 *
 */
public class MatlabFunction<T> {

    private class Completion implements CompletionObserver {

        private T returnValue;

        private Semaphore semaphore = new Semaphore(0);

        /*
         *
         * @see com.mathworks.jmi.CompletionObserver#completed(int,
         *      java.lang.Object)
         */
        @SuppressWarnings("unchecked")
        public void completed(int arg0, Object arg1) {
            returnValue = (T) arg1;
            semaphore.release();
        }

        T getReturnValue() {
            try {
                semaphore.acquire();
                return returnValue;
            } catch (InterruptedException e) {
                return null;
            }
        }
    }

    /** The name of the matlab function */
    String function;

    /** Handle to the matlab object */
    Matlab matlab = new Matlab();

    /**
     * Create a thread safe blocking matlab function object
     *
     * @param function
     *            The name of the matlab function
     */
    public MatlabFunction(String function) {
        this.function = function;
    }

    /**
     * Execute the matlab function
     *
     * @param args
     *            Variable input arguments
     * @return the result of the matlab function.
     */
    public T execute(Object... args) {
        Completion completion = new Completion();
        matlab.feval(function, args, completion);
        return completion.getReturnValue();
    }

}


Use the class like

MatlabFunction<double []> f = new MatlabFunction<double []>("times");
double x[] = f.execute(10,20);


The function should return the value 20

Just remember that you can't call this from the Matlab command line. It will deadlock and hang your Matlab. This should only be run from a seperate thread not directly invoked by the Matlab thread.

If you get a ClassCastException when running this then Matlab is returning a datatype different to what you have specified in the generics specification. Use a debugger to figure out what kind of datatype is being returned by matlab.

Loading Groovy Scripts In Matlab

Groovy is a neat java like scripting language which is much neater for writing small scripts.

The below code shows how to load groovy scripts into matlab. It involves registering the groovy classloader with the matlab classloader. ( Took me ages to figure this one out ).

function klass = groovy_load_class(script);
    import groovy.lang.*;
    import com.mathworks.jmi.*;

    % Locate the script on the matlab path
    script = which(script);

    % Get the system class loader
    p_loader = java.lang.ClassLoader.getSystemClassLoader;

    % Create the Groovy class loader
    loader = GroovyClassLoader(p_loader);

    % Register the class loader with the matlab
    % environments
    com.mathworks.jmi.OpaqueJavaInterface.registerClassLoader(loader);

    % Parse the groovy class
    klass = loader.parseClass(java.io.File(script));


It will find the script on the Matlab path and load it returning the java class handle of the new class. You can then create new instances of it as if it were a normal java class.

klass = groovy('MyGroovyClass.groovy');
h = com.xtargets.MyGroovyClass;

Change the title of the matlab window

QUO posted this on that matlab newsgroup. If you want to change the title of the Matlab main window here is a function that will do the job.

function changetitle(str)

   %first get all of the Java frames present in the current JVM
   frms = java.awt.Frame.getFrames();

   %now, let's look through those frames for one that seems like it
might be the main frame
   root = [];
   for m = 1:length(frms)
      if strcmpi(get(frms(m),'Type'), ...
             'com.mathworks.mde.desk.MLMainFrame')
           root = frms(m);
         break;
      end
   end
   if isempty(root)
      error('Could not find my main frame')
   end
   set(root,'Title',str)

Adding new java classes to your matlab path.

There are three things you can do. Either add the full path to the jar or class files directory into classpath.txt

$matlabroot/java/jarext/xalan.jar
$matlabroot/java/jarext/xercesImpl.jar
$matlabroot/java/jarext/xml-apis.jar
$matlabroot/java/jarext/groovy-all-1.0-jsr-01.jar
mac=/System/Library/Java
c:\projects\myjars\mycooljavaproject.jar


or use the dynamic java classpath commands.

javaaddpath

Creating Java Objects

To use java within matlab you first have to import the package you wish to use.

import javax.swing.*


Then to create a new object you use the matlab syntax for creating objects. That is you leave out the "new" keyword. For example

a = JButton;

« Earlier8 items total Later »




Sponsored by

Sole Central

Your one stop shop for Birkenstock and Crocs shoes and sandles.