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

The javacomponent function

August 4, 2010 68 Comments

In this blog I have often showed how using Java components can significantly improve Matlab GUI. Here is a simple reminder:

sample Java components integrated in Matlab figure window (click for details)
sample Java components integrated in Matlab figure window (click for details)

Matlab is highly integrated with Java, and Java classes can seamlessly be accessed from Matlab. However, displaying Java GUI objects, as opposed to using computational (non-displayable) Java classes, requires using Matlab’s built-in javacomponent function. I have often used this function in past articles here, and today I would like to describe it in more detail.

javacomponent

javacomponent, available since R14 (Matlab 7.0), is yet another semi-documented built-in function. This means that the function is explained in a comment within the function (which can be seen via the edit(‘javacomponent’) command), but nonetheless does not have official help or doc pages. It is an unsupported function originally intended only for internal Matlab use (which of course doesn’t mean we can’t use it).
javacomponent accepts a component class name (a string) or a reference to a previously-created component object, an optional pixel position parameter (default=[20,20,60,20], just like uicontrol; may also contain the strings ‘North’, ‘South’, ‘East’ or ‘West’), and an optional parent container handle (defaults to the current figure). javacomponent then adds the requested component as a child of the requested parent container and wraps it in a Matlab Handle-Graphics (HG) container. javacomponent returns two handles: the Matlab HG container handle and a reference (handle) to the Java component. Here are some sample invocation formats:

>> [jButton, hButton] = javacomponent('javax.swing.JButton')
hButton =
	javahandle_withcallbacks.javax.swing.JButton
jButton =
          158.002197265625
>> javacomponent('javax.swing.JButton','North');
>> javacomponent(javax.swing.JButton('Click me!'),[50,40,80,30]);
>> javacomponent(javax.swing.JButton('Click me!'),'East',hFig);

>> [jButton, hButton] = javacomponent('javax.swing.JButton') hButton = javahandle_withcallbacks.javax.swing.JButton jButton = 158.002197265625 >> javacomponent('javax.swing.JButton','North'); >> javacomponent(javax.swing.JButton('Click me!'),[50,40,80,30]); >> javacomponent(javax.swing.JButton('Click me!'),'East',hFig);

Note the difference between Java object creation and javacomponent: A pre-created Java object only resides in JVM (Java Virtual Machine) memory, not onscreen, until javacomponent is called to display it. javacomponent only creates objects when a class name (string) parameter is passed to it, as a convenience service to programmers. In practice, it is better to separate these two actions: create the Java object separately, and then pass the object’s reference handle to javacomponent for display. This enables easier error-trapping if the Java object cannot be created or fails to initialize, before attempting to display the object:

% Create and initialize a JScrollBar object
try
   jScrollbar = javaObjectEDT('javax.swing.JScrollBar');
   jScrollbar.setOrientation(jScrollbar.HORIZONTAL);
catch
   error('Cannot create Java-based scroll-bar!');
end
% Display the object onscreen
try
   javacomponent(jScrollbar,'South');
catch
   error('Cannot display Java-base scroll-bar!');
end

% Create and initialize a JScrollBar object try jScrollbar = javaObjectEDT('javax.swing.JScrollBar'); jScrollbar.setOrientation(jScrollbar.HORIZONTAL); catch error('Cannot create Java-based scroll-bar!'); end % Display the object onscreen try javacomponent(jScrollbar,'South'); catch error('Cannot display Java-base scroll-bar!'); end

Note that Java GUI object should always use the EDT (Event Dispatch Thread). The reasons for this were outlined in the recent Matlab-EDT article. For this reason, the JScrollBar is created using the built-in javaObjectEDT function, which exists since R2008a and became documented/supported in R2009a.
javacomponent accepts parent handles that are figures, toolbars, uipanels or uicontainers. Unfortunately, frames are not uicontainers and therefore cannot be used as javacomponent parents. Addendum Aug 6 2010: I made an incorrect statement in the original post here regarding uipanels, which has now been removed. I thank the reader who pointed this out to me.
Once the component has been created, even before it has been placed onscreen, it can be manipulated just like any other Java object. For example:

jButton.setText('Click again!');  % or: set(jButton,'text','…')

jButton.setText('Click again!'); % or: set(jButton,'text','…')

The component can also be manipulated to some extent via its HG container, which is of a special Matlab type (class) called hgjavacomponent. This includes getting/setting the component position, position units, visibility, resizing callback, tag, UserData etc:

set(hButton,'units','norm', 'position',[0.2,0.3,0.1,0.05]);
set(hButton,'visible','off'); %note: on/off, not true/false as in Java
set(hButton,'ResizeFcn',{@resizeCallbackFunc,param1,param2});

set(hButton,'units','norm', 'position',[0.2,0.3,0.1,0.05]); set(hButton,'visible','off'); %note: on/off, not true/false as in Java set(hButton,'ResizeFcn',{@resizeCallbackFunc,param1,param2});

