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

Setting line position in an edit-box uicontrol

March 26, 2009 21 Comments

I often see requests in the Matlab forum (CSSM) regarding modifying some uicontrol property that is not exposed by Matlab. Since all Matlab uicontrols are based on underlying Java Swing controls, accessing these features is possible via their Java control peers.
In this post I will give the example of setting the caret (cursor) position in a multi-line edit-box. Apparently, whenever the string contents of such a uicontrol is modified, Matlab automatically sets the caret position on the first character of the first line. It is often requested to place the caret on the last line, so that the last line scrolls into view, rather than the first line. This is the case, for example, if you wish to display an event log that keeps adding new entries at the bottom.
The first step in accessing the underlying Java control is to download my FindJObj submission on the File Exchange. FindJObj searches down the window frame hierarchy until it finds a Java control with the exact position and size of the requested Matlab HG handle (FindJObj has lots of other goodies which will be described in another post).
Once we have the Java peer reference handle (in our case, a UIScrollPane object), we select its internal edit-box control (an object of class com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline) and use its setCaretPosition() method to move the caret to the end of the text:

>> % Create the multi-line edit-box
>> str = {'multi','line','editbox'};
>> hEdit = uicontrol('style','edit','max',3,'string',str);

Editbox caret at top row (default)
Editbox caret at top row (default)

>> % Get the underlying Java control peer (a scroll-pane object)
>> jhEdit = findjobj(hEdit)
jhEdit =
	javahandle_withcallbacks.com.mathworks.hg.peer.utils.UIScrollPane
