Syntax highlighted labels & panels

A few weeks ago, a reader of my article about rich Matlab editbox contents asked whether it is possible to display syntax-highlighted contents, i.e. contents whose color changes based on its underlying text, often called syntax hilite in affection. I gave a very specific answer in a reply comment, which I expand in today’s full-length article.

Matlab has two built-in Java classes that can present syntax-highlighted text: SyntaxTextLabel presents single-line labels, while SyntaxTextPane presents a multi-line editor pane. Both of these classes support C, HTML/XML, Java and Matlab syntax highlighting, as well as standard plaint-text. Some related JIDE classes are also described.

SyntaxTextLabel

SyntaxTextLabel is used to display a syntax-highlighted single-line text label according to the specified programming language: C_STYLE, HTML_STYLE, JAVA_STYLE, PLAIN_STYLE and of course M_STYLE for Matlab code:

str = 'for id=1:3, set(h(id),''string'',num2str(id)); end  % Matlab code';
codeType = com.mathworks.widgets.SyntaxTextLabel.M_STYLE;
jCodeLabel = com.mathworks.widgets.SyntaxTextLabel(str,codeType)
[jhLabel,hContainer] = javacomponent(jCodeLabel,[10,10,300,20],gcf);

SyntaxTextLabels (different code styles)

SyntaxTextLabels (different code styles)

StyledLabel

More flexibility in the displayed label styles can be achieved with HTML/CSS, and the bundled JIDE class com.jidesoft.swing.StyledLabel provides even more flexibility:

import java.awt.*
import com.jidesoft.swing.*
str = 'Mixed Underlined Strikethrough Super and Subscript combo Styles';
com.mathworks.mwswing.MJUtilities.initJIDE;
jStyledLabel = StyledLabel(str); 
styles = [StyleRange(0,5,  Font.BOLD,   Color.BLUE), ...
          StyleRange(6,10, Font.PLAIN,StyleRange.STYLE_UNDERLINED),...
          StyleRange(17,13,Font.PLAIN,  Color.RED,   ...
                           StyleRange.STYLE_STRIKE_THROUGH), ...
          StyleRange(31,5, Font.PLAIN,  Color.BLUE,  ...
                           StyleRange.STYLE_SUPERSCRIPT), ...
          StyleRange(37,3, Font.ITALIC, Color.BLACK), ...
          StyleRange(41,9, Font.PLAIN,  Color.BLUE,  ...
                           StyleRange.STYLE_SUBSCRIPT), ...
          StyleRange(51,5, Font.PLAIN,  StyleRange.STYLE_WAVED + ...
                           StyleRange.STYLE_STRIKE_THROUGH)];
jStyledLabel.setStyleRanges(styles);
[jhLabel,hContainer] = javacomponent(jStyledLabel,[10,10,300,20],gcf);

JIDE StyledLabel (different font styles)

JIDE StyledLabel (different font styles)

StyledLabels have subclasses that can be used to present styled text in tables, trees or lists. JIDE also provides the convenient StyledLabelBuilder, which enables easy multi-style text construction.

Finally, JIDE provides the ClickThroughStyledLabel, a StyledLabel extension that allows setting a target component, so that mouse clicks on the label will actually trigger the target component. This can be useful in forms where components have adjacent descriptive labels.

SyntaxTextPane

Multi-line syntax-highlighted code can be displayed with Matlab’s SyntaxTextPane class. SyntaxTextPane uses MIME types rather than styles for syntax-highlighting, but the end-result appears similar:

jCodePane = com.mathworks.widgets.SyntaxTextPane;
codeType = jCodePane.M_MIME_TYPE;  % ='text/m-MATLAB'
jCodePane.setContentType(codeType)
str = ['% create a file for output\n' ...
       '!touch testFile.txt\n' ...
       'fid = fopen(''testFile.txt'', ''w'');\n' ...
       'for i=1:10\n' ...
       '    % 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)

The nice thing about SyntaxTextPane is that it syntax-highlights on-the-fly as you type or edit in the SyntaxTextPane (assuming you have not disabled editing with the setEditable(flag) method). This is exactly the behavior we have come to expect in the full-blown Matlab editor, and can now be embedded as a simple panel within our GUI.

Despite its misleadingly-simple look, SyntaxTextPane actually has most capabilities of the full-blown editor, not just syntax highlighting. This includes multiple undo/redo actions; smart indentation/commenting; automatic indication of corresponding block elements (if-end, for-end, etc. – also known as delimiter matching); search/replace, drag-and-drop and cut-copy-paste support; and many more.

Interested readers can use the uiinspect and checkClass utilities to explore the full capabilities offered by SyntaxTextPane. In this respect it would be helpful to also look at its super-class (SyntaxTextPaneBase) and the related SyntaxTextPaneUtilities class.

Summary

These Java classes are examples of built-in classes that can be used in Matlab applications, enabling a much richer GUI experience than possible using the standard (documented/supported) Matlab widgets.

As I have shown above, using these classes is extremely easy, and requires absolutely no Java knowledge. On the flip side, these internal Matlab classes may easily break in any future Matlab release, so be extra careful when deciding to use them. Future articles in this website will describe other similarly-useful built-in classes.

Have you found any other useful built-in Matlab class? If so, please post a comment.

Related posts:

  1. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  2. Customizing Matlab labels Matlab's text uicontrol is not very customizable, and does not support HTML or Tex formatting. This article shows how to display HTML labels in Matlab and some undocumented customizations...
  3. Images in Matlab uicontrols & labels Images can be added to Matlab controls and labels in a variety of manners, documented and undocumented. ...
  4. Setting axes tick labels format Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...
  5. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  6. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...

Categories: GUI, High risk of breaking in future versions, Java

Tags: , , , ,

Bookmark and SharePrint Print

11 Responses to Syntax highlighted labels & panels

  1. kmilo17pet says:

    I tried with this code:

    jCodePane.setFont(java.awt.Font('Arial',java.awt.Font.PLAIN,8),1)

    to change font type,size and style, but it does not work.
    Also, how display the “line numbers”?

    • I’m not sure about the font, but here’s one way to display line numbers:

      glyph = org.netbeans.editor.GlyphGutter(jCodePane.getEditorUI);
      glyph.setSize(java.awt.Dimension(20, jCodePane.getHeight));
       
      jPanel1 = javax.swing.JPanel;
      jPanel1.getLayout.setHgap(0);
      jPanel1.getLayout.setVgap(0);
      jPanel1.add(glyph);
       
      jPanel2 = javax.swing.JPanel(jPanel1.getLayout);
      jPanel2.add(jPanel1);
      jPanel2.add(jCodePane);
       
      jScrollPane = com.mathworks.mwswing.MJScrollPane(jPanel2);
      [jhPanel,hContainer] = javacomponent(jScrollPane,[10,10,300,50],gcf);

      Note that even in the Matlab Editor line numbers are displayed in a separate glyph panel, and are not part of the syntax pane.

    • Jesper says:

      Hi Yair,

      I’m trying to get the linenumbers in, but simply adding your code example to the syntaxpane example above, gives a very weird result, both in matlab 2012b and 2013b.

      I must admit that I’m new to java in matlab, and i understand little of the code i am copy-pasting from your examples;
      is there a way you should edit the position vector for it to work correctly, or is it simply broken in the newer matlab releases?

  2. Oscar says:

    Thank you very much for sharing this extremely useful undocumented Matlab feature. I use it in several GUIs. One minor thing I am running into is that if a large text is loaded in the pane it automatically generates a scroll bar (great!), but the focus of the pane is on the end of the text. Is there a way to force the focus towards the top of the text (automatically move the scroll-bar all the way up)?

  3. Sune says:

    I’m having some troubles loading text into the CodePane directly from .m files. If I use a standard fopen fgets/fgetl approach to populate a string with the contents of a .m file, I miss all the string formatting and have to insert formatting myself. But this becomes troublesome when I try to correct for i.e. sprintf’s interpretation of apostrophes, backslash and so on. Does a more direct method exist for doing this job?

    • @Sune – not that I know of. There’s a setFilename(string) method, but apparently it doesn’t do what you need (I’m not exactly sure what it does). I suggest reading the file as a simple text file, character-by-character, without any formatting, and let the code pane do all the formatting for you.

  4. Jesper says:

    Hi Yair,

    First of all, love your work, love your book.

    I am currently implementing the syntaxpane in a GUI, where i would like to validate the matlab code entered.
    Do you know if its possible to extract information about syntax-errors from the jCodePane object?

    Hope you can help,

    Jesper

  5. Pingback: Animated busy (spinning) icon | Undocumented Matlab

Leave a Reply

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

*

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