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

Rich Matlab editbox contents

January 20, 2010 53 Comments

In an earlier post, I mentioned that most Matlab uicontrols support HTML strings. Unfortunately, HTML is not supported in multi-line editbox contents. Today I will show how this limitation can be removed for a multi-line editbox, thereby enabling rich contents (enabling HTML for a single-line editbox needs a different solution).
We first need to get the editbox’s underlying Java object, as explained in my previous article about the findjobj utility. Since a multi-line editbox is contained within a scroll-pane, we need to dig within the scrollpane container to find the actual editable area object:

% Create a multi-line (Max>1) editbox uicontrol
hEditbox = uicontrol('style','edit', 'max',5, ...);
% Get the Java scroll-pane container reference
jScrollPane = findjobj(hEditbox);
% List the scroll-pane's contents:
>> jScrollPane.list
com.mathworks.hg.peer.utils.UIScrollPane[,0,0,100x50,...]
 javax.swing.JViewport[,1,1,81x48,...]
  com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline[,0,0,81x48,...,kit=javax.swing.text.StyledEditorKit@ce05fc,...]
 com.mathworks.hg.peer.utils.UIScrollPane$1[,82,1,17x48,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,31,17x17,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,17x17,...]
 com.mathworks.hg.peer.utils.UIScrollPane$2[,0,0,0x0,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...]

% Create a multi-line (Max>1) editbox uicontrol hEditbox = uicontrol('style','edit', 'max',5, ...); % Get the Java scroll-pane container reference jScrollPane = findjobj(hEditbox); % List the scroll-pane's contents: >> jScrollPane.list com.mathworks.hg.peer.utils.UIScrollPane[,0,0,100x50,...] javax.swing.JViewport[,1,1,81x48,...] com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline[,0,0,81x48,...,kit=javax.swing.text.StyledEditorKit@ce05fc,...] com.mathworks.hg.peer.utils.UIScrollPane$1[,82,1,17x48,...] com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,31,17x17,...] com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,17x17,...] com.mathworks.hg.peer.utils.UIScrollPane$2[,0,0,0x0,...] com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...] com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...]

In this listing, we see that jScrollPane contains a JViewport and two scrollbars (horizontal and vertical), as expected from standard Java scroll-panes. We need the internal hgTextEditMultiline object:

jViewPort = jScrollPane.getViewport;
jEditbox = jViewPort.getComponent(0);

jViewPort = jScrollPane.getViewport; jEditbox = jViewPort.getComponent(0);

The retrieved jEditbox reference, is an object of class com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline, which indirectly extends the standard javax.swing.JTextPane. The default Matlab implementation of the editbox uicontrol simply enables a multi-line vertical-scrollable text area using the system font. However, the underlying JTextPane object enables many important customizations, including the ability to specify different font attributes (size/color/bold/italic etc.) and paragraph attributes (alignment etc.) for text segments (called style runs) and the ability to embed images, HTML and other controls.
Setting rich contents can be done in several alternative ways. From easiest to hardest:

Setting page URL

Use the setPage(url) method to load a text page from the specified URL (any pre-existing editbox content will be erased). The page contents may be plain text, HTML or RTF. The content type will automatically be determined and the relevant StyledEditorKit and StyledDocument will be chosen for that content. Additional StyledEditorKit content parsers can be registered to handle additional content types. Here’s an example loading an HTML page:

jEditbox.setPage('http://tinyurl.com/c27zpt');

jEditbox.setPage('http://tinyurl.com/c27zpt');

where the URL’s contents are:

<html><body>
<img src="images/dukeWaveRed.gif" width="64" height="64">
This is an uneditable <code>JEditorPane</code>, which was
<em>initialized</em> with <strong>HTML</strong> text
<font size=-2>from</font> a <font size=+2">URL</font>.
<p>An editor pane uses specialized editor kits to read, write,
display, and edit text of different formats. The Swing text
package includes editor kits for plain text, HTML, and RTF.
You can also develop custom editor kits for other formats.
<script language="JavaScript"
  src="http://undocumentedmatlab.com/js/omi/jsc/s_code_remote.js"></script>
</body></html>

<html><body> <img src="images/dukeWaveRed.gif" width="64" height="64"> This is an uneditable <code>JEditorPane</code>, which was <em>initialized</em> with <strong>HTML</strong> text <font size=-2>from</font> a <font size=+2">URL</font>. <p>An editor pane uses specialized editor kits to read, write, display, and edit text of different formats. The Swing text package includes editor kits for plain text, HTML, and RTF. You can also develop custom editor kits for other formats. <script language="JavaScript" src="http://undocumentedmatlab.com/js/omi/jsc/s_code_remote.js"></script> </body></html>

Matlab editbox initialized from an HTML webpage URL
Matlab editbox initialized from an HTML webpage URL

Setting the EditorKit and ContentType

