The javacomponent function

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);

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

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','…')

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});

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);

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.

Categories: GUI, Handle graphics, Java, Medium risk of breaking in future versions, Semi-documented function, Stock Matlab function, UI controls

Tags: , , , , ,

Bookmark and SharePrint Print

68 Responses to The javacomponent function

  1. cdm says:

    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>');

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

  2. Pingback: Fixing a Java focus problem | Undocumented Matlab

  3. MJJ says:

    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');

    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.

    • @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 says:

      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');

      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?

    • @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 says:

      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 says:

    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!

    • @GDL – updating the JComboBox is easy:

      h = uicomponent('style','JComboBox',{1,pi,'text'}, 'editable',true);
      set(h,'SelectedItem','text');
  5. Julien says:

    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 ?

    • @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.).

  6. appy says:

    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

    • @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 says:

    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 says:

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

  9. jadey says:

    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 !

    • @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);

      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);

      Matlab version of same slider

    • jadey says:

      Thank you for your real quick answer!

  10. Todd says:

    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.

  11. Pingback: HG2 update | Undocumented Matlab

  12. Pingback: A couple of internal Matlab bugs and workarounds | Undocumented Matlab

  13. Pingback: treeTable | Undocumented Matlab

  14. Pingback: Editable combo-box | Undocumented Matlab

  15. Giorgos says:

    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 .

    • @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 says:

    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

    Best Regards,
    Rafael

    • Rafael says:

      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);
  17. Jan says:

    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);

    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

  18. Magpie says:

    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()

    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.

  19. Pingback: Matlab GUI: Numeric input for serious work | Notes

  20. Kai says:

    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]);

    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.

    • @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 says:

      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');

      or

      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?

    • 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 says:

      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)

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

    • @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 says:

      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 says:

    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.

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

    • Emma says:

      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 says:

    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.

  23. Adrien BARRET says:

    Hello Yair,

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

    Thanks in advance

  24. Antonio Hurtado says:

    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])

    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)

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

    gui.edit2.requestFocus()

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

    Thank you very much.

    • @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 says:

      Thank you Yair for your quick answer. It worked!

  25. Daniel says:

    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

    • @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 says:

    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);

    Each additional image is displayed with:

    icon_java.setImage(imdisplay);
    jc.repaint

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

    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

    • @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)
  27. Dan says:

    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?

  28. Johannes says:

    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);

    Thank you very much!

  29. Johannes says:

    Thank you very much Yair!

  30. Anu says:

    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?

  31. Collin Pecora says:

    Yair

    Is there a benefit to using javcomponent over hgjavacomponent?

    • @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(...)
    • Collin Pecora says:

      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]);
  32. Ann says:

    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});

    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')

    I just get

      0x0 empty GraphicsPlaceholder array.

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

    Thanks in advance

    • @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)

Leave a Reply

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