Setting line position in an edit-box uicontrol

Thursday, March 26th, 2009

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. Rich Matlab editbox contents The Matlab editbox uicontrol does not handle HTML contents as do other uicontrols. In this article I show how this limitation can be removed....
  5. 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...
  6. 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....

Tags: , , ,

Categories: GUI, Java, Medium risk of breaking in future versions, UI controls

This entry was posted on Thursday, March 26th, 2009 at 3:38 am PST
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

PoorSo-soHelpfulVery helpfulExcellent! (No Ratings Yet)
Loading ... Loading ...
Bookmark and Share Print Print

5 Responses to “Setting line position in an edit-box uicontrol”

  1. Heiko Heiko says:

    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!

  2. Yair Altman Yair Altman says:

    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.

  3. Heiko Heiko says:

    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

  4. A. Bindemann A. Bindemann says:

    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

  5. Yair Altman Yair Altman says:

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

Leave a Reply


Wrap code fragments inside <pre lang="matlab"> tags, like this:

   <pre lang="matlab">
   a = magic(3);
   sum(a)
   </pre>