When adding Java components which are container classes (descendants of java.awt.Container), it is important to remember that only other Java components can be added to these containers. Matlab objects such as axes (for plots or images) and uicontrols cannot be added since they do not have a Container wrapper. Therefore, feel free to use these Java containers as long as their contained GUI is limited to Java components (JButton, JComboBox etc.). This limitation is very annoying – it would be very useful to be able to place Matlab axes or uicontrols within a JTabbedPane or JSplitPane. Instead, we need to rely on Matlab-based workarounds (uitab and uisplitpane) which are cumbersome compared to their Java counterparts.
javacomponent can be used to place not only Swing components but also Swing-extended components onscreen. Matlab itself almost never uses Swing components as-is, instead preferring to use MathWorks-derived extensions of these components, generally in the com.mathworks.mwswing or com.mathworks.widgets packages. These packages and their classes are all in the static Java classpath and are therefore automatically available for use by Matlab programmers.
Just like Matlab components, javacomponent can also display third-party or your own Swing-derived components. There are quite a few online sources for Swing components that can easily be incorporated in your Matlab application. Simply download the relevant class files, add them to your static (via classpath.txt) or dynamic (via javaaddpath) Java classpath, use javacomponent to display them, then use their reference handle to manipulate their appearance and behavior.
javacomponent, useful as it is, has several limitations. In its string variant (classname) it requires a fully-qualified classname that is not inferred automatically. It also has a different parameters format than uicontrol, which may confuse users. javacomponent also cannot display java.awt.Window components. Finally, it returns two handles – one is a handle() reference of the Java object; the second an HG handle (a double numeric value) of the automatically-created HG container – users are often confused as to which property should be set on which of these handles.

javacomponent-based utility functions

To overcome these limitations, I created UIComponent – a utility that merges uicontrol and javacomponent, available for download on the File Exchange. It accepts all uicontrol parameters and styles, as well as any other displayable Java (Swing/AWT) class. uicontrol‘s calling syntax was preserved for full backwards compatibility. uicomponent uses the built-in uicontrol whenever possible (for standard Matlab styles), and javacomponent for all other Java classes.
uicomponent returns the same two handles that javacomponent returns (namely, a Java reference handle and a numeric HG handle), modified to include each other’s properties and handles (yet another undocumented trick that merits a dedicated article). Here are some examples (more can be found in uicomponent‘s help comment):

uicomponent('style','edit', 'String','hello');  % a regular uicontrol
uicomponent(hFig, 'style','edit', 'String','hello'); % specify parent
uicomponent('style','jspinner','value',7);
uicomponent('style','javax.swing.jslider','tag','myObj');
uicomponent('style','JComboBox',{1,pi,'text'},'editable',true);

uicomponent('style','edit', 'String','hello'); % a regular uicontrol uicomponent(hFig, 'style','edit', 'String','hello'); % specify parent uicomponent('style','jspinner','value',7); uicomponent('style','javax.swing.jslider','tag','myObj'); uicomponent('style','JComboBox',{1,pi,'text'},'editable',true);

Another File Exchange submission which aims to tackle some of javacomponent‘s limitations is Malcolm Lidierth’s JCONTROL. jcontrol uses Matlab’s new object-oriented class approach and has the benefit of returning just a single handle object, which aggregates the handles for both HG container and the contained Java object.

Related posts:

  1. Common javacomponent problems – The javacomponent function is very useful for placing Java components on-screen, but has a few quirks. ...
  2. Javacomponent background color – This article explains how to align Java component background color with a Matlab color....
  3. Function definition meta-info – There are multiple ways to retrieve meta-info about functions in Matlab. ...
  4. The hgfeval function – The semi-documented hgfeval function can be useful for callback chaining - this article explains how...
  5. ismembc – undocumented helper function – Matlab has several undocumented internal helper functions that can be useful on their own in some cases. This post presents the ismembc function....
  6. sprintfc – undocumented helper function – The built-in sprintfc function can be used to quickly generate a cell-array of formatted strings. ...