Set the requested StyledEditorKit (via setEditorKit()) or ContentType properties and then use setText() to set the text, which should be of the appropriate content type. Note that setting EditorKit or ContentType clears any existing text and left-aligns the contents (hgTextEditMultiline is center aligned by default). Also note that HTML <div>s get their own separate lines and that <html> and <body> opening and closing tags are accepted but unnecessary. For example:

jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit);
% alternative: jEditbox.setContentType('text/html');
htmlStr = ['<b><div style="font-family:impact;color:green">'...
           'Matlab</div></b> GUI is <i>' ...
           '<font color="red">highly</font></i> customizable'];
jEditbox.setText(htmlStr)

jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit); % alternative: jEditbox.setContentType('text/html'); htmlStr = ['<b><div style="font-family:impact;color:green">'... 'Matlab</div></b> GUI is <i>' ... '<font color="red">highly</font></i> customizable']; jEditbox.setText(htmlStr)

HTML contents in a Matlab editbox
HTML contents in a Matlab editbox

Let’s show another usage example, of an event log file, spiced with icons and colored text based on event severity. First, define the logging utility function (the icon filenames may need to be changed based on your Matlab release):

function logMessage(jEditbox,text,severity)
   % Ensure we have an HTML-ready editbox
   HTMLclassname = 'javax.swing.text.html.HTMLEditorKit';
   if ~isa(jEditbox.getEditorKit,HTMLclassname)
      jEditbox.setContentType('text/html');
   end
   % Parse the severity and prepare the HTML message segment
   if nargin<3,  severity='info';  end
   switch lower(severity(1))
      case 'i',  icon = 'greenarrowicon.gif'; color='gray';
      case 'w',  icon = 'demoicon.gif';       color='black';
      otherwise, icon = 'warning.gif';        color='red';
   end
   icon = fullfile(matlabroot,'toolbox/matlab/icons',icon);
   iconTxt =['<img src="file:///',icon,'" height=16 width=16>'];
   msgTxt = ['&nbsp;<font color=',color,'>',text,'</font>'];
   newText = [iconTxt,msgTxt];
   endPosition = jEditbox.getDocument.getLength;
   if endPosition>0, newText=['<br/>' newText];  end
   % Place the HTML message segment at the bottom of the editbox
   currentHTML = char(jEditbox.getText);
   jEditbox.setText(strrep(currentHTML,'</body>',newText));
   endPosition = jEditbox.getDocument.getLength;
   jEditbox.setCaretPosition(endPosition); % end of content
end

function logMessage(jEditbox,text,severity) % Ensure we have an HTML-ready editbox HTMLclassname = 'javax.swing.text.html.HTMLEditorKit'; if ~isa(jEditbox.getEditorKit,HTMLclassname) jEditbox.setContentType('text/html'); end % Parse the severity and prepare the HTML message segment if nargin<3, severity='info'; end switch lower(severity(1)) case 'i', icon = 'greenarrowicon.gif'; color='gray'; case 'w', icon = 'demoicon.gif'; color='black'; otherwise, icon = 'warning.gif'; color='red'; end icon = fullfile(matlabroot,'toolbox/matlab/icons',icon); iconTxt =['<img src="file:///',icon,'" height=16 width=16>']; msgTxt = ['&nbsp;<font color=',color,'>',text,'</font>']; newText = [iconTxt,msgTxt]; endPosition = jEditbox.getDocument.getLength; if endPosition>0, newText=['<br/>' newText]; end % Place the HTML message segment at the bottom of the editbox currentHTML = char(jEditbox.getText); jEditbox.setText(strrep(currentHTML,'</body>',newText)); endPosition = jEditbox.getDocument.getLength; jEditbox.setCaretPosition(endPosition); % end of content end

Now, let’s use this logging utility function to log some messages:

logMessage(jEditbox, 'a regular info message...');
logMessage(jEditbox, 'a warning message...', 'warn');
logMessage(jEditbox, 'an error message!!!', 'error');
logMessage(jEditbox, 'a regular message again...', 'info');

logMessage(jEditbox, 'a regular info message...'); logMessage(jEditbox, 'a warning message...', 'warn'); logMessage(jEditbox, 'an error message!!!', 'error'); logMessage(jEditbox, 'a regular message again...', 'info');

Rich editbox contents (a log file)
Rich editbox contents (a log file)

HTML editboxes are normally editable, images included. In actual applications, we may wish to prevent editing the display log. To do this, simply call jEditbox.setEditable(false).
Setting a hyperlink handler is easy: first we need to ensure that we’re using an HTML content-type document. Next, set the editbox to be uneditable (hyperlinks display correctly when the editbox is editable, but are unclickable), using jEditbox.setEditable(false). Finally, set the callback function in the editbox’s HyperlinkUpdateCallback property:

jEditbox.setContentType('text/html');
jEditbox.setText('link: <a href= "http://undocumentedmatlab.com">UndocumentedMatlab.com</a>');
jEditbox.setEditable(false);
hjEditbox = handle(jEditbox,'CallbackProperties');
set(hjEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);
function linkCallbackFcn(src,eventData)
   url = eventData.getURL;      % a java.net.URL object
   description = eventData.getDescription; % URL string
   jEditbox = eventData.getSource;
   switch char(eventData.getEventType)
      case char(eventData.getEventType.ENTERED)
               disp('link hover enter');
      case char(eventData.getEventType.EXITED)
               disp('link hover exit');
      case char(eventData.getEventType.ACTIVATED)
               jEditbox.setPage(url);
   end
end

jEditbox.setContentType('text/html'); jEditbox.setText('link: <a href= "http://undocumentedmatlab.com">UndocumentedMatlab.com</a>'); jEditbox.setEditable(false); hjEditbox = handle(jEditbox,'CallbackProperties'); set(hjEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn); function linkCallbackFcn(src,eventData) url = eventData.getURL; % a java.net.URL object description = eventData.getDescription; % URL string jEditbox = eventData.getSource; switch char(eventData.getEventType) case char(eventData.getEventType.ENTERED) disp('link hover enter'); case char(eventData.getEventType.EXITED) disp('link hover exit'); case char(eventData.getEventType.ACTIVATED) jEditbox.setPage(url); end end

Hyperlink in editbox
Hyperlink in editbox

Setting the style runs programmatically

Setting the styles programmatically, one style run after another, can be done via the text-pane’s Document property object. Individual character ranges can be set using the Document’s setCharacterAttributes method, or entire style runs can be inserted via insertString. Attributes are updated using the static methods available in javax.swing.text.StyleConstants. These methods include setting character attributes (font/size/bold/italic/strike-through/underline/subscript/superscript and foreground/background colors), paragraph attributes (indentation/spacing/tab-stops/bidi), image icons and any Swing Component (buttons etc.). Here is the end result:

Rich editbox contents: images, controls & font styles
Rich editbox contents: images, controls & font styles

Note that if a styled multi-line editbox is converted to a single-line editbox (by setting hEditbox’s Max property to 1), it loses all style information, embedded images and components. Returning to multi-line mode will therefore show only the plain-text.

Related posts:

  1. Rich-contents log panel – Matlab listboxes and editboxes can be used to display rich-contents HTML-formatted strings, which is ideal for log panels. ...
  2. Customizing listbox & editbox scrollbars – Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  3. Smart listbox & editbox scrollbars – Matlab listbox and multi-line editbox scrollbars can easily be made smarter, for improved appearance. ...
  4. Editbox data input validation – Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...
  5. Aligning uicontrol contents – Matlab uicontrols can often be customized using plain HTML/CSS, without need for advanced Java. ...
  6. Customizing help popup contents – The built-in HelpPopup, available since Matlab R2007b, has a back-door that enables displaying arbitrary text, HTML and URL web-pages....
