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. 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...
  2. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  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. 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....

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

Tags: , , , ,

Bookmark and SharePrint Print

16 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

  6. Adam says:

    Hi Yair,

    Thank you for this great article and the accompanying chapter in your book. I’ve enjoyed both thoroughly. The SyntaxTextPane seems perfect for an application I’m looking to write (a simple XML editor in MATLAB), but the only acceptable MIME-type as far I can tell is the MATLAB one. Passing in the XML MIME type does not seem to have any effect and passing in the HTML MIME type throws a Class Cast Exception (or something similar). I am on MATLAB R2013a.

    Are you aware of any syntax highlighting functionality for languages other than MATLAB within SyntaxTextPane? If so, how can I activate that functionality? If not, is there a way for me to write my own syntax highlighting rules and pass them into an instance of SyntaxTextPane? Or, I noticed that the MATLAB Editor has rules for XML/HTML syntax highlighting… can I make use of that some how?

    Thank you for your great work!

  7. Björn says:

    Hi Yair,
    This is a great blog! I wouldn’t be able to do much java programming without it.

    The SyntaxTextPane and the possibility to add line numbers as you showed in a comment is great. Is it also possible to include the code folding capability of the Matlab editor in this textpane? I haven’t been able to find any way of including a com.mathworks.widgets.text.fold.MWCodeFoldingSideBar which I think is the way to do it.
    Your help is highly appreciated.

    Björn

  8. John Smith says:

    Hi, Yair,

    Thank you very much for the info on your blog and book. They are very useful.

    I came to this “syntax hilite” blog because I was searching how to delete all comments in an M-file. Since Matlab recognizes comments, and it doesn’t get confused by, for example, % comment text…, fprintf(‘%10.3f’), or sprintf(‘%% comment’), I want to utilize it and not reinvent the wheel like some existing file on the FileExchange.

    But the question is: where can I find that method and in which class? What is the syntax for that method?

    If you already have posts regarding to this topic, could you show me that article?

    Thank you very much!

    • @John – to the best of my knowledge there is no direct method to do this. You are welcome to try to poke around in the Java classes mentioned in this article, but I don’t think it will get you what you want.

      I’ve created a utility that does this (stripping comments from m-files) for my personal use and it works splendidly. I’m willing to sell you a copy if you wish – contact me by email (altmany at gmail) if you are interested.

Leave a Reply

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

*

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