Find all java objects contained within a java container or Matlab GUI handle
If no output parameter is specified, then an interactive GUI window will be displayed with a tree-view of all container components, their properties and callbacks.
Syntax:
[handles,levels,parentIds,listing] = findjobj(container,'PropName',PropValue(s),...)
Inputs:
- container - optional GUI handle. If unsupplied then current figure will be used
- 'PropName',PropValue - optional list of case insensitive property pairs. PropName may also be named -PropName.
Supported properties:
- 'position' - filter results based on those elements that contain the specified X,Y position or a java element
Note: specify a Matlab position (X,Y = pixels from bottom left corner), not a java one
- 'size' - filter results based on those elements that have the specified W,H (in pixels)
- 'class' - filter results based on those elements that contain the substring (or java class) PropValue
Note: filtering is case insensitive and relies on regexp, so you can pass wildcards etc.
- 'property' - filter results based on elements that possess the specified case-insensitive property string or have property values in cell array format: {'propName', 'propValue'}. Example: findjobj(...,'property', {'Text','click me'})
- 'depth' - filter results based on specified depth. 0=top-level, Inf=all levels (default=Inf)
- 'flat' - same as: 'depth',0
- 'not' - negates the following filter: 'not','class','c' returns all elements EXCEPT those with class 'c'
- 'persist' - persist figure components information, allowing much faster results for subsequent invocations
- 'print' - display all java elements in a hierarchical list
Note1: optional PropValue of element index or handle to java container
Note2: normally this option would be placed last, after all filtering is complete.
- 'list' - same as 'print'
Outputs:
- handles - list of handles to java elements
- levels - list of corresponding hierarchy level of the java elements (top=0)
- parentIds - list of indexes (in unfiltered handles) of the parent container of the corresponding java element
- listing - results of 'print'/'list' options (empty if 'print'/'list' were unspecified)
Sample usage:
>> hButton = uicontrol('string','click me');
>> jButton = findjobj(hButton,'nomenu'); % or: jButton = findjobj('property',{'Text','click me'});
>> jButton.setFlyOverAppearance(1);
>> jButton.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.HAND_CURSOR));
>> set(jButton,'FocusGainedCallback',@myMatlabFunction); % some 30 callback points available...
>> jButton.get; % list all changeable properties...
>> hEditbox = uicontrol('style',edit');
>> jEditbox = findjobj(hEditbox,'nomenu');
>> jEditbox.setCaretColor(java.awt.Color.red);
>> jEditbox.KeyTypedCallback = @myCallbackFunc; % many more callbacks where this came from...
>> jEdit.requestFocus;
(Many more examples in the utility's help section)
Known issues/limitations:
- Cannot currently process multiple container objects - just one at a time
- Initial processing is a bit slow when the figure is laden with many UI components (so better use 'persist')
- Passing a container Matlab handle is currently found by position+size: should find a better way to do this
- Labels have a write-only text property in java, so can't be found using 'property',{'Text','string'} notation
Technical description:
* https://UndocumentedMatlab.com/articles/findjobj-find-underlying-java-object
* https://UndocumentedMatlab.com/articles/findjobj-gui-display-container-hierarchy
Warning:
This code heavily relies on undocumented and unsupported Matlab functionality. It works on Matlab 7+, but use at your own risk!
Bugs and suggestions:
Please send to Yair Altman (altmany at gmail dot com)
See also:
java, handle, findobj, findall
Yair Altman (2021). findjobj - find java handles of Matlab graphic objects (https://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects), MATLAB Central File Exchange. Retrieved .
Inspired by: UIINSPECT - display methods, properties & callbacks of an object
Inspired: inspect time series events, BacStalk, BiofilmQ, tweak, kristinbranson/JAABA, MATLAB Snippets, Stock Trader Journal, directorscut82/matbuttons, Microscopy Image Browser (MIB), attachScrollPanelTo - add scroll-panel to a uipanel or axes, Microscopy Image Browser 2 (MIB2), statusbar, getjframe - Retrieves a figure's underlying Java frame, enable/disable entire figure window, setDesktopVisibility, UIINSPECT - display methods, properties & callbacks of an object, Manage and Dock Figures into Group, Virtual Tackball, maximize, uhelp, Command window text, Graphical Wrappers, Reorderable Listbox, Colorize Document Bar, tortoise svn toolbar integration, Sim.I.am, Realtime trading with Matlab and IB presentation files, fixuilabels, Programmatically scroll Variables Editor, embeddedmethodsviewer - show functions and methods within matlab editor, Figure from text file (supports HTML tags), Panic Simulator, tprintf -- Print to Second Terminal Window, GavriYashar/Matlab-Editor-Plugin, Copy Paste, Probability Distribution Plotter, Dynamic Search Box, checkVersion - Check for a newer file version on the File Exchange, figs2tabs - move figures into a single tabbed gui, Dicom Operator - EsmeProcess, Chess Master, smart_scrollbars fixes Matlab's listbox/editbox scrollbars to only show as needed, Message Logger, scatool, SessionManager, kview - Interface for signal/data easy visualization and processing
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Create scripts with code, output, and formatted text in a single executable document.
This submission has been helpful in so many ways and I really appreciate the time put into keeping it up to date. Just an FYI to other users, the JavaFrame property and javacomponent function used in this submission will no longer be supported by Matlab in future releases. More info: https://www.mathworks.com/products/matlab/app-designer/java-swing-alternatives.html
MATLAB R2019b changes the ID of the warning MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame to MATLAB:ui:javaframe:PropertyToBeRemoved so the warning suppression in this function needs updating, though the functionality itself seems still to work fine!
Thanks for the update, Yair! The latest version (7/3/19) of findjobj appears to fix the problem I was having with the 9/21/18 version in MATLAB R2018b/R2019a.
Fantastic tool! Many thanks for creating it and keeping it up to date.
@Yair - I too don't think the problem is with findjobj. Unfortunately Mathworks technical support have decided they won't look into it.
@Boyd - I do not believe the problem is in findjobj, but in any case you have a simple alternative for labels: https://undocumentedmatlab.com/blog/transparent-labels
I have been using this function to let me change the background of a uicontrol to transparent (function below). Upon updating to 2019a, my code started to crash due to a memory leak (it worked fine in 2018b and previous versions of Matlab). I have been back and forth many times with tech support, and have provided them with a simple version of the code which demonstrates the memory leak. Tech support has told me that they believe the problem is in findjobj, but that since it is 3rd party code they won't support it. I am very unhappy with this answer and am continuing to push back, but so far no luck.
function h = transparentUIcontrol(varargin)
% Creates a uicontrol with transparent background
h = uicontrol(varargin{:});
jLabel = findjobj(h);
jLabel.setOpaque(false);
if isfield(jLabel,'BorderPainted')
jLabel.BorderPainted = false;
end
jLabel.repaint();
end
Thank you for this - and it works with 2019a. (Version 1.47 had errors).
Regarding my previous post, I found a workaround:
1. create a "dummy" figure where to parent the uitable
2. grab its Java handles and store them in a property
3. change the uitable parent to "TabPanel"
4. delete the dummy figure
I still cannot understand why the tool doesn't work if there is a "TabPanel" in the parenting tree of the uitable, though...
I was looking for Java Handles underneath a uitable. It has always worked properly, until when I added a component of the GUI Layout Toolbox, in particular "TabPanel". It is now one of the grand-grand-grand(...)parents of my uitable: findjobj is not able to get my Java Handles anymore. I also tried to give findjobj the ancestor figure of my uitable as input, using the option "class" (findjobj(figureAncestor, '-nomenu', 'class', 'UITablePeer') , but nothing happens. I found out that if I get the property "JavaFrame" from each of the grandparents of my uitable, the only not-empty result I get is when I interrogate the "TabPanel" object (which makes sense!): I was wondering if it is somehow related to the misfunctioning of the tool...
@Yair - You're right. If instead of the optional GUI handle, I use the figure and search by 'class' parameter, then it works:
jHandle = findjobj(h,'class','JTabbedPane')
...although more slowly... Fortunately, the speed is fixed adding the 'nomenu' parameter.
jHandle = findjobj(h,'class','JTabbedPane','nomenu')
Thanks a lot!
@Mariano - findjobj uses among other things the pixel position and size to find the underlying Java object and this may change with the display resolution. Instead, you can try to use the 'class' parameter to search for the object, and this should be independent of the resolution.
Amazing tool!
Just a weird issue that I've come across with the following code (Matlab 2018b):
h = figure;
tabgroup = uitabgroup(h);
tab1 = uitab(tabgroup, 'Title','tab1');
tab2 = uitab(tabgroup, 'Title','tab2');
jHandle = findjobj(tabgroup,'class','JTabbedPane')
If I set the screen display settings in Windows (7 and 10) with 125% size, then I get:
jHandle =
1x0 empty handle
But if I set the screen display settings with 100% size, then fine... I get what I expected:
jHandle =
javahandle_withcallbacks.com.mathworks.mwswing.MJTabbedPane
Thanks!
@Eddie - thanks for your note, I incorporated your workaround in the latest version that I just uploaded.
@Jeevith - MathWorks changed the internal implementation of uitables so findjobj now only reports the table's wrapper scroll-pane handle. You can get the uitable peer via hScrollpane.getViewport.getView. Alternatively, you can still get the peer handle directly if you search for it in its containing figure (not directly via the uitable handle): findjobj(hTable.Parent, 'class','uitablepeer')
Findjobj no longer finds java handle of uicontrol for 2018b. However I found a fix. Replace line 3399 -
set(hControl,'Tooltip','!@#$%^&*');
with
set(hControl,'TooltipString','!@#$%^&*');
It appears that setting Tooltip property no longer set the ToolTipText in its Java Container. But setting TooltipString does.
Hello Mathworks,
findjobj function is not working properly for the property 'UITablePeer' but it is working fine for other properties and for details please refer the below code.
value = findjobj(handles, '-nomenu', 'class', 'UITablePeer')
The value that is returned by function findjobj for the property 'UITablePeer' is not correct.
We are using the latest version of findjobj.m file and the matlab version which we are using in 2017b.
It is working fine in matlab version 2011b but not in matlab version 2017b.
Can you please provide the solution so as to fix the issue.
Thank you.
Thanks a lot, it works. findjobj???
@Hanzala - findjobj only works with Java-based windows (created using GUIDE or the figure function). AppDesigner (and the uifigure function) creates a Java-script window that is not, and will never be, supported by findjobj.
Hello. This tool works as mentioned for normal GUIDE components but i've been trying to implement this in an app designer app. The returned handles are always empty. Has this been tested with app designer as yet?
Excellent tool
thnaks, it's really useful to me. i want to move the position of scrollbar where i want automatically, i will share this code jScrollpane = findjobj(handles.tagTable_TargetList);
jScroll = jScrollpane.getComponent(0);
scrollMax = jScrollpane.getVerticalScrollBar.getMaximum;
scrollValue = floor(scrollMax * ((row_index-1)/row));
jScroll.setViewPosition(java.awt.Point(0,scrollValue));
Really useful, i used it to bind right click on list views in my sessionmanager project.
This is great! Very useful, both as a tool, and an example of building tree-based GUIs. Thanks for sharing this.
Is this expected to work with uifigure and all other associated appdesigner components?
With an earlier version, had the same error as CalinV:
Error @ jScrollpopup.getViewport.getView --> "Undefined function 'getViewport' for input arguments of type 'handle.handle'."
Seems to be fixed in new version and was likely due to new drawing order/delay. Great work!
very good ui
Same error as for CalinV. Thannx for the fantastic utility!
Great function! I have a question regarding changing the Background and Foreground color of popupmenu items when hovering the mouse over them (default is that clasic blue). How can I do that ?
I tried with the folowing code lines (which worked for listbox and table classes) with no success:
function popupmenu_Callback(hObject, eventdata, handles)
jScrollpopup = findjobj(hObject);
jPopupmenu = jScrollpopup.getViewport.getView;
jPopupmenu.setSelectionBackground(java.awt.Color(1,0.6,0));
jPopupmenu.setSelectionForeground(java.awt.Color(0,0,0));
jPopupmenu.setSelectionAppearanceReflectsFocus(0);
Error @ jScrollpopup.getViewport.getView --> "Undefined function 'getViewport' for input arguments of type 'handle.handle'."
I really hope Matlab can expose the java handle of UI object for advanced programming. Then we don't need this complicated trick. Until then this is a great tool!
Fantastic utility. With the previous version, I was using the following code to change the widths of the first column of cells (the row names) of a table, to 100 pixels
jTable = findjobj(handles.MyTable)
rowHeaderViewport = jTable.getComponent(4)
rowHeader = rowHeaderViewport.getComponent(0) ;
rowHeaderViewport.setPreferredSize(java.awt.Dimension(100,0)) ; % 100 = width in pixels
height = rowHeader.getHeight ;
rowHeader.setPreferredSize(java.awt.Dimension(100,height)) ;
rowHeader.setSize(100, height) ;
In the new version this returns an error at the third line:
Java exception occurred:
java.lang.ArrayIndexOutOfBoundsException: No such child: 0
at java.awt.Container.getComponent(Unknown Source)
I found two reasons why the latest version is much slower than before. Both lie within findjobj_fast:
1) pause(0.001) is really inaccurate and actually pauses for 0.01 secs or more on my machine. This is a known issue with pause.
2) in findTooltipIn, the getToolTipText method takes ages, especially because it is called 100 times until the code switches to the legacy method.
Both times it can't find an object via the fast method and my code wastes 14secs (for 6 ui elements to inspect) here.
My quick workaround is to reduce the counter to 10 (line 3390) and the pause to 0.01 (line 3395). The solution is probably to rethink the approach or decide earlier that the fast method isn't finding anything.
I extensively use finjobj, which is a wonderful tool. But unfortunately, I had to revert to version 2014-01-04 because every one of the newest versions breaks something in my code :
2016-04-11 version: some of my tooltips get replaced by '!@#$%^&*'
2016-04-14 version: generates errors in the command line
2016-04-19 version: fixes the tooltip and errors from the two previous versions, but takes about twice the time to execute (8 s instead of ~4 s for my GUI initialization code to execute)
By the way I'm using R2011b.
This is a great function that we use all the time for an interactive mapping GUI. We were glad to have a speed update. While it really improved things when using the newer versions of Mat Lab, our GUI took about 10 times longer to open in MatLab 2012 which many of our users have (faster map graphics than 2014b).
Using the profiler I tracked the issue to the fact that findTooltipIn is called 1100 times per call to findjobj. jControl is always empty so the while loop executes 100 times in findjobj_fast. Once in findTooltipIn it calls itself 54 times (in our application) all for nought. Then since jControl is still empty it executes the old logic. I have solved the issue for now in our code by just adding a version test before going down this route.
Thanks
Thanks Yair! The latest update works great
@MikeLab - I just uploaded a new version that should fix the problem that you see on R2013a (or any other Matlab release older than R2014b)
This is very useful!
Is there a way to access an older version of findjobj?
The current version works well for me with Matlab 2015a, but on PCs with Matlab 2013a, I get an error.
Here is an example:
function GetJTableTest
f = figure;
data = rand(3);
colnames = {'X-Data', 'Y-Data', 'Z-Data'};
t = uitable(f, 'Data', data, 'ColumnName', colnames, ...
'Position', [20 20 460 350]);
jscroll = findjobj(t);
end
-----------
Command Line Output:
>> GetUITable
findjobj: Number of elements in right hand side does not match number required by left hand
side
Error in findjobj (line 278)
handles (dataLen+1:end) = [];
Error in GetUITable (line 8)
jscroll = findjobj(t);
410 rethrow(err);
--------------
Additional Information: The scope of variable 'handles' spans multiple functions.
I use it ALL THE TIME. Love it!
Much appreciate the update! Significantly faster. I see about a x4 improvement in my functions that use findjobj.
However, it was not a simple drop and place of the new findjobj. I set the parent figure of the component to be invisible however findjobj would not find all the components. The previous findjobj was able to.
I was able to workaround this by moving the figure off screen and letting findjobj find the components and move it back screen.
Hi Yair,
I don't see much improvement in speed for a GUI application with about 25 uicontrols.
Furthermore, the tooltipstring of my uitable keeps displaying strange characters.
Marco
Hi Yair, great work on this findjobj function! Been using it for our GUIs and it worked great. One of my colleague updated to both Matlab R2015b and Windows 10. Now the findjobj does not return anything from a uitable.
I thought it could be related to the new Matlab version, so I tried it on my windows 7 machine and I get the following from a simple call to a uitable in R2015b:
>> hTable = uitable;
>> jScroll = findjobj(hTable)
jScroll =
javahandle_withcallbacks.com.mathworks.hg.peer.utils.UIScrollPane
On the windows 10 machine I get :
>> hTable = uitable;
>> jScroll = findjobj(hTable)
jScroll =
handle: 1-by-0
The java object is not recovered...
Do you think this is related to the OS? Are there any differences in the way Matlab would handle java objects between Windows 7 and 10?
Thanks in advance,
Charles
Excellent utility. FWIW I had some problems in a GUIDE gui where I called findjobj several times in my opening function, as it caused the gui to loose keyboard focus. This was solved by calling x = findjobj(gcf) in the OutputFcn. There was no need to use 'x', simply pointing findjobj to the gcf did the job.
Thanks Yair for fighting for a better Matlab :-)
I've faced a problem with findjobj which makes it hard to use.
findjobj doesn't find objects in inactive tabs. Is there a workaround? For now, I select the tabs before drawing them, but this is not really fail-safe.
Thanks a lot,
Tobias
@Yair — I found a small bug when trying to inspect the root object:
>> findjobj(groot)
findjobj: The following error occurred converting from matlab.ui.Root to handle.handle:
Conversion to handle.handle from matlab.ui.Root is not possible
Error in findjobj/traverseContainer (line 505)
handles(thisIdx) = handle(jcontainer,'callbackproperties');
Error in findjobj (line 259)
traverseContainer(container,0,1);
Strangely enough, when trying an "old-school" approach, it doesn't err:
>> findjobj(0)
ans =
handle: 1-by-1144
And the main node is the Main Desktop Frame "com.mathworks.mde.desk.MLMainFrame".
Besides that, FindJObj is an excellent very useful utility. Keep up the good work!
Aha - I was unaware that I could use the clear command to reset the persistent variable - thanks for that info.
@Gary - I think your solution is not good: findjobj already clears the persistent handles when it detects a different container than the previous one.
If you already know that the container's contents (rather than its handle) have changed, all you need to do to clear the persistent handles is to call clear('findjobj') at that point. Subsequent calls to findjobj will see cleared persistent vars and will recompute them.
If you like findjobj, please rate it.
Yair - thank you very much for this fix. I'd like to make another recommendation. It has been valuable for me to use 'persist', but then to erase the persistent catalog when I know the container has changed contents. I handled this by adding "pContainer = [];" after "if isempty(container)" at around line 170; I'm not sure if this would mess up other users or if you want a specific argument value that would erase the container.
- gary
@David & @Gary - the latest version of FindJObj addresses this issue and differentiates between overlapping controls, without having to use the workaround suggested by David.
Hi Paul,
I've found a solution to your problem, but it's not ideal as it requires running the findjobj twice to rescan all objects.
% findjobj test script
hWnd=figure;
tgrp = uitabgroup('Parent',hWnd);
tab1 = uitab('Parent',tgrp,'Title','tab1');
tab2 = uitab('Parent',tgrp,'Title','tab2');
t1=uitable('Parent',tab1);
a1=findjobj(t1)
set(findjobj(t1,'-property',{'Name',''}),'Name','uitable1')
%%
t2=uitable('Parent',tab2);
%%
set(findjobj(t2,'persist','-property',{'Name',''}),'Name','uitable2')
a = findjobj(t1,'-nomenu','-property',{'Name','uitable1'},'-property',{'UIClassID','ScrollPaneUI'});
b = findjobj(t2,'-nomenu','-property',{'Name','uitable2'},'-property',{'UIClassID','ScrollPaneUI'});
Hi Yair - My code snippet replaced my earlier comment. The 'aliasing' problem is that findjobj cannot distinguish two different tables placed in the same position in two different tabs.
Thanks!
Here is the test code to demonstrate the aliasing problem:
% findjobj test script
hWnd=figure;
tgrp = uitabgroup('Parent',hWnd);
tab1 = uitab('Parent',tgrp,'Title','tab1');
tab2 = uitab('Parent',tgrp,'Title','tab2');
t1=uitable('Parent',tab1);
a=findjobj(t1),
%%
t2=uitable('Parent',tab2);
%%
a=findjobj(t1),
b=findjobj(t2),
a==b,
Matlab does not actually render the Java component until it is displayed at least once. So until that time, findjobj will return empty.
In R2014b the entire underlying graphics rendering engine has changed (so-called HG2) so it is not surprising that things that worked well in 14a need to be adapted to work in 14b. In fact, I find it a small miracle that findjobj still works well [most of the time] in 14b... In your case, you can simply activate the tabs programmatically, and call drawnow(), and this should solve your issue.
I had a similar error to Sneha, coming when a findjobj call that worked in 2014a returned an empty results in 2014b.
It my case, I was creating a uitable on a TabPanel from the GUILayoutToolbox. findjobj was not able to find the uitable after creation. It was able to find it after I changed the active tab to be that containing the uitable.
Not sure if that helps - or exactly why findjobj cannot find the object before the tab is activated.
I am also getting an error using this function in the 2014b version. "No appropriate method, property, or field getViewport for class handle.handle."
Zoé - download the latest version, it should work ok on R2014b.
Unfortunately, findjobj not seem to work in R2014b:
findjobj: Error using javahandle.com.mathworks.hg.peer.UITreePeer/set
The name 'NodeExpandedCallback' is not an accessible property for an
instance of class 'com.mathworks.hg.peer.UITreePeer'.
Error in findjobj/presentObjectTree (line 1524)
set(tree_hh, 'NodeExpandedCallback', {@nodeExpanded, tree_h});
Error in findjobj (line 303)
presentObjectTree();
Dear Yair,
Somehow the code seems to not always work when I run .m file. I built a GUI with a pushbutton and a edit box. If i press the pushbutton i can chose data such as .txt and .csv files and write the first 20 lines in the edit box. However, sometimes, when loding the same files (what I get when I load them is also identical, so it should not be my data loading function), there is a horizonal scrollbar and sometimes there is not. The follwoing I wrote in the GUI opening function:
jScrollPane = findjobj(handles.edit1);
set(jScrollPane,'VerticalScrollBarPolicy',20); jScrollPane.setHorizontalScrollBarPolicy(30);
jViewPort = jScrollPane.getViewport;
jEditbox = jViewPort.getComponent(0);
jEditbox.setWrapping(false);
Do you have any idea? Is there a bug or is it just me (more likely XD)
Thanks,
Kathi
I use findjobj to add icon on multiples Button and use Progressbar...but when i run the Gui, it open and close ( flasjing)at each "findobject" call.
then works fine... any idea what's going on ?
jButton = java(findjobj(handles.Apply, 'nomenu'));
myIcon = fullfile(currentDir,'/icons/apply.png');
jButton.setIcon(javax.swing.ImageIcon(myIcon));
jButton.setBorder(raisedetched);
Michael
How to put matlab on steroids! Very useful to have more control of your GUI.
Very useful and very cool
Sebastian - perhaps the nested panels cause the reported pixel position of the mtable to be slightly different than the jtable, causing the jtable not to be found at the expected position/size. This would not surprise me since each uipanel ads a 1-2 pixel border on each side so the more uipanels that you nest the larger the probability of a position mismatch.
Dear Yair;
Sorry about the confusion - my comments doesn't seem to have posted correctly.
I have used your excelent findobj on many occasions but today discovered a strange behaviour. When nesting many panels inside each, findjobj does not seem to be able to find that underlying java table handle. As a simple example:
subpanel1 = uipanel('Parent', gcf, 'units','normalized','Position',[0 0 1 1]);
subpanel2 = uipanel('Parent', subpanel1, 'units','normalized','Position',[0 0 1 1]);
subpanel3 = uipanel('Parent', subpanel2, 'units','normalized','Position',[0 0 1 1]);
subpanel4 = uipanel('Parent', subpanel3, 'units','normalized','Position',[0 0 1 1]);
% This works correctly
mTable= uitable('Parent',subpanel3,'Units','normalized',...
'Position',[0.02 0.14 0.96 0.84]);
jHandle = findjobj(mTable)
% This does not work - findjobj returns empty
mTable2= uitable('Parent',subpanel4,'Units','normalized',...
'Position',[0.02 0.14 0.96 0.84]);
jHandle2 = findjobj(mTable2)
Any thoughts?
Best regards
Sebastian
Dear Yair;
Adding to my previous comment, I have noticed that findjobj(gcf,'class','uitable') correctly finds the handle also in the later case. The trouble with this in my case is that I have several tables in the GUI and this returns a vector of all tables and all I have found no way to distinguish between these to extract the particular one that I want.
Best Regards
Sebastian
Yair - I've found one issue that should be resolved:
If after calling findjobj with the "persist" option the main GUI window is moved, then subsequent calls to findjobj will fail to return the object handle. This is because the container (or pContainer) is one of the persisted variables, and the processPositionArgs function uses container.getX and container.getY to filter the java objects.
To make matters worse, a subsequent call to findjobj without the "persist" argument does not disable persistence. The way I read the code, the only way to force findjobj to recalculate all of the positions is to call it first on a separate figure with the "persist" argument and then on the desired figure without the "persist" argument. (I haven't tested this so I could be wrong). I think this could be fixed fairly easily with a few code changes around line 237.
The complete fix will be a little more involved though.
It looks like others (i.e. Kesh Ikuma) have had similar issues. I've rated this as a 4 for an awesome tool. This would be a 5 if the "persist" option could be made to reset if the figure is moved or resized.
Yair - What do you think of adding a flag 'repersist' (or whatever name you think best describes the feature) to rescan the container to update the persistent data?
I run into a problem by calling findjobj(...,'persist') multiple times as the GUI is constructed. I've modified line 240 to
"if isequal(pContainer,container) && ~paramSupplied(varargin,'persist')"
for the time being but would love to have an official feature to account for this case.
Thanks, Kesh
@Dan - maybe, it should be simple enough to test
Yair,
Thanks for the feedback.... Would it work if I were to undock the figure, find the object, and then re-dock? Or would the act of re-docking the figure change the handles?
@Dan K - This is correct: findjobj is not expected to work for docked figures since the Java components hierarchy in this case is entirely different - a docked figure is merely an internal panel within the Desktop window, not a standalone Frame/window as in the undocked case.
Maybe one day I'll upload a fix for this, but I don't expect it in the near term.
Yair,
Thank you for the great utility. One item I noticed. It doesn't work with figures that are docked. If I use:
hButton = uicontrol('string','click me');
jButton = findjobj(hButton,'nomenu');
On an undocked figure, it finds the handle, but if I dock the figure, it returns an empty matrix. Thoughts?
Thank you Yair!
By using this function I was able to work around a problem in some code I am writing, that has been bugging me for days!
@Satwik - you can tell findjobj to search by position and/or class, not just size - read the findjobj help.
In my experience, the position sometimes changes by a few pixels on different systems but the size remains the same - it's odd that you find that size changes.
First off, thanks for all the great submissions. They greatly extend the utility of MATLAB GUIs.
I ran into a strange problem using findjobj, which has its origin upstream, but comes from findjobj finding elements by position.
On a GUI created by a colleague, findjobj works perfectly on windows machines, but fails intermittently on linux.
I have traced this back to the fact that the size detected seems to change sometimes in linux, despite the fact that these are hardcoded in the gui. For example the height component of contentSize in getRootPanel changes and this causes the baseDeltas for the height to go out of the accepted range.
I realize this is likely not an issue with findjobj, but I was wondering if you had run into this issue before and/or could offer some suggestions on how to ensure reliable detection of gui size.
Ok thanks, that was it.
If I change any uicontrol's (edit box) properties after I've changed its pointer (I have done a calendar of which days are edit boxes and I want its hover pointer set to default arrow and not |), it seems to malfunction the setCursor.
What I want to know is if an uicontrol's propeties are being constantly changed do their setCursor property reset to default or I just have to change it once.
Summing up, what I want is to change a calendar's edit boxes days pointer to the default arrow.
Thank you.
Ricardo - the button is probably not visible at the time that you call findjobj. It has to be visible to work
First of all, thank you for all your contributions. I've read you a lot.
I can't get the fidjobj working on R2012b, it returns me always []
e.g.
>> hButton = uicontrol('string', 'Hello');
jButton = findjobj(hButton);
jButton
jButton =
[]
UPDATE:
It works now. I had to re-set the callback function after b = findjobj(handle2).
It seems that the second call to findjobj, deactivates the callbacks for object a.
Thanks for your help.
There is no real reason that it should not work. Perhaps one of the tables was not visible at the time that findjobj() was called. place a breakpoint on both lines to check whether this is in fact the case.
Thanks for your answer. I don't mean vectorization.
I have problems using
a = findjobj(handle1)
b = findjobj(handle2)
Both calls were made from different functions, handle1 and handle2 are different tables in the same GUI. call_1 XOR call_2 works fine. Any suggestions?
@ismirbrille - findjobj only works on a single component at a time, it is not vectorized. To get the underlying Java objects of multiple Matlab controls you would need to call findjobj separately for each of the controls.
@Yair Altman - Thank you for this code, very useful, good job!
Do you currently work at a version which supports multiple container objects?
I have to use 2 tables with java functionality at a time.
Sad, that Matlab doesn't support modern GUI development.
Thanks for the great work to overcome the limitations!
Ok, Thank you!!!! Yair Altman
@Katana13 - Java customizations are not saved in FIG files. See here for a discussion and workaround: http://undocumentedmatlab.com/blog/figure-toolbar-components/#comment-13897
Extremely useful toolbox for creating GUIs. I don't know if it's a limitation (Matlab R2012a). Example:
h = figure('Menubar','none', 'Toolbar','none','Tag','figure');
str = ' je suis vraiment le plus beau de la planete terrrer de la foucv oeufe fz ozfz efz fvousf zefzf ouvzfz ozfz fouz fz fzo ufzf zouz fozufozf uzo fzoufzo fuziofz fzofiuzfoiz fouzfo ';
hEdit = uicontrol('Parent',h, 'Style','edit', 'FontSize',9, ...
'Min',0, 'Max',2, 'HorizontalAlignment','left', ...
'Units','normalized', 'Position',[0 0 1 1], ...
'String',str,'Tag','hEdit');
%# enable horizontal scrolling
jEdit = findjobj(hEdit);
jEditbox = jEdit.getViewport().getComponent(0);
jEditbox.setWrapping(false); %# turn off word-wrapping
jEditbox.setEditable(false); %# non-editable
set(jEdit,'HorizontalScrollBarPolicy',30); %# HORIZONTAL_SCROLLBAR_AS_NEEDED
%# maintain horizontal scrollbar policy which reverts back on component resize
hjEdit = handle(jEdit,'CallbackProperties');
set(hjEdit, 'ComponentResizedCallback','set(gcbo,''HorizontalScrollBarPolicy'',30)')
saveas(h,'test','fig');
No problem, if you directly run the script (horizontal + vertical scrollbar available). But if you launch the saved file : 'test.fig', the horizontal scrollbar becomes unavailable.
Thanks
Extremely useful function that helped me alot. Just excellent!
Thanks for the support!
I used findjobj to update a table position, and it works well, but there are some rendering artifacts as a result of the update - hopefully seen here: http://imgur.com/uJYps3Y .
Apologies, as I am not too familiar with java, but a simple drawnow doesn't seem to help.
@Georgios - the control must be visible for findjobj to work. You can make the figure visible in the OpenFcn using the commands
set(hObject,'Visible','on'); drawnow;
If you don't want the figure to physically appear onscreen, you can set its position to [-300,-300,200,200] or some other off-screen location. The figure will become visible but hidden... You can later move it to your screen center in the OutputFcn.
Hallo and congrats for the excellent code!
My issue is the following:
I need to use the findjobj, before the uicontrol is properly rendered.
Is there a way to achieve this?
(I need to set some attributes of the uicotnrol, in the OpenFcn function of the GUI.) Which means that the uicontrols are not yet rendered.
@Echidna - findjobj works out-of-the-box and does not require any additional installation or file, including in deployed (compiled) apps. So I am 99.99% certain that the problem is in your code. It could be due to one of several possibilities:
1) perhaps your editbox has not become visible onscreen long enough before your call to findjobj. Findjobj must have the control visible before it can find its underlying Java component. Place calls to pause(0.1) and drawnow before your call to findjobj, to ensure that this is indeed so.
2) maybe your callback function became invalid for some reason. For example, if you modify the editbox from multi-line to single-line or other similar changes, then the underlying Java control may have changed, forcing you to re-set your callback
3) maybe your update callback is being called but runs into a bug when updating the listbox for some reason. Place debug printouts in your callback to check this.
This code works great when I run my GUI directly in Matlab BUT when I compile it into an executable using deploytool, it does not always work. More specifically it works the first time I change the text in the edit box, sometimes the second time but somewhere thereafter (always at a different point), it does not seem to work anymore (i.e. no update of my listbox when I type in the edit-field and some other strange stuff sometimes happens as freezing of the list box, not finding the text string even though I know it is there and such).
Is this a known bug and how can I solve this? Is there another file that I need to include in the "Shared resources and helper files" section besides the findjobj.m file which I of course have included?
@Peter - as far as I could test, the latest findjobj works correctly on R2012b. try running your two lines in a new figure and see for yourself. Perhaps in your specific GUI findjobj cannot find the slider control for some reason. One possible explanation is that the uicontrol is not fully rendered (displayed) when findjobj is being run. In this case, placing a short pause(0.05) and drawnow(), might help. Also ensure that the slider is actually displayed onscreen (Visible=on, valid Position and Value).
I've used this module successfully for many years, thanks.
With R2012b I've got problems:
jh = findjobj( slider, 'nomenu');
jh.AdjustmentValueChangedCallback = @(src,event)sliderCallbackFunc(src);
and the second line results in an error
Incorrect number of right hand side elements in dot name assignment. Missing [] around left hand side is a
likely cause.
Anybody else had related problems under R2012b.
@Changshun Deng - I believe that the latest version of FindJObj that I uploaded yesterday solves this issue
Hi, I run this programe findjobj(jEditor) as http://undocumentedmatlab.com/blog/accessing-the-matlab-editor/
I can not get the objects of editor.
an error: ??? findjobj: There is no 'UserData' property in the 'javax.swing.JTable$1' class.
my matlab version is: MATLAB Version 7.4
@Ward - thanks - I believe that you may be right. This has no effect unless there are several overlapping/similar results in the filtering process, which is very rare. But in such rare cases, your fix would solve a problem of returning both the parent and the child handles.
On lines 646-649 you discard the first if in the original handles the first is the parent of second. Is this correct after Args processing or should the first line be
if length(foundIdx) > 1 && isequal(handles(foundIdx(1)).java, handles(foundIdx(2)).getParent)
This is a very cool tool, but I'm running into the same problem that Michael had - if I compile the code, I get a metric ton of "file is empty" messages. Everything works fine, it just gets in the way of other things I'd like to use the output window for. Any hope of an update to address this?
@HaveF - you don't need to use the 'nomenu' parameter when you specify an input handle such as hButton.
I cannot reproduce any of the issues that you report. Perhaps try to download the latest version of the utilities.
Try adding a call to drawnow and/or pause(0.1) before you call findjobj. Also, ensure that the control is actually visible (findjobj can only detect visible components).
seems lost something...
When I try findjobj, something strange on my machine.
>> hButton = uicontrol('string','click me'); jButton = findjobj('property',{'Text','click me'});
it's all right as I expected.
but
>> hButton = uicontrol('string','click me'); jButton = findjobj(hButton,'nomenu')
just return *ans = <1x0>*
and another thing, I am a big fun of yours.
I use setPrompt before, but when I try findjobj, my prompt disappear.
just like this:
[18:57:11]temp_proj>>
[18:57:11]temp_proj>>
[18:57:11]temp_proj>> hButton = uicontrol('string','click me');
[18:57:16]temp_proj>> jButton = findjobj('property',{'Text','click me'});
>>
and another thing, I am a big fun of yours.
I use setPrompt before, but when I try findjobj, my prompt disappear.
just like this:
[18:57:11]temp_proj>>
[18:57:11]temp_proj>>
[18:57:11]temp_proj>> hButton = uicontrol('string','click me');
[18:57:16]temp_proj>> jButton = findjobj('property',{'Text','click me'});
>>
Excellent!
the above code works - often ;)
sometimes it throws:
No appropriate method, property, or field getViewport for class handle.handle.
-> class handle.handle => haha
how can i assure findjobj found the table?
currently i retry on failure:
code:
function setTableSelectedCellColor(table)
%
try
jUIScrollPane = findjobj(table, 'nomenu');
jUITable = jUIScrollPane.getViewport.getView;
jUITable.setSelectionBackground(java.awt.Color(1,1,1));
jUITable.setSelectionForeground(java.awt.Color(0,0,0));
catch
setTableSelectedCellColor(table);
end
end %function
end code
Fabulous!
I use it to avoid selection induced color change for a table with white background:
code:
% create the table
table = uitable( ...
'Parent', layout,...
'ColumnWidth', {100, 150}, ...
'ColumnName', {tableTitle}, ...
'RowName', [], ...
'ColumnFormat', {'char', selectionList}, ...
'ColumnEditable', [false, true],...
'Data', tableData, ...
'CellEditCallback', @selectionChanged);
% workarount to avoid seletion induced color change
jUIScrollPane = findjobj(table);
jUITable = jUIScrollPane.getViewport.getView;
jUITable.setSelectionBackground(java.awt.Color(1,1,1));
jUITable.setSelectionForeground(java.awt.Color(0,0,0));
end code
is there a way to make the findjobj command faster?
@Evzen - for some reason, you got the handle of a uitable rather than the editbox, and of course you cannot set the page URL for uitables...
Perhaps your uitable resides at the same pixel position as the editbox?
Try to place a breakpoint on the line following the call to findjobj to determine exactly which object it found.
More information on setting rich editbox contents can be found here: http://undocumentedmatlab.com/blog/rich-matlab-editbox-contents/
Awsome utility. Thanks for sharing, but I have a little problem and i dont resolve it. I use a code from your webpage, but it give me this error with method setPage:
No appropriate method, property, or field setPage for class
com.mathworks.hg.peer.ui.UITablePeer$22.
hEditbox = uicontrol('style','edit', 'max',5);
jScrollPane = findjobj(hEditbox);
jViewPort = jScrollPane.getViewport;
jEditbox = jViewPort.getComponent(0);
jEditbox.setPage('http://www.google.com');
@Sean - you don't need findjobj to access specific toolbar buttons - you can use the built-in findall function, as explained here: http://undocumentedmatlab.com/blog/modifying-default-toolbar-menubar-actions/
This is an awesome tool. Thanks for your sharing your work Yair.
I'm trying to use findjobj to get the java handle for a toolbar uitogglebutton. It does not find the handles for the button. When I call the function like this:
findjobj;
it finds the toolbar button. Why is this and is there a way I can modify findjobj to directly find toolbar buttons?
Works super! Nevertheless, when I compile this line:
jScrollPane = findjobj(handles.editBox)
and I execute the code, I get many times the message 'File is empty' in the command line. Anyway, the code works nevertheless!? Any ideas?
Best regards!
PS: I use your tool to extract selected text from an edit box.
Finally got it to work, thanks a lot for the updates!
Hi Guys,
I have written the following code in _OpeningFcn(because I have used GUIDE!),
pause(0.01);
drawnow;
jb=findjobj('class','pushbutton');
drawnow;
set(jb(2), 'MousePressedCallback', @UpVertTest);
guidata(hObject, handles);
--------------------
Up to here everything works fine,
But at the end of my m file where I define the related function(UpVertTest) I have problem,
I want to have access to normal handles and do some changes, But I get this error:
??? Undefined function or method 'toDouble' for input arguments of type 'java.awt.Dimension'.
Error in ==> opaque.double at 80
dbl = toDouble(opaque_array(1));
Error in ==> guidata at 85
if isscalar(h) && ishghandle(h)
Error in ==> RatRobot_GUI4>UpVertTest at 523
handlesData=guidata(src);
this is the code I have written:
function UpVertTest(src, evnt)
% trying to access to handles
handlesData=guidata(src);
% set new initial value in GUI
set(handlesData.VerticalPosStart,'string',handlesData.initZ-handles.Step(3));drawnow;
-----------
I think there is something wrong with my function definition,
any ideas?
I used the findjobj-function as described at http://undocumentedmatlab.com/blog/customizing-listbox-editbox-scrollbars/ to disable text-wrapping and display a horizontal scroll-bar in a GUI edit-box.
Many thanks for this fabulous tool. It works like a charm.
after further testing, following the use of findjobj, from time to time i get the following errors:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.text.BoxView.calculateMinorAxisRequirements(BoxView.java:886)
at javax.swing.text.html.BlockView.calculateMinorAxisRequirements(BlockView.java:129)
at javax.swing.text.BoxView.checkRequests(BoxView.java:918)
at javax.swing.text.BoxView.getPreferredSpan(BoxView.java:528)
at javax.swing.text.html.BlockView.getPreferredSpan(BlockView.java:345)
at javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan(BasicTextUI.java:1342)
at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(BasicTextUI.java:908)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1622)
at javax.swing.JEditorPane.getPreferredSize(JEditorPane.java:1412)
at com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline.getPreferredSize(EditTextPeer.java:864)
at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:769)
at java.awt.Container.layout(Container.java:1421)
at java.awt.Container.doLayout(Container.java:1410)
at java.awt.Container.validateTree(Container.java:1507)
at java.awt.Container.validate(Container.java:1480)
at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:670)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:124)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:633)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
is there a workaround?
that does make sense. thank you for clarifying that.
Jveer - FindJObj *cannot* work in the GUIDE-created *_OpeningFcn because the figure is not yet visible at this time and so the Java components have still not rendered and therefore cannot be found.
Try placing your call to FindJObj *after* the figure has become visible and all the controls have completed rendering, for example by moving your FindJObj call to the *_OutputFcn function, hopefully after a call to drawnow to ensure that everything has completed rendering.
i'm sorry to report it still doesn't work. downloaded it today, tried it on r2009b and r2010a. frustratingly sometimes it works sometimes it doenst.
1) run from a script - it works
2) run from opening function of a GUI created using guide - doesn't work
3) run the script from #1 after #2 failed - it doesn't work!
4) reopen matlab and run #1 - works
very strange.
Patrick, Emad & Jayveer - I have yesterday uploaded a new version of FindJObj that fixes the problem you have reported.
FYI, the problem occurred due to a slightly different implementation of the Java hierarchy for Matlab figure windows. The new code should work find on all the older Matlab 7 versions *IN ADDITION* to R2010a.
As always, I am very committed to fixing such utilities, to the best of my abilities, also in upcoming Matlab releases.
findjobj returns [] on r2010a !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
which makes the following tutorial useless!! - http://undocumentedmatlab.com/blog/rich-matlab-editbox-contents/#EditorKit along with everything else on the website since they all depend on finjobj!
I have the same problem as Patrick.
I made a slider using GUIDE; its handle is hSlider.
I called jSlider = findjobj(hSlider);
I tried this with MATLAB 2007b, this worked very well, thank you.
Then I tried this with MATLAB 2009a, findjobj returned empty!
Actually, calling findjobj with any arguments all returned empty.
What did I do wrong?
Dear Malcolm - Thanks for the feedback.
ApplicationData is a hidden property which is not shown by the property inspector used by FindJObj.
To see this information, simply select the relevant object in the FindJObj hierarchy tree and click the "Inspect object" button. This opens the UIInspect utility, which does display ApplicationData (if available) in UIInspect's bottom-right ("other properties") table.
If you need more control, you can always use FindJObj's "Export to workspace" button, and get the ApplicationData from the exported object handle.
Superb tool Yair. Do you any plans to provide access to the application data areas of the objects e.g. from the context menu in the left-hand panel?
That's simply amazing how deep inside could you get into Matlab internals! That's incredibily useful if one needs to bult-in matlab into Java application. Something like this should be definetely included into Builder JA
thx
Great function. The interactive display is a brilliant feature.
I made a slider using GUIDE; its handle is hSlider.
I called jSlider = findjobj(hSlider);
I tried this with MATLAB 2007b, this worked very well, thank you.
Then I tried this with MATLAB 2009a, findjobj returned empty!
Actually, calling findjobj with any arguments all returned empty.
What did I do wrong?
Why do I get this error whenever i tried findjobj;
??? findjobj: Undefined function or variable "jcb".
I have the latest version of findjobj file.
I've actually solved my problem. After reading this page: http://undocumentedmatlab.com/blog/uicontrol-callbacks/,
I tried changing the way I set the callbacks. Before, I set the callbacks directly on the java-object. However, when I used the handle() function and then set the callbacks the problem disappears.
In summary:
before:
set(myJavaObject,'MouseReleasedCallback',@callbackfcn);
now:
myHandle = handle(myJavaObject,'CallbackProperties');
set(myHandle,'MouseReleasedCallback,@callbackfcn)
I've been using this file for about a year now (great work Yair!), and a very weird issue has crept up now that I've upgraded from R2007b to R2008b.
What happens to me is that I have a few custom java-objects instantiated (they are a modified version of the java-swing table), with userdata and function callbacks associated with them via calls like: set(myTableObj,'MouseReleasedCallback',@callbackfcn);
set(myTableObj,'userdata',data);
After findjobj returns, all of the userdata and callbacks have been cleared out. I've stepped through findjobj line by line, and cannot find a culprit. In fact, when I get to the "return" line on 279, the userdata and function callbacks are still properly associated with the java-objects. However, once findjobj returns, all userdata and function callbacks of my java-objects are cleared to an empty matrix.
Any thoughts on this?
@Leonardo - FindJObj does not enable modifying the displayed object hierarchy - perhaps I will add this feature in a future version. You need to update the hierarchy outside FindJObj and then click on the <Refresh Tree> button.
Great file! i just have one doubt using it: if I can chance the order of some structures. I have some check boxes and using 'tab' to select them is completely out of order, and using this function I found that it's following the specific order that is on the tree.
So, can I change the place of my tree's items?
thanks for the code
Great work, Yair! I have refferenced it in my spaces.
Only one suggestion: To be compatible with future versions of ML, the use of "JavaFrame" in your function should be avoid. The "JavaFrame" is a com.mathworks.hg.peer.FigurePeer Object, it can be easily obtained using a JAVA approach instead of the get(hfig,'JavaFrame'). For example, you can get if from the mde's Client.
ucd puri,
> but i did not understand how did you figured out
> AdjustmentValueChangedCallback attribute in line below
I just used findjobj itself:
hSlider = uicontrol('style','slider' );
findjobj( hSlider )
Dennis
btw: did I mention findjobj is excellent !?
Awesome tool to find the underlying java objects of MATLAB objects! Works great!
Great work!
brilliant!
Another suggestion (valid for Matlab 7.5):
If you want to inspect the Editor-container, you will need to change lines 175-176 from
origContainer = container;
contentSize = [container.getWidth, container.getHeight];
to
origContainer = container;
if strcmp(container.getName,'Editor');
container=container.getInternalFrame;
end
contentSize = [container.getWidth, container.getHeight];
Sebastian
Info for MATLAB 7.5.
An inconsistency in uitreenode.m (%MATLAB%\toolbox\matlab\uitools\uitreenode.m) prevents "findjobj" to work properly. You have to change the first line in "uitreenode.m" from ...
function node = uitreenode(value, string, icon, isLeaf)
... to ...
function node = uitreenode(dummy,value, string, icon, isLeaf)
... , then everything initializes just fine.
After fixing that, it's SWEET! I've just spend hours and hours writing down the hirarchy of objects and was just starting to think, how nice it would be to have everything at hand in "file"-browser ... well, you know it: it's all on the FEX, ... somewhere ...
Thanks,
Sebastian
thanks
ucd puri - jControl and uiComponent are simply Matlab functions that enable easy access and usage of Java controls, which in general are more powerful than the basic Matlab controls. The FindJObj function is useful for finding the handle of a Java control within a Matlab figure, similarly to Matlab's basic findobj function.
Java control functionality can be googled (e.g., "java jslider") , or you can read any good book or online tutorial about Java Swing (e.g., java.sun.com/docs/books/tutorial/uiswing/components/). Alternately, you can use my uiInspect submission on the Matlab File Exchange to see exactly which properties/methods/callbacks are available for any component (Java, Matlab or COM) - http://www.mathworks.com/matlabcentral/fileexchange/17935
Yair Altman
I implemented this function Dennis's way. it works perfect. Thanl all. but i did not understand how did you figured out AdjustmentValueChangedCallback attribute in line below
jSlider.AdjustmentValueChangedCallback = {@FollowSliceSliderCallback,guidata(gcbo)};
Which all other attributes i can use with jSlider.(.....)
and how to find ot about them.
Regards n Thanks for tips
Tanuj
HI All, One more stupid question if you dnt mind. I am an intermidiate user of matlab, and learning more. I did not exactly understood the difference between
1) jControl function
2) findjObj function, and
3) uiComponent function.
Regards n Thanks for help. Tanuj
The R2008 warnings can be eliminated by typing:
warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
warning('off','MATLAB:uitreenode:MigratingFunction');
I'll add it to a new version soon, but you can simply use this in your startup file or your Matlab Command Window.
Yair
Running this in R2008a brings up the warning:
Warning: figure JavaFrame property will be obsoleted in a future release. For more information see the JavaFrame resource on
the MathWorks Web site.
> In findjobj>getRootPanel at 266
In findjobj at 164
I guess, ln 257 should be
set(0,'ShowHiddenHandles','on');
instead of
set(0,'ShowHiddenHandles','off');
thanks!
a great piece of work! thanks!
Yair, is that possible for you to make it compatible with 08a? it causes a bunch of thread error/warning in 08a.
thank you!
Peter - all you need to do to prevent scanning the menu-bar is to add the '-nomenu' option. For example: jObj=findjobj(hObj,'-nomenu'); Unfortunately, I could not find a way to scan the menu-bar without actually activating all menu options.
Is it just me or does everyone who uses this script have problem on initialization.
Whenever start my own script which uses findjobj, "it" scrolls through the top menu ('file', 'edit','view','insert',...'help'). This is a little annoying
Thanks for the reply, Yair!
I am using: % $Revision: 1.9 $ $Date: 2007/08/14 23:03:04 $ which is the version I get when clicking the .m button on Mathworks (this page). Is there indeed I later version?
Nevertheless, you provided the solution saying the control has to be rendered. I created both the uicontrol AND the javacallback in the OpeningFcn.
I left the creation of the uicontrol in place but now I moved the below lines of code to the OutputFcn (not sure if that's a proper place for such purposes though):
jSlider = findjobj( handles.sliceSlider );
drawnow;
jSlider.AdjustmentValueChangedCallback = {@FollowSliceSliderCallback,guidata(gcbo)};
Now it works perfectly. Thanks again!
Dennis
Thanks for your feedback Dennis.
Please ensure you're using the latest version of FindJObj (currently dating 2007-11-13). Also, when calling findjobj immediately after creating a UI control, you must let the Matlab/Java engine time to fully render the control. This can be done with a simple drawnow command, possibly followed by a small pause(0.01).
Yair
I found out that
jSlider = findjobj(hSlider)
ans = <1x0>
eventhough just doing
findjobj
lists all java-objects including the slider.
Also, when just using the Command Window, it works find: I can create figure with a slider with a callback that continuously calls an .m file.
Dennis
Using Matlab 7.5 (R2007b) and doing
1 hSlider = uicontrol('style','slider' );
2 jSlider = findjobj(hSlider);
3 jSlider.AdjustmentValueChangedCallback = @FollowSliceSlider_Callback;
I get:
No public field AdjustmentValueChangedCallback exists for class handle
Using:
set(jSlider,
'AdjustmentValueChangedCallback', @FollowSliceSlider_Callback );
I get no error, but the callback function is never reached.
Am I missing something here?
Thanks for any help
Dennis
Bob - the bottom tree branch that FindJObj displays is the Handle Graphics hierarchy - only the top branch is the Java hierarchy. If you don't see it, perhaps you're not using the latest version of FindJObj.
This is interesting, would it be easy to organize the objects the way as they are thought of in the Child/Parent as the handle graphics user would see them?
the cellfun behavior has changed in Matlab 7.1 - unfortunately FINDJOBJ relies on the new behavior, so you must have version 7.1+ to run. Sorry about the confusion...
Hello Yair!
Sorry for typing mistake in the post. The matlab command issued is "findjobj" and not "finjobj". I have not renamed the file. The file name is kept "findjobj.m" only. I ensure that script is run by setting breakpoints in the m-file.
So here I restate the problem.
If I issue the command, the figure window is created and I get following error message
>> findjobj
findjobj
??? findjobj: Function name must be a string.
If I set breakpoint for error,the error is reported at line 234 of the code. The value of error variable is
K>> err
err =
message: 'findjobj: Function name must be a string.'
identifier:'MATLAB:cellfun:InvalidFirstInput'
The Java version is
Java 1.5.0 with Sun Microsystems Inc. Java HotSpot(TM) Client VM (mixed mode)
with regards,
YP
--
On MATLAB Version 7.0.4.365 (R14) Service Pack 2 I get following error when findjobj is run (with and without arguments)
>>finjobj
??? findjobj: Function name must be a string.
It is the best piece of code on Matlab/Java I have ever seen in Matlab Central. I am very grateful to the author for sharing his knowledge.