A few days ago, a CSSM user asked whether it is possible to modify the appearance of the Bytes column in the Workspace pane, so that it will present data in KBytes rather than in Bytes. Although I promised that my next post will explain FindJObj and its uses, I couldn’t resist the challenge. Here’s the solution to the request:
In this post I will assume Matlab release R2008a (7.6) - the adaptations for other releases should be minor at worst. First, we need to retrieve the Workspace table’s Java reference handle. In the past I’ve already shown several uses for the Matlab Desktop’s Java handle. Today we’ll use this handle to get the Workspace pane’s handle:
>> jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance jDesktop = com.mathworks.mde.desk.MLDesktop@42d390 >> jWSBrowser = jDesktop.getClient('Workspace') jWSBrowser = com.mathworks.mde.workspace.WorkspaceBrowser[Workspace,0,24,355x707,...] >> jWSTable = jWSBrowser.getComponent(0).getComponent(0).getComponent(0) jWSTable = com.mathworks.mlwidgets.workspace.WorkspaceTable[WorkspaceTable,0,0,352x102,...]
Next, we note that jWSTable is a simple java Swing JTable, and as such we can easily modify its column header:
jWSTable.getColumn('Bytes').setHeaderValue('KBytes'); jWSBrowser.repaint;
Modifying the column’s behavior to display 1/1024 of the initial values is more tricky. We can use a simple TableCellRenderer, replacing WorkspaceTable’s DefaultTableCellRenderer. We first create the following KBytesCellRenderer.java file:
import java.awt.*; import javax.swing.*; import javax.swing.SwingConstants.*; import javax.swing.table.*; public class KBytesCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); //System.out.println(row + "," + column + " => " + value); ((KBytesCellRenderer)cell).setHorizontalAlignment(TRAILING); // TRAILING = right int bytes = Integer.parseInt(value.toString()); ((KBytesCellRenderer)cell).setText(bytes/1024 + ""); // Bytes => KBytes return cell; } public KBytesCellRenderer() { super(); } }
Next, we find out our Matlab’s Java version:
>> version -java ans = Java 1.6.0 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode
Next, we download and install a JDK version compatible with our Matlab’s Java version. You can download the latest JDK from here or here. Previous JDK versions can be downloaded from here or here (which even lets you select your requested update number). Development versions, usually fixing reported bugs, are described and can be downloaded from here. Note that you need the full JDK, not just the JVM/JRE runtime versions.
Next, we compile this file using the JDK’s Java compiler (javac) utility: In your system’s command-line (outside Matlab), type the following in the folder containing your KBytesCellRenderer.java file:
javac KBytesCellRenderer.javaIf all goes well, javac will report no error and will create a KBytesCellRenderer.class file in the current folder (or you can download it directly from here).
Now copy this KBytesCellRenderer.class file to one of the folders in your Matlab’s javaclasspath (for example, C:\Program Files\Matlab\R2008a\java\patch\) and restart Matlab. Don’t worry - all this is only a one-time operation.
After restarting Matlab, we have all the chips in place, so we can place the following code in our startup.m script:
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance; jWSBrowser = jDesktop.getClient('Workspace'); jWSTable = jWSBrowser.getComponent(0).getComponent(0).getComponent(0); jWSTable.getColumn('Bytes').setHeaderValue('KBytes'); jWSTable.getColumn('Bytes').setCellRenderer(KBytesCellRenderer); jWSBrowser.repaint;

Before - bytes

After - KBytes
We can use a slightly more complex CellRenderer to highlight cells with too high a value or to present thousands (comma) separator by simply modifying and recompiling KBytesCellRenderer.java, updating the class file in our javaclasspath folder and restarting Matlab. Here’s the version for the thousands separator (American locale):
import java.awt.*; import javax.swing.*; import javax.swing.SwingConstants.*; import javax.swing.table.*; import java.text.NumberFormat; public class KBytesCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); //System.out.println(row + "," + column + " => " + value); ((KBytesCellRenderer)cell).setHorizontalAlignment(TRAILING); // TRAILING = Right int bytes = Integer.parseInt(value.toString()); NumberFormat nf = NumberFormat.getInstance(); ((KBytesCellRenderer)cell).setText(nf.format(bytes/1024)); // Bytes => KBytes return cell; } public KBytesCellRenderer() { super(); } }

After - formatted KBytes
If you have created an interesting CellRenderer, I will be happy to hear about it in the comments section below.
Related posts:
- 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...
- Setting the Matlab desktop layout programmatically The Matlab desktop enables saving and switching layouts using the main menu. This post shows how to do so programmatically....
- Accessing the Matlab Editor The Matlab Editor can be accessed programmatically, for a wide variety of possible uses - this article shows how....
- 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....
- setPrompt - Setting the Matlab Desktop prompt The Matlab Desktop's Command-Window prompt can easily be modified using some undocumented features...
- EditorMacro - assign a keyboard macro in the Matlab editor EditorMacro is a new utility that enables setting keyboard macros in the Matlab editor. this post details its inner workings....
Print
|


I surely noted your answer the day you posted it in my NG help request. I also implemented your solution but i wanted to display MB with two decimal places and comma separated values…
Since i never programmed in JAVA i spent all day trying on the links that you added here…and this is as far as i went:
first of all i don’t know how to elevate to a power :).
second i can’t get it rigtht with the decimal format….
I’ll keep trying…
Oleg
Oleg - There are two separate problems with your code:
1) you need a DecimalFormat object (instance) before you can use applyPattern().
2) bytes/(1024*1024) is an integer division so the result is rounded to an integer. Instead, use bytes/(1024.0*1024.0) to ensure a floating-point result.
Here’s the resulting code fragment:
You might also be interested to add a “MB” suffix:
I plan to submit a utility to the File Exchange within a few days, that will enable users to choose their display format. I will post a followup when it is available.
By the way, DecimalFormat (and most Java) experiments can easily be done directly in the Matlab Command Window, without the annoying need to recompile Java and restart Matlab. For example:
Thank you very much for the tips. I’m eager to try your next submission!
Oleg
Nice trick!
Is it possible to make the Size column display the size for 4-D matrices this way?
Right now, the Size column just displays “4-D” in case of a 4-D matrix, instead of “m x n x p x q”, which is very annoying…
Cheers,
Ben
@Ben - I think what you ask is possible if you add a JMI call in your CellRenderer. In a nutshell, the Renderer code will get the variable name from the table’s other column, and query its size by invoking JMI with the size function. However, this is non-trivial and also goes against known programming practices (that Renderers should be kept as light and fast as possible). On the other hand, I cannot think of any other way to do it.