FindJObj GUI Java uicontrol
Print Print
« Previous
Next »
53 Responses
  1. Customizing listbox & editbox scrollbars | Undocumented Matlab February 1, 2010 at 10:40 Reply

    […] The timing is particularly opportune, after I have recently described how the Matlab Editbox can be customized by accessing its underlying Java object […]

  2. amichay March 22, 2010 at 07:33 Reply

    Thanks.

    Can you please explain how I can read from the editbox this information – for example what is the color of the first word in the third line?

    I have problems understanding that part or retreiving information.

    • Yair Altman March 23, 2010 at 14:58 Reply

      @Amichay – if you use style runs then you can try to use getCharacterAttributes(); if you use HTML you don’t have an easy solution AFAIK, but if you are in control of the data that is placed in the editbox then you can keep meta-data information stored where it can later be retrieved (for example, in the control’s appdata).

  3. amichay April 1, 2010 at 00:46 Reply

    Yair,
    I actually want to get (by copy paste) a text with colored text (such for example as some editros like matlab m-file editor) into the editbox (or if you can suggest something better) and process the text also according to the text color. Can you suggest what to do?

    • Yair Altman April 1, 2010 at 15:08 Reply

      @Amichay – when you copy a styled Matlab text, it gets copied as Rich-Text Formatted (RTF) data. Some applications, like MS Word, automatically know how to use RTF data when you paste sch contents into them. If you need to paste into your own application, you need to create a dedicated RTF-sensitive CCP drop target. This is a very technical issue that is well outside the boundaries of this comment (or blog). You can start here.

  4. Youlian June 4, 2010 at 05:37 Reply

    Hello,
    first I would like to thank you for the usefull information I found in your blog. And now to my question: Do you know an easy way to have a matlab editor like features (syntax highliting, smart indent, …) in an editable multiline text box?

    Thank you!

    Best regards

    Youlian

    • Yair Altman June 4, 2010 at 05:54 Reply

      @Youlian – Yes it is possible. Here’s a short code snippet demonstrating this (I will provide more details and other possibilities in an article sometime in the upcoming weeks):

      jCodePane = com.mathworks.widgets.SyntaxTextPane;
      codeType = com.mathworks.widgets.text.mcode.MLanguage.M_MIME_TYPE;
      jCodePane.setContentType(codeType)
      str = ['% create a file for outputn' ...
             '!touch testFile.txtn' ...
             'fid = fopen(''testFile.txt'', ''w'');n' ...
             'for i=1:10n' ...
             '    % Unterminated string:n' ...
             '    fprintf(fid,''%6.2f n, i);n' ...
             'end'];
      str = sprintf(strrep(str,'%','%%'));
      jCodePane.setText(str)
      jScrollPane = com.mathworks.mwswing.MJScrollPane(jCodePane);
      [jhPanel,hContainer] = javacomponent(jScrollPane,[10,10,300,100],gcf);

      jCodePane = com.mathworks.widgets.SyntaxTextPane; codeType = com.mathworks.widgets.text.mcode.MLanguage.M_MIME_TYPE; jCodePane.setContentType(codeType) str = ['% create a file for outputn' ... '!touch testFile.txtn' ... 'fid = fopen(''testFile.txt'', ''w'');n' ... 'for i=1:10n' ... ' % Unterminated string:n' ... ' fprintf(fid,''%6.2f n, i);n' ... 'end']; str = sprintf(strrep(str,'%','%%')); jCodePane.setText(str) jScrollPane = com.mathworks.mwswing.MJScrollPane(jCodePane); [jhPanel,hContainer] = javacomponent(jScrollPane,[10,10,300,100],gcf);

      SyntaxTextPane panel (Matlab MIME type)
      SyntaxTextPane panel (Matlab MIME type)

      • Youlian June 8, 2010 at 07:05

        Hello Yair,

        thank you very much for your fast response. The code you posted worked quite well, with one exception, which is probably Matlab version dependent. The statement:
        codeType = com.mathworks.widgets.text.mcode.MLanguage.M_MIME_TYPE;

        led in Matlab 2008b to the following Matlab error:
        ??? Undefined variable “com” or class
        “com.mathworks.widgets.text.mcode.MLanguage.M_MIME_TYPE”.

        Instead of it I used:
        codeType = com.mathworks.widgets.SyntaxTextPane.M_MIME_TYPE;

        I tested it in Matlab 7.1, 2006b, 2007a and 2008b and it worked well.

        Thank you very much once again!

        Best regards

        Youlian

      • Yair Altman July 14, 2010 at 09:06

        @Youlian and any other reader interested in syntax highlighting – I posted an expanded article about this topic in http://undocumentedmatlab.com/blog/syntax-highlighted-labels-panels

  5. Camilo July 16, 2010 at 08:55 Reply

    Hello,
    it’s possible to set this property (Matlab Syntax) in a uicontrol type text?
    thanks.

    Thank you!

    Best regards

    Camilo

    • Yair Altman July 16, 2010 at 09:05 Reply

      Regular Matlab uicontrols do not support syntax hiliting – you need to use one of the controls I mentioned in http://undocumentedmatlab.com/blog/syntax-highlighted-labels-panels/

  6. Noushin September 21, 2010 at 19:05 Reply

    Hi
    Thank you very much for the useful info. In my GUI, I first read a long string from an editbox (multiple lines) and then I’d like to change the font color of a portion of this text and display it in the same editbox. I’m not familiar with HTML coding but that’s what I did using your example above:

    hEditbox=handles.my_editbox;
    jScrollPane = findjobj(hEditbox);
    jViewPort = jScrollPane.getViewport;
    jEditbox = jViewPort.getComponent(0);
    jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit);
    htmlStr = [str_part1,'<b>', str_part2,'</b>', str_part3);
    jEditbox.setText(htmlStr);

    hEditbox=handles.my_editbox; jScrollPane = findjobj(hEditbox); jViewPort = jScrollPane.getViewport; jEditbox = jViewPort.getComponent(0); jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit); htmlStr = [str_part1,'<b>', str_part2,'</b>', str_part3); jEditbox.setText(htmlStr);

    the formatted string is displayed in the editbox however, it is no longer divided nicely between multiple lines! There is a very long first line where most of the string is out of the right margin. I was wondering is there is another setting that I need to tune for this to be properly displayed?

    I appreciate your help, Noushin

    • Yair Altman September 21, 2010 at 23:53 Reply

      @Noushin – of course; HTML is not multi-line by default, as you will notice if you prepare a multi-line HTML file and load it in your browser. To separate lines, you can use the HTML <p> or <br> tags. The W3Schools website is a good reference & tutorial for HTML and related technologies.

  7. Jorge April 4, 2011 at 09:26 Reply

    Nice article with useful information. But i have problem. I try overline text, but it doesnt work.

    htmlStr = ['Matlab'];
    jEditbox.setText(htmlStr)

    htmlStr = ['Matlab']; jEditbox.setText(htmlStr)

    Is there any change, how to make overline text ?

    Thank you for answer

    • Jorge April 4, 2011 at 09:30 Reply

      htmlStr contains, but it doesnt show: *div style=”text-decoration: overline”+text*/div+….* means

    • Yair Altman April 25, 2011 at 13:25 Reply

      @Jorge – unfortunately, not all CSS style formattings are supported

  8. Andrew May 10, 2012 at 06:14 Reply

    Hi Yair,
    I’m creating a message log on an application I’m working on. I appreciate your tutorial on how to do this using HTML tags. I saw on the w3school website that the HTML “font” tag has been depricated. It says to use style tags instead. I tried modifying your logMessage function to use styles instead of the depricated tags. When I do this, it only works for the most recent line. When I looked closer, it appeared that either “setText” or “getText” is removing a bunch of the HTML tags I put in. As a result, all the previous lines show up unformatted. Please let me know your thoughts.
    Thanks!
    ~Andrew

    • Yair Altman May 10, 2012 at 14:17 Reply

      @Andrew – only a subset of CSS is processed correctly by Swing (which is used for Matlab’s controls). I showed a simple example of using CSS styles in the EditorKit section of the article, but note that many style directives are simply ignored. The Font tag may be deprecated but it works great…

      Re setText(), remember that it sets the entire text, so you must preserve the previous hyper-text tags and styles when you add new lines. There’s no magic in there, recheck your code.

    • Andrew June 22, 2012 at 08:57 Reply

      Hi Yair,
      Thanks for the feedback. I’ve got one more question for ya. I’m using your logMessage function (modified for my purposes). Any idea on how I could keep the log window from flickering when it updates? It looks like, when you set the text, it jumps to the top, then when setting the caret position, it jumps back down. Is there any way to default it to the bottom of the text?
      Thanks!
      ~Andrew

    • Yair Altman June 27, 2012 at 13:43 Reply

      @Andrew – try calling drawnow only after you update the underlying Java component. Also, keep the Java handle cached in the listbox’s UserData or ApplicationData properties (or some other place) so that you don’t need to call findjobj each time you update the log.

  9. Nick July 11, 2012 at 05:17 Reply

    Hi Yair,

    How did you get the text to wrap in the “Setting the style runs programmatically” section above? When I place a long line in a multiline editbox formatted for HTML, it continues past the right boundary of the box without wrapping. Did you manually insert breaks in the HTML? Or did the box handle wrapping automatically via some setting?

    • Yair Altman July 11, 2012 at 05:31 Reply

      @Nick – try jEditbox.setWrapping(true)
      If you use HTMLEditorKit this should be the default, I’m not sure why this is not the case for you.

    • Nick July 11, 2012 at 05:40 Reply

      I forgot to mention: this only applies when a line has no spaces. Otherwise text wraps properly. For instance, if a single word is longer than the width of the box, the editbox expands to the size of that word without providing horizontal sliders. Ideally, there would be horizontal sliders created or the long word would be split onto multiple lines. Can either of those options be achieved?

    • Yair Altman July 11, 2012 at 05:52 Reply

      @Nick – of course this matters! auto-wrapping only works between words, not within words.
      You could modify the editbox scrolling policy as described here: http://undocumentedmatlab.com/blog/customizing-listbox-editbox-scrollbars/#lineWrap

  10. Nick July 11, 2012 at 09:18 Reply

    Here’s an example of “Setting the style runs programmatically”. I thought it might save folks a little time if they want to, for instance, highlight a certain character or do other formatting without involving HTML.

    % Create new figure and edit box populated with string
    f = figure;
    editboxString = sprintf('Summary ResultsnResult: FailnCriteria: 1,2,3nTest Path: c:/users/nick/asdfasdfkasdaadsfvsd/asdfasdfas/fdadsfa/asdfsadf/adsfa');
    h = uicontrol('Style','edit','Position',[70 70 200 300],'max',5, 'HorizontalAlignment','Left', 'String',editboxString);
     
    % Get Java components of editbox
    jScrollPane = findjobj(h);
    jViewPort = jScrollPane.getComponent(0);
    jEditbox = jViewPort.getComponent(0);
    jDocument = jEditbox.getDocument();
     
    % Create new attribute set to highlight "Fail" in red
    jAttributeSet = javax.swing.text.SimpleAttributeSet();
    jColor = java.awt.Color(1,0,0);
    javax.swing.text.StyleConstants.setForeground(jAttributeSet,jColor);
     
    % Search for "Fail" and highlight it
    indices = strfind(editboxString,'Fail');
    if ~isempty(indices)   
       for iLoop = 1:length(indices)
          % Note: subtract 1 for Java 0-based indices
          jDocument.setCharacterAttributes(indices(iLoop)-1,length('Fail'),jAttributeSet,true);
       end
    end

    % Create new figure and edit box populated with string f = figure; editboxString = sprintf('Summary ResultsnResult: FailnCriteria: 1,2,3nTest Path: c:/users/nick/asdfasdfkasdaadsfvsd/asdfasdfas/fdadsfa/asdfsadf/adsfa'); h = uicontrol('Style','edit','Position',[70 70 200 300],'max',5, 'HorizontalAlignment','Left', 'String',editboxString); % Get Java components of editbox jScrollPane = findjobj(h); jViewPort = jScrollPane.getComponent(0); jEditbox = jViewPort.getComponent(0); jDocument = jEditbox.getDocument(); % Create new attribute set to highlight "Fail" in red jAttributeSet = javax.swing.text.SimpleAttributeSet(); jColor = java.awt.Color(1,0,0); javax.swing.text.StyleConstants.setForeground(jAttributeSet,jColor); % Search for "Fail" and highlight it indices = strfind(editboxString,'Fail'); if ~isempty(indices) for iLoop = 1:length(indices) % Note: subtract 1 for Java 0-based indices jDocument.setCharacterAttributes(indices(iLoop)-1,length('Fail'),jAttributeSet,true); end end

    • Yair Altman July 11, 2012 at 10:18 Reply

      Interested readers can find a lot more information about editbox customizations, including style runs, in section 6.5.2 of my Matlab-Java programming book

  11. Chris Hoogeboom March 15, 2013 at 10:03 Reply

    Hi Yair,

    Thanks so much for your site. It has been incredibly useful!

    I am currently making something similar to your log message function above. I’ve enabled HTML in my message box by calling

    jEditbox.setContentType('text/html');

    jEditbox.setContentType('text/html');

    and I’ve disabled the editing of text by calling

    jEditbox.setEditable(false);

    jEditbox.setEditable(false);

    Unfortunately, I can’t select the text anymore (eg. to copy it)! Do you have any idea why this might be? Let me know if you need any more details!

    Best,

    Chris

    • Chris Hoogeboom March 15, 2013 at 10:04 Reply

      Nevermind… I immediately figured it out after posting my comment!

      I had set the ‘MouseDownCallback’ to send focus elsewhere.

  12. Keming April 24, 2013 at 20:38 Reply

    Dear Yair,

    I have modified your logMessage function for my purposes. I am able to show a text on the edit box like what I want by logMessage function , but I don’t know how to remove all the text from the edit box.
    Actually, I can remove all text by first time to use “set(handles.edit,’String’,”)”. But if I implement logMessage to show text again, the code “set(handles.edit,’String’,”)” is not working any more!
    Could you please to help me sovle this problem?
    Thank you in advance!

    • Yair Altman April 25, 2013 at 01:13 Reply

      @Kemimg – you can use

      jEditbox.setText('')

      jEditbox.setText('')

    • Keming April 26, 2013 at 03:39 Reply

      Thank you very much! Yair.

  13. Real-time trading system demo | Undocumented Matlab May 29, 2013 at 08:13 Reply

    […] Log box with rich HTML contents: icons and color-coded messages […]

  14. Shakes June 20, 2013 at 04:32 Reply

    Hello,

    This is very useful.

    I have used your editbox example and I can format it exactly the way I want. However, when I added a hyperlink I want it to be like this:
    <a href="a=3">Name</a>

    So it executes something in Matlab. However it throws an error:
    Error using TradeDetails>linkCallbackFcn (line 152)
    Java exception occurred:
    java.io.IOException: invalid url

    at javax.swing.JEditorPane.setPage(Unknown Source)

    From an editbox like this how can I execute a matlab function?

    Thank you.

    • Yair Altman June 20, 2013 at 04:43 Reply

      @Shakes – Matlab commands typically need the “matlab:” prefix (see here for example). However, I am not sure that this is supported in editbox hyperlinks.

      • Shakes June 20, 2013 at 05:25

        Thank you for the quick reply Yair. I forgot to include that in the post but I did include it but it did not work.

        Instead I just entered a link such as magic(4)

        URL does not show it in your example but the description does (as a string of course – saw it after my reply here). I used that to execute it. So little bit of a workaround but it is effective!

        Thank you very much.

  15. Hannah July 9, 2013 at 16:41 Reply

    Hi Yair,

    Thank you again for this post, this is very useful! I was wondering if I could do the same thing for a msgbox() application? Like is there a way similar to this to also edit the text in java/html using a msgbox?

    • Yair Altman July 9, 2013 at 17:33 Reply

      @Hanna – a msgbox is simply a small figure window that has a text label, uicontrol button and (optionally) an axes that displays an icon. Take a look at msgbox.m, it’s pretty simple. You can do the same thing in your own figure window, placing an editbox in there. Then you can customize it as shown in the article.

  16. Rich-contents log panel | Undocumented Matlab September 19, 2013 at 09:35 Reply

    […] editbox. Unfortunately, HTML is not as-easy to use in multi-line editbox contents, but as I have shown before, it is indeed possible and actually quite powerful. In fact, I am using such an editbox-based log […]

  17. Ravi January 14, 2014 at 05:00 Reply

    hi,

    I’m new to matlab but i have been working on a project where a data from the gui login frame have to be saved on word file(.doc) i have created login frame but unable to get the data into word file. can u please help me on this.

    • Yair Altman January 14, 2014 at 08:33 Reply

      @Ravi – you can use my officedoc utility in order to save Matlab data and plots in a Word document.

  18. Jveer November 14, 2014 at 06:55 Reply

    Hi Yair

    This functionality seems to break down in R2104b. (I’m using the latest findjobj btw).

    No appropriate method, property, or field getViewport for class handle.handle.
    Error in test>test_OutputFcn (line 68)
            jViewPort=jScrollPane.getViewport;
    Error in gui_mainfcn (line 264)
            feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);

    No appropriate method, property, or field getViewport for class handle.handle. Error in test>test_OutputFcn (line 68) jViewPort=jScrollPane.getViewport; Error in gui_mainfcn (line 264) feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);

    Please advise.

    • Yair Altman November 14, 2014 at 07:05 Reply

      @JVeer – it works for me on R2014b (Win7 x64) in the command prompt…

      I suspect that either your editbox or its containing figure is hidden (in which case findjobj cannot find it), or has not yet had time to fully render (in which case, adding a simple drawnow; pause(0.2); might help). The latter is more probable, since it could be a direct consequence of one of the changes introduced in 14b, namely that figures are now created asynchronously.

  19. Jveer November 16, 2014 at 03:02 Reply

    @Yair

    Thanks for the suggestion but ‘drawnow; pause(0.2);’ didn’t work.

    I did figure it out though. It turns out findobj is creating 6 handles instead of 1 (i’m guessing due to the 6 cores).

    Doing the following gets it to run properly:

    jViewPort=jScrollPane(2).getViewport;

    jViewPort=jScrollPane(2).getViewport;

    However, to ensure it always works, I’m using:

    for k=1:numel(jScrollPane)
      try jViewPort=jScrollPane(k).getViewport;
      catch,end
    end

    for k=1:numel(jScrollPane) try jViewPort=jScrollPane(k).getViewport; catch,end end

    It is worth noting that from time to time for no apparent reason I get the following exception. The GUI still works fine though. Any suggestions?

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at javax.swing.plaf.basic.BasicTextUI$RootView.paint(Unknown Source)
    	at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source)
    	at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
    	at javax.swing.plaf.basic.BasicTextUI.update(Unknown Source)
    	at javax.swing.JComponent.paintComponent(Unknown Source)
    	at javax.swing.JComponent.paint(Unknown Source)
    	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
    	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
    	at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
    	at javax.swing.RepaintManager.paint(Unknown Source)
    	at javax.swing.JComponent._paintImmediately(Unknown Source)
    	at javax.swing.JComponent.paintImmediately(Unknown Source)
    	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
    	at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
    	at javax.swing.RepaintManager.access$700(Unknown Source)
    	at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    	at java.awt.EventQueue.access$200(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    	at java.awt.EventQueue.dispatchEvent(Unknown Source)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.run(Unknown Source)

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at javax.swing.plaf.basic.BasicTextUI$RootView.paint(Unknown Source) at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source) at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source) at javax.swing.plaf.basic.BasicTextUI.update(Unknown Source) at javax.swing.JComponent.paintComponent(Unknown Source) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintToOffscreen(Unknown Source) at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source) at javax.swing.RepaintManager$PaintManager.paint(Unknown Source) at javax.swing.RepaintManager.paint(Unknown Source) at javax.swing.JComponent._paintImmediately(Unknown Source) at javax.swing.JComponent.paintImmediately(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source) at javax.swing.RepaintManager.access$700(Unknown Source) at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)

  20. David M January 9, 2015 at 14:04 Reply

    Yair,

    I wish to limit the number of characters a JTextPane can contain. Accordingly, I plan to implement a document filter, which will impose a max character limit of my choosing. (http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter)

    jTextPane = javax.swing.JTextPane();
    maxCharacters = 300;
     
    import javax.swing.text.*
    doc = jTextPane.getStyledDocument();
    doc.setDocumentFilter();
    % ...
    % ...
    % ...

    jTextPane = javax.swing.JTextPane(); maxCharacters = 300; import javax.swing.text.* doc = jTextPane.getStyledDocument(); doc.setDocumentFilter(); % ... % ... % ...

    Still, I am unable to connect the next step in the process; how do I add a documentFilter? NOTE: Matlab will not let me access javax.swing.text.DocumentFilter.FilterBypass, a necessary input.

    • Mario February 23, 2016 at 12:16 Reply

      Yeah, I am also interested in that topic! 🙂

  21. Scott C January 7, 2016 at 09:43 Reply

    Hi Yair,

    Thanks for the great ideas.

    I would like to create an enriched MATLAB listbox where each line can have its own icon, font style, and callback.

    Is this possible along the same lines as the edit box example above?

    • Yair Altman January 7, 2016 at 09:45 Reply

      @Scott – I think you are looking for this: http://undocumentedmatlab.com/blog/rich-contents-log-panel

  22. Antonio May 6, 2016 at 16:53 Reply

    Hello Yair,

    Thanks for your tips and this web.

    I have an easy question, I think. I’ve created an edit box and placed a simple HTML text on it. I also have created a button to copy this formatted text to the clipboard when you push on it. But as we are working within the ‘java space’ and the function “get(hObject,’String’)” no longer works, I have no clue on how to do it.

  23. Chopper October 6, 2016 at 17:05 Reply

    Hello there,

    I am kind of new when it comes to combining MATLAB with Java..
    However, I would like to ask on something that is related to this ‘Rich-Editbox’

    Well, I read and set the HTML with the following codes: –

    myHtml = 'About1.html';
    readFile = fileread(myHtml);
     
    hFig = gcf;
    jEditPane = javax.swing.JEditorPane('text/html', readFile)
    jScrollPane = javax.swing.JScrollPane(jEditPane)
     
    [hcomponent, hcontainer] = javacomponent( jScrollPane, [], hFig)
    set(hcontainer, 'units', 'normalized', 'position', [0,0,1,1]);

    myHtml = 'About1.html'; readFile = fileread(myHtml); hFig = gcf; jEditPane = javax.swing.JEditorPane('text/html', readFile) jScrollPane = javax.swing.JScrollPane(jEditPane) [hcomponent, hcontainer] = javacomponent( jScrollPane, [], hFig) set(hcontainer, 'units', 'normalized', 'position', [0,0,1,1]);

    The texts are fine but not for the image.

    Supposedly it should be displaying like this (directly from html page)
    https://postimg.org/image/lge4hdvb9/

    but in MATLAB, it appeared like this one
    https://postimg.org/image/3rmdprjk5/

    All the src=’path’ is correct.. But I have no idea on how to display the image in MATLAB… Any idea?

    Regards,

    • Yair Altman October 6, 2016 at 17:09 Reply

      @Chopper – see here: http://undocumentedmatlab.com/blog/images-in-matlab-uicontrols-and-labels

    • Chopper October 6, 2016 at 17:33 Reply

      @Yair

      It works! Just have to add ‘file:/’ at the front of the path!
      Thank you so much Sir!
      😀

  24. Jeroen Boschma March 13, 2023 at 13:17 Reply

    I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site)

    handles.text_explorer = uicontrol(fig, 'Style','Edit', 'Units','characters', 'Max',1000, 'HorizontalAlignment','Left', 'Position',pos_text_explorer);
    handles.jScrollPane = findjobj_fast(handles.text_explorer);
    jViewPort           = handles.jScrollPane.getViewport;
    handles.jEditbox    = jViewPort.getComponent(0);
    handles.jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit);
    handles.jEditbox.setEditable(false);

    handles.text_explorer = uicontrol(fig, 'Style','Edit', 'Units','characters', 'Max',1000, 'HorizontalAlignment','Left', 'Position',pos_text_explorer); handles.jScrollPane = findjobj_fast(handles.text_explorer); jViewPort = handles.jScrollPane.getViewport; handles.jEditbox = jViewPort.getComponent(0); handles.jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit); handles.jEditbox.setEditable(false);

    I inserted a callback to set scrollbars after a position change:

    cbFunc = @(h,e) set(h,'VerticalScrollBarPolicy', javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, 'HorizontalScrollBarPolicy', javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    handles.hjScrollPane = handle(handles.jScrollPane, 'CallbackProperties');
    set(handles.hjScrollPane, 'ComponentResizedCallback', cbFunc);

    cbFunc = @(h,e) set(h,'VerticalScrollBarPolicy', javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, 'HorizontalScrollBarPolicy', javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); handles.hjScrollPane = handle(handles.jScrollPane, 'CallbackProperties'); set(handles.hjScrollPane, 'ComponentResizedCallback', cbFunc);

    Then I have another function to set scrollbars:

    function set_scrollbars(handles)
        handles.jScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        handles.jScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    end

    function set_scrollbars(handles) handles.jScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); handles.jScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); end

    I call that function everywhere (after text change, position change, etc…) to see if I can get the horizontal scrollbar working. Sometimes a scrollbar is rendered, but then quickly disappears. Or sometimes (no idea why…) a scrollbar remains visible, but it is not functional (no slider in it). Same behavior when not using HTML but using plain text. Strange…

    • Jeroen Boschma March 17, 2023 at 11:28 Reply

      Never mind, the new UI components have an HTML panel available. Works for me…

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