GUI Handle graphics Java schema.prop Semi-documented function uicontrol
Print Print
« Previous
Next »
68 Responses
  1. cdm September 30, 2010 at 11:36 Reply

    Is it possible to get html links working using this method?
    Something like the following (which doesn’t work):
    **[edited for clarity]**

    hEdit = uicontrol('style','edit','max',80,'pos',[20,20,150,20]);
    jEdit = findjobj(hEdit);
    vEdit = jEdit.getViewport;
    wEdit = vEdit.getComponent(0);
    wEdit.setEditorKit(javax.swing.text.html.HTMLEditorKit);
    set(wEdit,'Text','<a href="http://www.google.com" rel="nofollow">Go to Google!</a>');

    hEdit = uicontrol('style','edit','max',80,'pos',[20,20,150,20]); jEdit = findjobj(hEdit); vEdit = jEdit.getViewport; wEdit = vEdit.getComponent(0); wEdit.setEditorKit(javax.swing.text.html.HTMLEditorKit); set(wEdit,'Text','<a href="http://www.google.com" rel="nofollow">Go to Google!</a>');

    This works, even underlines the links and colors them blue, but won’t open a browser if you click on them. Thoughts?

  2. Fixing a Java focus problem | Undocumented Matlab October 20, 2010 at 11:02 Reply

    […] An aspect of Matlab GUIs that include Java components that is often encountered (most recently reported yesterday) and is easily fixed, is Matlab’s default exclusion of all javacomponents from its focus traversal cycle. […]

  3. MJJ January 31, 2011 at 09:39 Reply

    Are there any work-arounds to get a component to fill the entire figure area (pane), so resizing works well?
    e.g.

    javacomponent('javax.swing.JButton','East');

    javacomponent('javax.swing.JButton','East');

    would create a button but it would only be attached to the right-handed side of the pane. If a button is created in pure Java with borderlayout and is placed in the center, it will expand to fill the entire parent, and also resize with it.

    • Yair Altman January 31, 2011 at 12:28 Reply

      @Martin (MJJ) – yes, this is possible: javacomponent returns two handles if you use its regular invocation form: javacomponent(component,position,container) (i.e., not the form that you have used) – the second handle is a handle to the regular HG Matlab container. You can easily modify this HG container’s Units property to ‘normalized’ and this will keep your component’s size and position synchronized with its container. If the container if the figure, you’re all set. If not, then you need to also fix the container and so on, just as you would do for any Matlab HG control.

      If you need finer-grained control (for example: attach to bottom-right, while preserving the pixel size), you can always trap the container’s ResizeFcn and modify the component size and/or position programmatically.

      Side-note: the 2-argument javacomponent form that you mentioned does not return an HG container because the JButton is attached to the figure’s content directly, not via a java.awt.Panel container which is assigned to the HG handle. Using this method is actually a topic for an entire future article, due to the possibilities that it enables…

      • MJJ February 1, 2011 at 02:43

        Thanks for the quick reply!

        I guess it kinda works:

        f = figure('menuBar','none','toolBar','none','handleVisibility','off');
        pos = getpixelposition(f);
        [b c] = javacomponent({'javax.swing.JButton','I''d hit that!'}, [0 0 pos(3:4)], f)
        set(c,'Units', 'normalized');

        f = figure('menuBar','none','toolBar','none','handleVisibility','off'); pos = getpixelposition(f); [b c] = javacomponent({'javax.swing.JButton','I''d hit that!'}, [0 0 pos(3:4)], f) set(c,'Units', 'normalized');

        will give you a nice big button (or small if you resize) but if you make it really big you can see that it is really anchored to the SW borders and that there actually is a small gap in the NE borders.

        Will I just have to live with that or do you have more tricks up your sleeve?

      • Yair Altman February 1, 2011 at 04:42

        @Martin (MJJ) – The gap is due to external margins that each control has, and internal margins (insets) of the containing RootPane. They are only a few pixels in size – is it that bothersome?

      • MJJ February 4, 2011 at 01:57

        I guess I can live with that 🙂

        I made a blunder somewhere in my larger GUI app, which gave a larger gap, now it’s only a few pixels.

  4. GDL May 17, 2011 at 09:15 Reply

    I have been unsuccessful in actually changing the contents of a the editable JComboBox specified by your example above. Can you please suggest a procedure for this? Thanks!

    • Yair Altman May 30, 2011 at 12:25 Reply

      @GDL – updating the JComboBox is easy:

      h = uicomponent('style','JComboBox',{1,pi,'text'}, 'editable',true);
      set(h,'SelectedItem','text');

      h = uicomponent('style','JComboBox',{1,pi,'text'}, 'editable',true); set(h,'SelectedItem','text');

  5. Julien June 2, 2011 at 07:08 Reply

    hello,
    Is it possible to set the background of javacomponents transparent ? I have 2 JLabel which overlay (this is deliberate) so that one is hiding a text part of the other one… Could you help me please ?

    • Yair Altman June 5, 2011 at 14:12 Reply

      @Julien – all Matlab GUI controls, including uicontrols and javacomponents, use a heavyweight java.awt.Panel container, rather than a lightweight javax.swing.JPanel. Unfortunately, the heavyweight Panels, unlike lightweight JPanels, cannot be made transparent. This means that even if the control or component is made transparent, this would still have no effect since their containing Panel is opaque. See an interesting discussion on this here. Note that while individual controls are opaque, the entire figure window can be made fully or partially transparent, as I have recently shown.

      To solve your immediate question about overlapping labels, you could perhaps simply use overlapping text labels that are displayed on an invisible axes (i.e., no grids, no x/y labels etc.).

    • Yair Altman May 4, 2016 at 19:32 Reply

      Follow-up: http://undocumentedmatlab.com/blog/transparent-labels

  6. appy February 15, 2012 at 03:34 Reply

    Can we set all uicontrol properties in single line of code to the object created by javacomponent example parent,background color ,tag,and etc.
    ex:uicontrol(‘parent’,hfig,’tag’,’ghs’,’style’,’push’,’Backgroundcolor’,[1 1 0]);
    i want to do it for javacomponent in single line what is the syntax is it same as java syntax

    • Yair Altman February 15, 2012 at 04:26 Reply

      @appy – the syntax is different – javacomponent only accepts the three parameters mentioned in the article: object, position and parent. However you can always use the built-in set function to update multiple properties of the Java object in a single line, just as you can do with a uicontrol‘s properties. Note, however, that using set for Java properties is discouraged, and you should generally use the jObject.setXXX() notation to prevent memory leaks.

  7. Keith March 7, 2012 at 14:39 Reply

    I’m unfamiliar with Java (all I know I have picked up from this website while trying to make a gui with functionality that documented matlab does not have) so which uicomponent or javacomponent ‘style’ would I use to create a scrollable non-editable text box (basically this box is a long skinny rectangle about 6 lines of text tall which usually but not always be tall enough to display a prompt to the user, and when appropriate the user can type stuff into a different long skinny text box, with a few buttons in between them)

  8. Keith March 7, 2012 at 15:21 Reply

    never mind I found your post on matlab central about using a multiline edit box with editable set to off.

  9. jadey April 5, 2012 at 11:11 Reply

    Hello,

    Thank you for these impressive works and tools making matlab gui much more efficient!
    I’m actually using a jslider thanks the uicomponent tool. It’s works nicely however I’d like to change the slider labels more or less as it is shown at the end of this article:
    http://docs.oracle.com/javase/tutorial/uiswing/components/slider.html
    According to this article, I should first create a table. I’m not very familiar with java and even less java with matlab, would you have any idea how to create this java table within a matlab code and then customize my jslider ?
    Thanks !

    • Yair Altman April 5, 2012 at 11:59 Reply

      @jadey – as I explain in section 2.1 of my Matlab-Java Programming book, creating and using a Java Hashtable in Matlab is extremely easy. Here’s the original Java code from the webpage that you mentioned:

      static final int FPS_MIN = 0;
      static final int FPS_MAX = 30;
      static final int FPS_INIT = 15;    //initial frames per second
       
      //Create the slider
      JSlider framesPerSecond = new JSlider(JSlider.VERTICAL, FPS_MIN, FPS_MAX, FPS_INIT);
      framesPerSecond.addChangeListener(this);
      framesPerSecond.setMajorTickSpacing(10);
      framesPerSecond.setPaintTicks(true);
       
      //Create the label table
      Hashtable labelTable = new Hashtable();
      labelTable.put( new Integer( 0 ),          new JLabel("Stop") );
      labelTable.put( new Integer( FPS_MAX/10 ), new JLabel("Slow") );
      labelTable.put( new Integer( FPS_MAX ),    new JLabel("Fast") );
      framesPerSecond.setLabelTable( labelTable );
       
      framesPerSecond.setPaintLabels(true);

      static final int FPS_MIN = 0; static final int FPS_MAX = 30; static final int FPS_INIT = 15; //initial frames per second //Create the slider JSlider framesPerSecond = new JSlider(JSlider.VERTICAL, FPS_MIN, FPS_MAX, FPS_INIT); framesPerSecond.addChangeListener(this); framesPerSecond.setMajorTickSpacing(10); framesPerSecond.setPaintTicks(true); //Create the label table Hashtable labelTable = new Hashtable(); labelTable.put( new Integer( 0 ), new JLabel("Stop") ); labelTable.put( new Integer( FPS_MAX/10 ), new JLabel("Slow") ); labelTable.put( new Integer( FPS_MAX ), new JLabel("Fast") ); framesPerSecond.setLabelTable( labelTable ); framesPerSecond.setPaintLabels(true);

      Java slider demo

      And here’s the equivalent Matlab code – note how closely it correlates with the Java code above:

      FPS_MIN = 0;
      FPS_MAX = 30;
      FPS_INIT = 15;    % initial frames per second
       
      % Create the slider
      framesPerSecond = javax.swing.JSlider(javax.swing.JSlider.VERTICAL, FPS_MIN, FPS_MAX, FPS_INIT);
      %framesPerSecond.addChangeListener(this);  % you need to set your Matlab callbacks here
      framesPerSecond.setMajorTickSpacing(10);
      framesPerSecond.setPaintTicks(true);
       
      % Create the label table
      labelTable = java.util.Hashtable();
      labelTable.put( int32( 0 ),          javax.swing.JLabel('Stop') );
      labelTable.put( int32( FPS_MAX/10 ), javax.swing.JLabel('Slow') );
      labelTable.put( int32( FPS_MAX ),    javax.swing.JLabel('Fast') );
      framesPerSecond.setLabelTable( labelTable );
       
      framesPerSecond.setPaintLabels(true);

      FPS_MIN = 0; FPS_MAX = 30; FPS_INIT = 15; % initial frames per second % Create the slider framesPerSecond = javax.swing.JSlider(javax.swing.JSlider.VERTICAL, FPS_MIN, FPS_MAX, FPS_INIT); %framesPerSecond.addChangeListener(this); % you need to set your Matlab callbacks here framesPerSecond.setMajorTickSpacing(10); framesPerSecond.setPaintTicks(true); % Create the label table labelTable = java.util.Hashtable(); labelTable.put( int32( 0 ), javax.swing.JLabel('Stop') ); labelTable.put( int32( FPS_MAX/10 ), javax.swing.JLabel('Slow') ); labelTable.put( int32( FPS_MAX ), javax.swing.JLabel('Fast') ); framesPerSecond.setLabelTable( labelTable ); framesPerSecond.setPaintLabels(true);

      Matlab version of same slider

    • jadey April 5, 2012 at 13:09 Reply

      Thank you for your real quick answer!

  10. Todd January 7, 2013 at 06:53 Reply

    Hi, I am using uicomponent under Matlab 2008b. I am now reading your book and the section on the EDT.

    However, in this thread: https://www.mathworks.com/matlabcentral/newsreader/view_thread/247071, you say that uicomponent does not place components on the EDT. However, I can’t find out what, exactly, is required from me to accomplish this.

    Do I just pass the component handle returned by uicomponent through javaObjectEDT? Or does it need to happen earlier, somewhere inside the uicomponent? Or do I need to pass it through findjobj first? Or am I completely mixed up and it has to be something else entirely?

    Thank you very much for your help.

    • Yair Altman January 7, 2013 at 07:07 Reply

      @Todd – you can use javaObjectEDT anytime you wish – it will start using the EDT from that point onward.

  11. HG2 update | Undocumented Matlab May 17, 2013 at 05:29 Reply

    […] is an open bug on R2012b and R2013a whereby the clf function does not delete javacomponent objects. This bug does not affect HG2, where clf works […]

  12. A couple of internal Matlab bugs and workarounds | Undocumented Matlab June 12, 2013 at 11:01 Reply

    […] in R2012b (Matlab 8.0) something broke and controls that are added to the figure window using the javacomponent function are no longer cleared by clf – all the regular Matlab axes and uicontrols are deleted, but […]

  13. treeTable | Undocumented Matlab August 6, 2013 at 00:13 Reply

    […] javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. I discussed it here. […]

  14. Editable combo-box | Undocumented Matlab October 9, 2013 at 08:45 Reply

    […] problems/limitations. We can create and display the component in one go using the semi-documented javacomponent function: position = [10,100,90,20]; % pixels hContainer = gcf; % can be any uipanel or […]

  15. Giorgos November 10, 2013 at 04:12 Reply

    Hallo Yair,

    You presented very nicely a way to introduce a jSlider in matlab. However, I would like to ask if there is a possibility to add a jSlider with 2 thumbs. So 2 values can be adjusted within the range of the slider.

    Something like this .

    • Yair Altman November 10, 2013 at 07:18 Reply

      @Giorgos – such a control is not part of the standard Swing library, but you can download it from 3rd-parties and use it in Matlab in exactly the same manner, using the javacomponent function.

  16. Rafael December 9, 2013 at 05:29 Reply

    Hallo Yair,

    What a great blog! Congratulations.

    I would like to create a panel. The panel has to have scrolling options. Unfortunately, I have a problem. JViewport does not display the whole entire scrolling client. That means 8 defined pushbuttons are never displayed together. Only some of them, depending on where they are located. I do not understand this. Can you help me?
    It’s part of my code

    import javax.swing.*;
     
    hFig=figure('Units','pixels','Position',[520 78 560 720],'Resize','off');
    hFig2=figure('Units','pixels','Position',[520 378 300 300],'Resize','off');
     
    panel=uipanel('Units','pixels','Position',[0 0 560 720],'Parent',hFig);
    jpanel=findjobj(panel);
    jscrollpane=JScrollPane(jpanel);
     
    javacomponent(jscrollpane,[50 50 200 200],hFig2);
    set(jscrollpane,'HorizontalScrollBarPolicy',31);
    set(jscrollpane,'VerticalScrollBarPolicy',22);  
     
    for i=[100,200,300,340,380,420,460,520];
        p=[50 i 100 40];
        uicontrol('style','pushbutton','units','pixels','position',p,'string',i,'parent',panel);
     
        set(hFig,'Visible','off');
        vis=findobj(panel,'Tag',i);
        set(vis,'Visible','on');
    end

    import javax.swing.*; hFig=figure('Units','pixels','Position',[520 78 560 720],'Resize','off'); hFig2=figure('Units','pixels','Position',[520 378 300 300],'Resize','off'); panel=uipanel('Units','pixels','Position',[0 0 560 720],'Parent',hFig); jpanel=findjobj(panel); jscrollpane=JScrollPane(jpanel); javacomponent(jscrollpane,[50 50 200 200],hFig2); set(jscrollpane,'HorizontalScrollBarPolicy',31); set(jscrollpane,'VerticalScrollBarPolicy',22); for i=[100,200,300,340,380,420,460,520]; p=[50 i 100 40]; uicontrol('style','pushbutton','units','pixels','position',p,'string',i,'parent',panel); set(hFig,'Visible','off'); vis=findobj(panel,'Tag',i); set(vis,'Visible','on'); end

    Best Regards,
    Rafael

    • Rafael December 20, 2013 at 04:26 Reply

      This is my solution:

      import javax.swing.*;
      import java.awt.*;
       
      hFig = figure(); % Create main figure
      jpan = JPanel(); % Create main panel
       
      % Set Layout
      % The two arguments to the BoxLayout constructor are the container that it 
      % manages and the axis along which the components will be laid out.
      jpan.setLayout(BoxLayout(jpan, BoxLayout.Y_AXIS));
       
      for i=1:20 % Loop = 20
          jbut1 = JButton(); % Create pushbutton
          jbut1.setAlignmentX(0.5); % Method sets the alignment for this object
          jpan.add(jbut1); % Add jButton to a JPanel
       
          % Specifying Component Sizes
          jbut1.setMinimumSize(Dimension(120, 25));
          jbut1.setPreferredSize(Dimension(120, 25));
          jbut1.setMaximumSize(Dimension(120, 25));
          jpan.add(Box.createRigidArea(Dimension(0,20))); % Fixed-size space between two components
      end
       
      jscrollpane=JScrollPane(jpan); % Add jPanels to a JScrollPane
       
      % Javacomponent adds the requested component as a child of the requested 
      % parent container and wraps it in a Matlab Handle-Graphics container
      javacomponent(jscrollpane,[50 50 200 200],hFig);

      import javax.swing.*; import java.awt.*; hFig = figure(); % Create main figure jpan = JPanel(); % Create main panel % Set Layout % The two arguments to the BoxLayout constructor are the container that it % manages and the axis along which the components will be laid out. jpan.setLayout(BoxLayout(jpan, BoxLayout.Y_AXIS)); for i=1:20 % Loop = 20 jbut1 = JButton(); % Create pushbutton jbut1.setAlignmentX(0.5); % Method sets the alignment for this object jpan.add(jbut1); % Add jButton to a JPanel % Specifying Component Sizes jbut1.setMinimumSize(Dimension(120, 25)); jbut1.setPreferredSize(Dimension(120, 25)); jbut1.setMaximumSize(Dimension(120, 25)); jpan.add(Box.createRigidArea(Dimension(0,20))); % Fixed-size space between two components end jscrollpane=JScrollPane(jpan); % Add jPanels to a JScrollPane % Javacomponent adds the requested component as a child of the requested % parent container and wraps it in a Matlab Handle-Graphics container javacomponent(jscrollpane,[50 50 200 200],hFig);

  17. Jan December 27, 2013 at 04:06 Reply

    Hi,
    I’m working on a Matlab GUI and was trying to implement a JDesktopPane with JInternalFrames.

    Is it possible to put Matlab GUI Elements (uicontrols, axes) into a JInternalFrame? I’ve managed to create an JInternalFrame and add it into the JDesktopPane, but I don’t know how to add a Matlab GUI Element.

    I have created the JDesktopPane using the JCONTROL class. It is stored in ‘obj.handles.desktop’, I can add a JInternalFrame via ‘obj.handles.desktop.add( handle )’.

    I used this to create the JInternalFrame:

    iframe = javax.swing.JInternalFrame('Preferences', true, true, true, true);
    iframe.setBounds(40, 40, 600, 400);
    iframe.setVisible( true );
    obj.handles.desktop.add(iframe);

    iframe = javax.swing.JInternalFrame('Preferences', true, true, true, true); iframe.setBounds(40, 40, 600, 400); iframe.setVisible( true ); obj.handles.desktop.add(iframe);

    This works for opening an JInternalFrame, but I do not have a Matlab handle to add Matlab components. If I try and add an ‘[jHandle, mHandle] = javacomponent(iframe);’, a second JinternalFrame with ‘zero size’ opens bottom left of the screen.

    I never worked with Java and this is my first bigger Matlab GUI project, so I am quite new to this.

    Thanks for helping and your very helpful Blog!
    Jan

    • Yair Altman December 31, 2013 at 16:11 Reply

      @Jan – you cannot add Matlab components to Java containers (e.g., JInternalFrame) – you can only add Java components to Matlab containers.

  18. Magpie April 8, 2014 at 07:30 Reply

    Hi,
    I would like to access the axis canvas handle in matlab figure. I use the following code to do it:

    hFig=figure;
    [javaAxisCanvas, javaContainer] = javacomponent('com.mathworks.hg.peer.AxisCanvas', [100 100 100 100], hFig);
    pause(1)% wait
    h_nativeWH = javaAxisCanvas.getNativeWindowHandle()

    hFig=figure; [javaAxisCanvas, javaContainer] = javacomponent('com.mathworks.hg.peer.AxisCanvas', [100 100 100 100], hFig); pause(1)% wait h_nativeWH = javaAxisCanvas.getNativeWindowHandle()

    It seems h_nativeWH returns correct value on windows, but on Mac OSX it returns the figure handle, hFig. Could you suggest if there is any other way of accessing axis canvas handle that works on Mac OSX? (I am running Matlab in HG2 mode with switch -hgVersion 2)
    Thanks.

    • Yair Altman April 8, 2014 at 12:19 Reply

      @Magpie – I don’t have a Mac, I’m afraid I can’t help you.

  19. Matlab GUI: Numeric input for serious work | Notes June 17, 2014 at 02:38 Reply

    […] (without GUIDE). Caveat: Doing anything with java handles is only possible when the GUI is visible, I think. Therefore it’s much better to place the FindJObj function in GUIDE’s […]

  20. Kai July 9, 2014 at 03:07 Reply

    Hi Yair,

    I have a problem when I’m using javacomponent. I have a jogl panel (GLJPanel) where I draw some animations on.
    Then I want to add this jogl panel to a uipanel by using the following codes

    %glpane is the jogl panel
    [comp, container] = javacomponent(glpane);
    %contentPanel is the uipanel under the jogl panel
    set(container, 'Parent', handles.contentPanel, 'Units', 'normalized', 'Position', [0 0 1 1]);

    %glpane is the jogl panel [comp, container] = javacomponent(glpane); %contentPanel is the uipanel under the jogl panel set(container, 'Parent', handles.contentPanel, 'Units', 'normalized', 'Position', [0 0 1 1]);

    the jogl panel is set to be transparent within java file and indeed it’s transparent when I test it in Java.
    However, it’s not transparent in Matlab. I think it might be the problem of the container. Do you have any suggestion regarding this problem.
    Thanks in advance.

    • Yair Altman July 9, 2014 at 03:31 Reply

      @Kai – Matlab places your JOGL panel in a wrapper JPanel for its GUI. The problem is not in the JOGL panel but in Matlab’s wrapper JPanel, which is opaque.

    • Kai Wang July 9, 2014 at 04:04 Reply

      Thanks for the reply.
      But how can I set the wrapper JPanel to be transparent. I used some commands like:

      %I don't know if it's correct
      set(container, 'Opaque', 'off');

      %I don't know if it's correct set(container, 'Opaque', 'off');

      or

      set(container, 'BackgroundColor', 'none');

      set(container, 'BackgroundColor', 'none');

      But it doesn’t work. So I think the container is not the same thing as the wrapper JPanel you mentioned? Maybe I should first find the JPanel by using findobj?

      • Yair Altman July 9, 2014 at 05:09

        You can try using glpane.getParent, but I would suspect that you will find it cannot be made transparent. In many Matlab releases, it’s a heavyweight java.awt.Panel (which cannot be made transparent) rather than a lightweight JPanel (which can).

    • Kai July 9, 2014 at 11:39 Reply

      Thanks for your answer. So is there a way to put a transparent GLJPanel on an uipanel and the contents on the uipanel can be displayed? It seems that javacomponent is the only way to bind Java GUI with Matlab GUI. My situation is using

      preview(video, hImage)

      preview(video, hImage)

      to show a live video stream on a uipanel/axes. The GLJPanel displays some transparent animation which is a mask of the video.

      • Yair Altman July 18, 2014 at 01:34

        @Kai – I don’t know of a way to bypass javacomponent. It’s an m-file so you could theoretically drill down into lower-level functionality, but I doubt the end result will be much different. Let us all know if you find otherwise, that would be very interesting.

    • Kai July 28, 2014 at 00:17 Reply

      Eventually I use UpdatePreviewWindowFcn to convert each video frame image into a Java Image object. I also override paintComponent() of JPanel to setup the Image object as the JPanel’s background image. So it’s like I copy the video stream to the JPanel. But the drawback is the high usage of CPU (7% to 10% extra usage), I’m still looking for a better way.

  21. Emma December 2, 2014 at 04:25 Reply

    Hi Yair,

    Thanks a lot. this is amazing work.

    I have one question, hope you know it….here is the date chosen..how about 24 hour? like second, minute, hour? Anyway you know?

    And how can I set the figure title here…Thanks a lot.

    • Yair Altman December 2, 2014 at 04:50 Reply

      @Emma – clarify your question. I do not understand it at all.

      • Emma December 2, 2014 at 04:59

        Hi Yair…

        I mean that when we also want people to choose the exact hour, minute and second in one day.
        About that hour, minute, and second choosing… So basically we want to specify the exact moment, not only date….
        you get me?

  22. Mac October 9, 2015 at 13:41 Reply

    Hello yair,

    Do you know if the javacomponent function is still available in Matlab latest Release 2015b?

    I am not able to find any documentation on the web.

    • Yair Altman October 10, 2015 at 09:01 Reply

      @Mac – yes, javacomponent is still supported

  23. Adrien BARRET October 13, 2015 at 07:26 Reply

    Hello Yair,

    The command set(0,'HideUndocumented','off') is not anymore required with R2015b release of matlab?

    Thanks in advance

    • Yair Altman October 13, 2015 at 12:54 Reply

      @Adrien – the HideUndocumented property was removed from the root handle in R2014b. To see the list of hidden/undocumented properties of a handle, use the getundoc utility.

  24. Antonio Hurtado December 1, 2015 at 08:26 Reply

    Hello Yair,
    I have a java component along with another normal uicontrols in a UI. The java componet is a Java Password Field and I created it this way:

    [gui.edit2,gui.ed2] = javacomponent('javax.swing.JPasswordField', [], gui.main);
    set(gui.ed2,'Units','characters','Position',[1 2.72 33 1.7])

    [gui.edit2,gui.ed2] = javacomponent('javax.swing.JPasswordField', [], gui.main); set(gui.ed2,'Units','characters','Position',[1 2.72 33 1.7])

    Everything works fine but I want to make this Java Password Field the active field just at the starting of the UI.
    If it was a normal uicontrol I know the method would be:

    uicontrol(gui.ed2)

    uicontrol(gui.ed2)

    but this doesn’t work with a Java Object.
    I tried things like

    gui.edit2.requestFocus()

    gui.edit2.requestFocus()

    but it doesn’t work either. What should I do?

    Thank you very much.

    • Yair Altman December 1, 2015 at 08:41 Reply

      @Antonio – perhaps some other Matlab components render onscreen after you Java password field, and they take the focus away. Try to run your requestFocus() after a drawnow, at the end of all uicontrols creation.

    • Antonio December 1, 2015 at 10:13 Reply

      Thank you Yair for your quick answer. It worked!

  25. Daniel December 4, 2015 at 08:26 Reply

    Hello Yair,

    I have a Matlab gui and I want to add a JSlider. The jSlider is just placed, but I have problems to get it in the uipanel. The blog was hlepful, but I don’t understand how to handle this.
    Thank you in advance.

    Daniel

    • Yair Altman December 5, 2015 at 08:31 Reply

      @Daniel – simply set the uipanel handle as the 3rd input arg of javacomponent(). If you need additional assistance with handling JSliders in Matlab, search this website for other posts, and/or get my Matlab-Java book, and/or ask me for a private consulting session.

  26. Chuck Andraka December 9, 2015 at 08:48 Reply

    Yair:

    I used this approach to attempt to deal with graphics shortcomings in 2015b. I have some images that must be displayed in figures in a timed fashion. the timing must be short, but more importantly determinate. In 2015b, my application was failing because the figure display was slow and the time it took was highly variable.

    I created a javacomponent perfectly overlaid on my figure axis, and display the figures on this. Rather than replace all of my code, I only do this in the time-critical steps, and allow MatLab to display plots and figures in the axes in less critical times. therefore, when the critical step is done, I delete the javacomponent.

    Due to several other issues with no known workaround (primarily compiled MatLab issues) in 2015b, i have to revert to 2013b for now. I left the javacomponent steps in place, and my code fails. The issue is that the delete does not make the container disappear, and so it blocks the slower, non-java images form displaying.

    Here is the setup of the javacomponent, and display of the first in a series of images. The image (imdisplay) is a matlab matrix converted to java with im2java2d. handles.projector is the handle to the figure, and sizeh, sizey are the dimensions of the image display area. The axes are set to completely fill the figure area:

    icon_java = javax.swing.ImageIcon(imdisplay);
    label = javax.swing.JLabel(icon_java);
    jc = javacomponent(label,[1,1,sizeh,sizey],handles.projector);

    icon_java = javax.swing.ImageIcon(imdisplay); label = javax.swing.JLabel(icon_java); jc = javacomponent(label,[1,1,sizeh,sizey],handles.projector);

    Each additional image is displayed with:

    icon_java.setImage(imdisplay);
    jc.repaint

    icon_java.setImage(imdisplay); jc.repaint

    At the end of the timed routine, I delete the javacomponent:

    jc.delete

    jc.delete

    This all worked great on 2015b, and gave consistent display timing (and quick). However, upon reverting to 2013b, the last step (delete) fails

    Any thoughts?
    Thanks
    Chuck

    • Yair Altman February 4, 2016 at 10:32 Reply

      @Chuck – don’t delete the component, but rather its Matlab container. This will work in both R2013b and R2015b:

      [jc,hc] = javacomponent(label,...);
      ...
      delete(hc)

      [jc,hc] = javacomponent(label,...); ... delete(hc)

  27. Dan May 6, 2016 at 09:13 Reply

    I used uicomponent to create an array of jsliders and tried to use this array in another but nested function where values of the sliders will be read and manipulated. However I got an error message that the array is not defined. What could be that goes wrong?

    • Yair Altman May 6, 2016 at 12:22 Reply

      You probably have a bug in your code. Use the Matlab debugger to find it.

  28. Johannes May 23, 2017 at 12:39 Reply

    Dear Yair,

    I have one question: Would it be possible to set certain properties of elements (e.g. Text-Font or BackgroundColor) at once?
    Right now I use to following scheme for that:

    guiel.elementA(1) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
    guiel.elementA(2) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
    guiel.elementA(3) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
    guiel.elementB(1) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
    guiel.elementB(2) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
    guiel.elementB(3) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); 
     
    newFont2 = java.awt.Font('Helvetica', java.awt.Font.PLAIN, 13);
     
    guiel.elementA(1).setFont(newFont2);
    guiel.elementA(2).setFont(newFont2);
    guiel.elementA(3).setFont(newFont2);
    guiel.elementB(1).setFont(newFont2);
    guiel.elementB(2).setFont(newFont2);
    guiel.elementB(3).setFont(newFont2);

    guiel.elementA(1) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); guiel.elementA(2) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); guiel.elementA(3) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); guiel.elementB(1) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); guiel.elementB(2) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); guiel.elementB(3) = javacomponent('javax.swing.JLabel', [0 0 1 1], 'Parent'); newFont2 = java.awt.Font('Helvetica', java.awt.Font.PLAIN, 13); guiel.elementA(1).setFont(newFont2); guiel.elementA(2).setFont(newFont2); guiel.elementA(3).setFont(newFont2); guiel.elementB(1).setFont(newFont2); guiel.elementB(2).setFont(newFont2); guiel.elementB(3).setFont(newFont2);

    Thank you very much!

    • Yair Altman May 24, 2017 at 12:45 Reply

      @johanes – you can do this:

      set([guiel.elementA, guiel.elementB], 'Font', newFont2);

      set([guiel.elementA, guiel.elementB], 'Font', newFont2);

  29. Johannes June 2, 2017 at 15:30 Reply

    Thank you very much Yair!

  30. Anu July 7, 2017 at 09:43 Reply

    hello sir,
    I have created a 2 tabgroups in my GUI.At first it is good but after adding uicontrols to those tabs using different panels i am getting errors and automatically a new hgjavacomponent is being added to GUI everytime i run the GUI. This results in abnormal behaviour of the GUI. How can i stop those hgjavacomponents visibility?

    • Yair Altman July 16, 2017 at 00:16 Reply

      @Anu – this sounds like a bug in your code. Errors are not supposed to happen.

  31. Collin Pecora November 30, 2017 at 16:44 Reply

    Yair

    Is there a benefit to using javcomponent over hgjavacomponent?

    • Yair Altman November 30, 2017 at 17:18 Reply

      @Collin – hgjavacomponent is a Matlab class that is meant to contain the relevant information on a contained Java-component (peer). You can think of it as a borderless panel that tightly-fits the Java peer, and enables users to set the control’s position, units etc. in a manner that is very similar to standard Matlab uipanels. Importantly, hgjavacomponent only creates this wrapper object, NOT the peer.

      In contrast, javacomponent places the Java peer in the requested position, and also creates a corresponding hgjavacomponent object to provide the uipanel-like wrapper functionality. Both of these handles are returned when you call javacomponent (the java peer reference handle, followed by the hgjavacomponent container handle):

      [hjControl, hContainer] = javacomponent(...)

      [hjControl, hContainer] = javacomponent(...)

      • Collin Pecora November 30, 2017 at 20:03

        Thanks Yair,

        So, it would be better to use javacomponent here?

        jhBut = handle(javaObjectEDT('javax.swing.JButton','Hello!'),'CallbackProperties');
        jhBut.ActionPerformedCallback = @this.onAction;
         
        hPanel = uipanel(...);
        hgjavacomponent('Parent',hPanel','JavaPeer',jhBut,'Units','norms','Position',[0,0,1,1]);

        jhBut = handle(javaObjectEDT('javax.swing.JButton','Hello!'),'CallbackProperties'); jhBut.ActionPerformedCallback = @this.onAction; hPanel = uipanel(...); hgjavacomponent('Parent',hPanel','JavaPeer',jhBut,'Units','norms','Position',[0,0,1,1]);

      • Yair Altman November 30, 2017 at 20:10

        yes

  32. Ann May 1, 2018 at 16:27 Reply

    Hi Yair,

    Thank you for your great blog.
    I want to use a slider so I add it to my figure in my UI_OpeningFcn(hObject is the handle to the figure).

    jRangeSlider = javacomponent(jRangeSlider, [150,150,850,80], hObject);
    set(jRangeSlider, 'Background',java.awt.Color.white);
    set(jRangeSlider, 'StateChangedCallback', {@sliderStartEndPoint_Callback, hObject});

    jRangeSlider = javacomponent(jRangeSlider, [150,150,850,80], hObject); set(jRangeSlider, 'Background',java.awt.Color.white); set(jRangeSlider, 'StateChangedCallback', {@sliderStartEndPoint_Callback, hObject});

    However, my GUI leads to to other GUIs. That is, whenever the user press a button, the main GUI is replaced by another GUI. Therefore I need to delete my java Object. How can I do this?
    Since I have to access to it from the callback of the pushbutton, I’m not sure how to access the handle of the object. I have the handle of the figure but whenever I do this

    findobj(hObject.Parent, 'Type', 'JavaWrapper')

    findobj(hObject.Parent, 'Type', 'JavaWrapper')

    I just get

      0x0 empty GraphicsPlaceholder array.

    0x0 empty GraphicsPlaceholder array.

    What am I doing wrong? How can I delete this object?

    Thanks in advance

    • Yair Altman May 1, 2018 at 16:31 Reply

      @Ann – the best way to delete the object is via its Matlab container panel, which is accessible as the 2nd output of javacomponent:

      [jRangeSlider, hContainer] = javacomponent(jRangeSlider, [150,150,850,80], hObject);
      ...
      delete(hContainer)

      [jRangeSlider, hContainer] = javacomponent(jRangeSlider, [150,150,850,80], hObject); ... delete(hContainer)

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