>> % Check that the scrollpane has a multiline edit control and 2 scrollbars
>> jhEdit.list
com.mathworks.hg.peer.utils.UIScrollPane[...]
 javax.swing.JViewport[...]
  com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline[...]
 com.mathworks.hg.peer.utils.UIScrollPane$1[...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[...]
 com.mathworks.hg.peer.utils.UIScrollPane$2[...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[...]
>> % Get the scroll-pane's internal edit control
>> jEdit = jhEdit.getComponent(0).getComponent(0)
jEdit =
com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline[...]
>> % Now move the caret position to the end of the text
>> jEdit.setCaretPosition(jEdit.getDocument.getLength);

Editbox caret at bottom (via Java)
Editbox caret at bottom (via Java)

Setting the caret position works, but is actually better done on the EDT using awtinvoke or javaMethodEDT. This will be explained in a separate EDT-specific article.

Related posts:

  1. Additional uicontrol tooltip hacks – Matlab's uicontrol tooltips have several limitations that can be overcome using the control's underlying Java object....
  2. Uicontrol callbacks – This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
  3. Setting listbox mouse actions – Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  4. Customizing uicontrol border – Matlab uicontrol borders can easily be modified - this article shows how...
  5. Setting status-bar text – The Matlab desktop and figure windows have a usable statusbar which can only be set using undocumented methods. This post shows how to set the status-bar text....
  6. Setting status-bar components – Matlab status-bars are Java containers in which we can add GUI controls such as progress-bars, not just simple text labels...
FindJObj GUI Java uicontrol
Print Print
« Previous
Next »
21 Responses
  1. Heiko April 17, 2009 at 05:59 Reply

    Hi. Yesterday I stepped over the findjobj function (actually a very fine piece of work, thank you very much!) while looking for a way to link the selected cells of multiple uitable objects (R2009a). I have four uitables showing related data at different processing stages. What I wanted was to click on one table and select the same cell in all four tables, which is not a native uitable property to set (or even get! The selected cell is given only in the CellSelectionEvent). With findjobj I found several promising methods. The methods “setRowSelectionInterval” and “setColumnSelectionInterval” seemed to link to the method “setSelectionInterval” of the javax.swing.DefaultListSelectionModel but it didn’t work at all. The method “changeSelection” (seems to be a wrapper from the MathWorks) finally did almost what I wanted. It selected the correct cells when I first clicked on a table, but after that, clicking on the tables directly entered the cell editing mode, even if this was disabled for the uitable object, and so the cellSelectionEvent was not fired anymore. I also couldn’t find out what the parameters of the method are. It takes four of them, the first is the row, the second is the column. The other two do change the behavior in an undescribable way. Do you have any hints where I can find out about the parameters of “changeSelection”, and if there is something else I could do to get the behavior I like to have? Maybe I misunderstood the SelectionInterval-functionality, but it didn’t change anything on the java objects. Thank you for reading!

    • Yair Altman April 17, 2009 at 06:38 Reply

      You can do 2 things with a standard JTable and the old uitable, but I’m not sure they work with the new uitable (no harm trying):

      1. Set all the table columns as non-editable using somthing like the following:

      for colIdx = 0 : numCols
      tablePeer.setEditable(colIdx,0); % 1:end doesn’t work…
      end

      2. Set all the table column CellEditors to have infinite ClickCountToStart, like this:

      for colIdx = 0 : numCols
      try
      editor=tablePeer.getColumnModel.getColumn(colIdx).getCellEditor;
      editor.setClickCountToStart(intmax); % i.e, never enter edit mode…
      catch
      % never mind…
      end
      end

      One or both of these may work for you.

      • Heiko April 19, 2009 at 23:29

        Thank you for the answer.

        Unfortunately, both of your options don’t work. But while trying I found that fiddling with the java settings alters the uitable properties in an unpredictable way. For instance, the ColumnEditable property is reset to default (1), which caused the described behavior.

        Another problem is, that there seems to be a loop through many different callbacks that call my CellSelectionCallback. Especially from the second selection it takes seconds for the tables to react, and the result is wrong.

        I stop working on this for now. Thank you again! Bye

  2. A. Bindemann June 1, 2009 at 05:25 Reply

    Yair,

    I’m having a problem with findjobj. It returns an empty result when I pass it the MATLAB handle of an edit box. The problem appears to begin in the call to getRootPanel on line 319 (jRootPane = jFigPanel.getRootPane).

    The function falls through to line 346 (jRootPane = jRootPane.getTopLevelAncestor;) which also returns an empty result.

    I’m trying to use a MATLAB GUI to display a message log, and would like to position the cursor at the end of the edit box. Interestingly, the edit box behavior under R14SP3 always placed the cursor at the end of the edit box. The behavior changed somewhere between that version and R2007b.

    Any ideas you might have would be appreciated.

    Thanks,
    A. Bindemann

    • Yair Altman June 1, 2009 at 10:38 Reply

      @Bindermann – I can think of two reasons for this problem:

      1. the figure or one of its components is hidden, thereby causing a problem in retrieving the RootPane and/or TopLevelAncestor (=Frame peer) references.

      2. are you using the latest version of FindJObj? – one of the latest versions increased the size/position tolerance used when trying to locate a handle onscreen and this may solve the problem of FindJObj not finding this handle.

      If none of these appear to be the cause, then please email me a reproducible code snippet and I’ll try to fix the problem.

  3. Sylvain April 18, 2011 at 22:26 Reply

    Hi everyone,

    I have used the FindObj fonction (great job M. Altman) and the carret does go to the end of the editbox, but the problem is that the view don’t follow the carret…
    I would like to know if you have any idea, maybe a simple setting that I don’t know , to get the scrollbar at the bottom of the text (I am quite a beginner with the whole matlab graphic interface).

    Regards,

    Sylvain

    • Yair Altman April 19, 2011 at 12:20 Reply

      This should happen automatically. Perhaps you simply need to add a call to jEdit.repaint();

      In any case, here’s how to programmatically move the vertical scrollbar to the bottom:

      jVScroll = jhEdit.getVerticalScrollBar;
      jVScroll.setValue(jVScroll.getMaximum);
      jhEdit.repaint;

      jVScroll = jhEdit.getVerticalScrollBar; jVScroll.setValue(jVScroll.getMaximum); jhEdit.repaint;

      More information about the scroll-bars: http://undocumentedmatlab.com/blog/customizing-listbox-editbox-scrollbars/

  4. Johannes September 23, 2011 at 04:38 Reply

    Hello Yair,

    first of all, thank you for the superb coding, findjobj has saved me from a lot of trouble. I am using your code to set the caret position to the last line inside an edit text box (used as a log inside my GUI) whenever I update the output.
    One problem remains: To write something inside the edit text box, I am using

    % get existing text
    exTex=get(handles.outputWindow,'String');
    % new Text to be appended
    addTest=sprintf('Some new text');
    % write new text 
    newText=sprintf('%s r %s ', exText, addText);
    % update output handle
    set(handles.outputWindow,'String',newText);

    % get existing text exTex=get(handles.outputWindow,'String'); % new Text to be appended addTest=sprintf('Some new text'); % write new text newText=sprintf('%s r %s ', exText, addText); % update output handle set(handles.outputWindow,'String',newText);

    The problem now is: the set command in the last line resets the scroll bar to the top. So if some lines stream into the output window, it jumps to the top and quickly back to the bottom (due to the set.caretPosition). Is there any other way I could write lines into my output window, without resetting the scroll bar to the top?

    Thanks and lots of regards from Germany!

    • Johannes September 27, 2011 at 07:12 Reply

      Never mind, I found a different solution using listboxes. It works now as I want it to be.

      All the best,
      Johannes

    • Nick April 18, 2012 at 06:37 Reply

      Johannes,

      Similar to you, I’m adding a console/log window to a GUI and would like the scroll bar at the bottom. With a list box, were you able to get rid of the ‘jump’ problem altogether?

      I think there might be a solution using an edit box by diving deeper into the underlying Java. However, I have only recently started using the findjobj utility, so I could be wrong about that.

      Nick

  5. Sainath M January 30, 2012 at 21:13 Reply

    Hello Yair,

    I am facing one problem when I write Java methods in Matlab.
    Ex:
    >> % Create the multi-line edit-box
    >> str = {‘multi’,’line’,’editbox’};
    >> hEdit = uicontrol(‘style’,’edit’,’max’,3,’string’,str);

    This is the script I am writing in Matlab command window. After that
    when I type the code

    >> jhEdit = findjobj(hEdit)

    Matlab is showing error

    ??? Undefined function or method ‘findjobj’ for input arguments of type
    ‘double’.

    It is the first time I am using Jmethods in Matlab, will you please guide me what is the problem…

    Thank you for your time,

    Regards,
    Sainath M.

    • Yair Altman January 31, 2012 at 01:54 Reply

      @Sainath – read the third paragraph: “The first step in accessing the underlying Java control is to download my FindJObj submission on the File Exchange”

    • Sainath M January 31, 2012 at 03:40 Reply

      I can able to work now…
      Thank you..

  6. RK MacLean November 30, 2012 at 16:02 Reply

    Using another one of Yair’s suggestions worked better for me:

    jhEdit = findjobj(handles.status_text);
    jhEdit.anchorToBottom;

    jhEdit = findjobj(handles.status_text); jhEdit.anchorToBottom;

  7. Thomas August 15, 2013 at 07:56 Reply

    Hi Yair,

    I have a multi-line editbox with a scrollbar (vertical as needed) and I want it, when activted, to be always on the botton.
    I tryed this

    jVScroll = jScrollPane.getVerticalScrollBar;
    jVScroll.setValue(jVScroll.getMaximum);
    jScrollPane.repaint;

    jVScroll = jScrollPane.getVerticalScrollBar; jVScroll.setValue(jVScroll.getMaximum); jScrollPane.repaint;

    and this

    jhEdit = findjobj(handles.my_editbox);
    jhEdit.anchorToBottom;

    jhEdit = findjobj(handles.my_editbox); jhEdit.anchorToBottom;

    but didn’t work… Can you tell me what am I doing wrong?
    Thanks

    • Yair Altman August 16, 2013 at 02:32 Reply

      @Thomas, perhaps this is done when the control is still not visible, perhaps you’re modifying the control in Matlab later on (this resets the underlying component), perhaps something else. You’ll need to debug it step-by-step to see where the problem is.

  8. Tiago Silva January 31, 2014 at 04:05 Reply

    Hello Yair,

    I’m trying to use something similar to this in order to remember the position of a uitable scrollbar after a data update. My problem is that although I got it work, it only really works in debug mode. The gui I’m developing is fairly complicated, but even a simple example code like the following only works as I’d expect it to do in debug mode:

    h = uitable;
    set(h,'Data',rand(20));
    pause(1);
    jh = findjobj(h);
    jhScroll = jh.getVerticalScrollBar;
    position = 100;
    set(h,'Data',rand(20));
    jhScroll.setValue(position);

    h = uitable; set(h,'Data',rand(20)); pause(1); jh = findjobj(h); jhScroll = jh.getVerticalScrollBar; position = 100; set(h,'Data',rand(20)); jhScroll.setValue(position);

    When running this with breakpoints and stepping each line at a time I end up with the uitable updated and the scrollbar at the bottom, as I expected it to behave. Executing the code normally, I can see the uitable is updated but I end up with the scrollbar at the top.

    Any idea of what I might be doing wrong? Thanks in advance.

    • Yair Altman January 31, 2014 at 04:28 Reply

      @Tiago – I believe that this is another case of EDT mixup.

      • Tiago February 3, 2014 at 03:01

        Thanks Yair, the EDT mixup page was helpful. Managed to get my GUI working as I wanted it to.

  9. Ana GG October 13, 2015 at 07:45 Reply

    Hello,
    This seems to work fine for editbox, but how can this be extended to a cell of uitable?
    My specific problem is: I have a hint text on a specific editable (text) cell of a table. When I click this cell I want the text to disappear but still I want the cursor to be in the cell to introduce the new value. I have done the first part, but to be able to write on this cell I need to click again, and it would be good if I didn’t have to do it.
    Thank you very much in advance,
    Ana

  10. Scott June 7, 2017 at 03:16 Reply

    I’m now using R2017a, and code that used to work with anchorToBottom is no longer working… any ideas?

    >> str = {'multi','line','editbox'};
    >> hEdit = uicontrol('style','edit','max',3,'string',str);
    >> jhEdit = findjobj(hEdit)
    jhEdit =
        1×0 empty handle

    >> str = {'multi','line','editbox'}; >> hEdit = uicontrol('style','edit','max',3,'string',str); >> jhEdit = findjobj(hEdit) jhEdit = 1×0 empty handle

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

Click here to cancel reply.

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

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

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