Recovering previous editor state

Editor with multiple loaded documents I find it very useful to use the Matlab editor’s ability to load multiple files to help me remember which files I still need to work on. I typically have a few dozen files loaded in the editor. I guess you could say that the editor’s list of files is a simple reflection of my open tasks. It would be extremely inconvenient if I ever lost this list.

Which is, unfortunately, exactly what happened to me yesterday.

I was about to close a figure window and accidentally closed the editor window that was behind it.

I was now in quite a jam: reopening the editor would not load all my files, but start with a blank (empty) editor. The Matlab editor, unlike modern browsers, does not have a ‘reopen last session’ option, and using the most-recently-used (MRU) files list would at best return the latest 9 files (the default Matlab preference is to have an MRU depth of only 4 files, but this is one of the very first things that I change whenever I install Matlab, along with a few other very questionable [IMHO] default preferences).

Luckily for me, there is an escape hatch: Matlab stores its Desktop windows state in a file called MATLABDesktop.xml that is located in the user’s prefdir folder. This file includes information about the position and state (docked/undocked etc.) of every Desktop window. Since the editor files are considered Desktop documents (you can see them under the Desktop’s main menu’s Window menu), they are also included in this file. When I closed the Editor, these documents were simply removed from the MATLABDesktop.xml file.

It turns out that Matlab automatically stores a backup version of this file in another file called MATLABDesktop.xml.prev, in the same prefdir folder. We can inspect the folder using our system’s file browser. For example, on Windows we could use:

winopen(prefdir)

So before doing anything else, I closed Matlab (I actually crashed it to prevent any cleanup tasks to accidentally erase this backup file, but that turned out to be an unnecessary precaution), deleted the latest MATLABDesktop.xml file, replaced it with a copy of the MATLABDesktop.xml.prev file (which I renamed MATLABDesktop.xml), and only then did I restart Matlab.

Problem solved – everything back to normal. Resume breathing. Once again I have my never-ending virtual task list in front of me as I write this.

Lessons learned:

  1. don’t be too quick on the close button trigger
  2. always keep a relatively recent backup copy of your important config files (BTW, I use the same advice with my FireFox browser, where I normally have dozens of open tabs – I keep a backup copy of the sessionstore.js file)
  3. if you do get into a jam, don’t do anything hasty that might make recovery impossible. Calm down, look around, and maybe you’ll find an automatic backup somewhere
Categories: Desktop, Low risk of breaking in future versions, Undocumented feature
Tags: , , ,
7 Comments

2011 perspective & plans for 2012

With 2011 behind us and a fresh 2012 ahead, it is time again for a short look at this website’s achievements so far, and plans for the future.

I started this blog three years ago, with an article on changing Matlab’s Command Prompt colors, shortly followed by an article on my cprintf utility, which to this day is still the most popular article on this website. cprintf is also one of my top-downloaded utilities, second only to findjobj, and closely followed by officedoc and uiinspect.

In 2011, I published 47 articles, including:

Hopefully there was enough material and diversity in there to satisfy different audiences. Judging by the traffic on the site, this appears to be the case indeed. Interest in this website still grows steadily, continuing the trend from the first two years. To date, 164,000 unique readers have read at least one article here (two on average), in over 300,000 different visits – more than doubling the figures from last year. In fact, the lowest traffic point of the year, which is customarily around Christmas/New-Year, has had about the same level of traffic this year as the highest-traffic weeks of 2010 (the other dip you see in 2011 is due to a week-long site-overhaul in March):

Steady readership growth (click for details)

Steady readership growth (click for details)

RSS and email subscription has also grown at a steady pace. I’m quite proud of the fact that there are more readers/subscribers to this blog than any other Matlab-related blog, excluding perhaps Loren’s. Having felt the pressure and difficulty in writing a fresh weekly post for the past three years, I truly admire Loren’s six years of continuous high-quality blogging.

The top countries from which you readers visit this site remains unchanged from last year’s post. So this year I will show a different angle, of the top cities visiting in 2011: Munich, London, Tel Aviv, Moscow, New York, Paris, Bangalore, Berlin, Zurich and Toronto.

Natick (MA, USA), home of the MathWorks HQ and some 30,000 other inhabitants, has dropped to 12th place in 2011, although it still maintains the #3 position in all-time visits (since this blog was started). Apparently, as this website gets wider recognition by Matlab users, the relative percentage of MathWorkers interested in this blog decreases, although in absolute numbers I can see that MathWorks visits have remained more-or-less constant.

Readers from all over the world (click for details)

Readers from all over the world (click for details)

In 2012 I plan to continue posting about undocumented aspects of Matlab. Specific plans include the much-overdue articles on uiinspect and its close relative checkClass, as well as additional articles on internal built-in controls. I hope to cross out many items in my TODO list.

There will also be more articles by guest bloggers – I have a growing list of such guest bloggers, of which I am extremely pleased, and some of the promised articles are very interesting. I encourage anyone who has an idea for an article to contact me by email (altmany at gmail, or use the link at the top-right of this page).

Happy 2012 everybody!

- Yair Altman

Categories: Uncategorized
Leave a comment

Command Window text manipulation

Sometimes the most obscure problems have simple solutions.

A few days ago, a Matlab user asked whether it is possible to solve the flashing effect whenever he cleared the Command Window. It turns out that this user runs a long process, and wanted to display interim information (progress etc.) in the Command Window. The obvious solution that he employed was to display the data in the Command Window, and then erase the window (using clc) and rewrite the data periodically.

Using control characters

Now, there are obviously other ways of doing this, the most obvious being a dedicated GUI window that displays the information and updates periodically. But to solve the user’s immediate issue, the solution I provided (acting on the 80-20 Pareto principle – a dedicated GUI window is better but would take longer to set up) was to use control characters to erase old data when displaying new data, rather than clearing the window. Here is the basic pseudo-code that I suggested (slightly modified):

reverseStr = '';
for idx = 1 : someLargeNumber
 
   % Do some computation here...
 
   % Display the progress
   percentDone = 100 * idx / someLargeNumber;
   msg = sprintf('Percent done: %3.1f', percentDone)
   fprintf([reverseStr, msg]);
   reverseStr = repmat(sprintf('\b'), 1, length(msg));
end

The idea is to use the backspace control-character (BS, or sprintf(‘\b’), or char(8)) repeatedly in order to erase the preceding characters from the Command Window, then print the new data.

(see related comments by Helge here)

Compatibility aspects

Back in the good-ol’-days, when I was hacking away c-shell scripts, ages ago when I created command-prompt C apps, and aeons ago on Vax (R.I.P.), I would have used the carriage-return control-char (CR, or sprintf(‘\r’), or char(13)) to completely erase everything up to the beginning of the current line. This would be much simpler than the repeated backspaces (using repmat in the pseudo-code above). Unfortunately, CRs behave differently in Matlab’s Command Window, causing \r to jump to the next line (similarly to \n), rather than erase to the beginning of the line. This is probably due to Java’s JTextArea’s implementation (on which the Command Window is based), and not due to Matlab itself. In any case, it shows that not all control characters behave the same way on different environments, which is actually not very surprising.

Another widely-used control character, the bell control-char (BEL, or sprintf(‘\g’), or char(7)) is not accepted at all by Matlab’s implementation of sprintf and its variants. Matlab users can always use the beep function of course, I’m just pointing this out as another inconsistency between Matlab’s *printf() implementation and that of other environments. And don’t even think of using raw device escape sequences (ah, the good-ol’-days, long gone now…).

Control characters that are accepted in Matlab and behave as expected include: FF (\f), NL (\n) and TAB (\t). These can be used in fprintf to modify the text spacing. The sprintf documentation mentions which of the control characters are accepted, so this is not, strictly speaking, an undocumented aspect. However, note that there is a discrepancy between the list of accepted control chars in the online/doc page compared to the help section (\a and \v are mentioned in the former but not in the latter).

For another type of Command Window text manipulation, namely colors, refer to my cprintf utility. For anyone who hasn’t noticed, I recently updated the utility on the Matlab File Exchange. Due to some internal modifications by MathWorks to the Command Window implementation in R2011b, cprintf no longer needs to pad color segments with spaces, and separate color segments can now be directly adjacent to each other (in R2011a and earlier, the spaces are unfortunately needed).

Have you used control characters in an innovative manner in your work? If so, please share your experience in a comment.

Happy New Year everyone!

Categories: Desktop, Low risk of breaking in future versions, Stock Matlab function
Tags:
3 Comments

Ideas for a new book

The experience of writing my Matlab-Java book was truly exhilarating. The book is now officially published and several hundred copies have been shipped already, first in America and starting last week also in the rest of the world. I hope these will all arrive before Christmas – if not then please be patient a few more days, since the initial demand has apparently exceeded the printing expectations.

If you are one of those who have received the book, please be kind enough to write a review of it, in book sites such as Amazon or Barnes & Noble.

As promised, I will maintain the book’s webpage with an errata list and possibly more information, as they become available.

The question of a new book

As with any birth, the initial exhilaration completely overwhelms, letting me forget how hard it has been to write the book. So while this “high” lasts, I wanted to ask you my readers for your opinion regarding a possible future book.

Which of the following books by me, possibly co-authored with another writer, would you be interested to read and/or have in your library?

  1. Professional Matlab application development
  2. Professional Matlab GUI
  3. Matlab performance tuning
  4. Undocumented Matlab – the non-Java parts
  5. Some other subject (please specify)
  6. None of the above

Please choose only a single item, or prioritize your choices. It will be a book about only one of the above topics, not several topics. I’m not going to write another 700-page monster that takes 5 years to prepare…

There are of course many factors going into a decision about whether or not to enter a book-writing project. It is a multi-year commitment that requires lots of effort, time, focus, and attention to detail. It affects the writer in a way that influences the entire family. In fact, my wife has already voted an emphatic “NO!” on this subject, and I’m pretty ambivalent about this issue myself.

Please do let me know what you think in a short comment. Happy Holidays everyone!

Categories: Uncategorized
Tags:
16 Comments

Converting Java vectors to Matlab arrays

Matlab includes built-in support for automatic conversion of Matlab cell arrays into Java arrays. This is important in cases when we need to pass information to a Java function that expects an array (e.g., String[]).

Numeric data array

In some cases, namely Java numeric arrays, Matlab also automatically converts the Java array into Matlab arrays. This is actually inconvenient when we would like to access the original Java reference in order to modify some value – since the Java reference is inaccessible from Matlab in this case, the data is immutable.

>> jColor = java.awt.Color.red
jColor =
java.awt.Color[r=255,g=0,b=0]
 
>> matlabData = jColor.getColorComponents([])
matlabData =
     1
     0     % < = immutable array of numbers, not a reference to int[]
     0

Non-numeric array

Very often we encounter cases in Java where the information is stored in an array of non-numeric data. In such cases we need to apply a non-automatic conversion from Java into Matlab.

If the objects are of exactly the same type, then we could store them in a simple Matlab array; otherwise (as can be seen in the example below), we could store them in either a simple array of handles, or in a simple cell array:

>> jFrames = java.awt.Frame.getFrames
jFrames =
java.awt.Frame[]:
    [javax.swing.SwingUtilities$SharedOwnerFrame ]
    [com.mathworks.mde.desk.MLMainFrame          ]
    [com.mathworks.mde.desk.MLMultipleClientFrame]
    [com.mathworks.mwswing.MJFrame               ]
 
% Alternative #1 - use a loop
>> mFrames = handle([]); for idx = 1 : length(jFrames); mFrames(idx)=handle(jFrames(idx)); end
>> mFrames
mFrames =
	handle: 1-by-4
>> mFrames(1)
ans =
	javahandle.javax.swing.SwingUtilities$SharedOwnerFrame
>> mFrames(2)
ans =
	javahandle.com.mathworks.mde.desk.MLMainFrame
 
% Alternative #2a - convert into a Matlab cell array
>> mFrames = jFrames.cell
mFrames = 
    [1x1 javax.swing.SwingUtilities$SharedOwnerFrame ]
    [1x1 com.mathworks.mde.desk.MLMainFrame          ]
    [1x1 com.mathworks.mde.desk.MLMultipleClientFrame]
    [1x1 com.mathworks.mwswing.MJFrame               ]
 
% Alternative #2b - convert to a cell array (equivalent variant of alternative 2a)
>> mFrames = cell(jFrames);

Note that if we only need to access a particular item in the Java vector or array, we could do that directly, without needing to convert the entire data into Matlab first. Simply use jFrames(1) to directly access the first item in the jFrames array, for example.

(note: Java Frames are discussed in chapters 7 and 8 of my Matlab-Java book).

Vectors and other Collections

Very often we encounter cases in Java where the information is stored in a Java Collection rather than in a simple Java array. The basic mechanism for the conversion in this case is to first convert the Java data into a simple Java array (in cases it was not so in the first place), and then to convert this into a Matlab array using either the automated conversion (if the data is numeric), or using a for loop (ugly and slow!), or into a cell array using the cell function, as explained above.

Different Collections have different manners of converting into a Java array: some Collections return an Iterator/Enumerator that can be processed in a loop (be careful not to reset the iterator reference by re-reading it within the loop):

% Wrong way - causes an infinite loop
idx = 1;
props = java.lang.System.getProperties;
while props.elements.hasMoreElements
    mPropValue{idx} = props.elements.nextElement;
end
 
% Right way
idx = 1;
propValues = java.lang.System.getProperties.elements;  % Enumerator
while propValues.hasMoreElements
    mPropValue{idx} = propValues.nextElement;
end

(note: system properties are discussed in section 1.9 of my Matlab-Java book; Collections are discussed in section 2.1)

Other Collections, such as java.util.Vector, have a toArray() method that directly converts into a Java array, and we can process from there as described above:

>> jVector = java.util.Vector;
>> jVector.add(1); jVector.add(2); jVector.add(3);
>> jVector.addAll(jv); jVector.addAll(jv);
>> jVector
jVector =
[1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0]
 
% Now convert into a Matlab cell array via a Java simple array
>> mCellArray = jVector.toArray.cell
mCellArray = 
    [1]
    [2]
    [3]
    [1]
    [2]
    [3]
    [1]
    [2]
    [3]
    [1]
    [2]
    [3]

Performance

It so happens, that the undocumented built-in feature function (or its near-synonym system_dependent) enables improved performance in this conversion process. feature(44) accepts a java.util.Vector and converts it directly into a Matlab cell-array, in one third to one-half the time that it would take the equivalent toArray.cell() (the third input argument is the number of columns in the result - the reshaping is done automatically):

>> mCellArray = feature(44,jVector,jVector.size)   % jVector.size = 12
mCellArray = 
    [1]    [2]    [3]    [1]    [2]    [3]    [1]    [2]    [3]    [1]    [2]    [3]
 
>> mCellArray = feature(44,jVector,4)
mCellArray = 
    [1]    [1]    [1]    [1]
    [2]    [2]    [2]    [2]
    [3]    [3]    [3]    [3]

The conversion process is pretty efficient: On my system, the regular toArray.cell() takes 0.45 seconds for a 100K vector, compared to 0.21 seconds for the feature alternative. However, this small difference could be important in cases where performance is crucial, for example in processing of highly-active Java events in Matlab callbacks, or when retrieving data from a database. And this latter case is indeed where a sample usage of this feature can be found, namely in the cursor.fetch.m function (where it appears as system_dependent(44)).

Please note that both feature and system_dependent are highly prone to change without prior warning in some future Matlab release. On the other hand, the conversion methods that I presented above, excluding feature, will probably still be valid in all Matlab releases in the near future.

Categories: Java, Low risk of breaking in future versions
Tags: , ,
1 Comment

Common javacomponent problems

The javacomponent function, which I described here last year, is a very important built-in Matlab function that enables placing Java components in Matlab figure GUI. Using javacomponent is pretty straight-forward. However, there are a few quirks that users should be aware of. In today’s article I’ll try to highlight some of them and discuss workarounds.

Figure visibility

Java components can only be placed onscreen when their containing Matlab figure has been made visible. This means that calls to javacomponent cannot be placed at the GUIDE-created *_OpeningFcn() function, because that function is invoked before the figure window is made visible.

Of course, we can always force the figure to become visible by setting the figure’s Visible property to 'on' in this function, before calling our javacomponents. But IMHO, a better option would be to simply place the javacomponents in the corresponding GUIDE-created *_OutputFcn() function, which is invoked after the figure window is made visible.

Auto-hiding with parent container

Java components are not automatically hidden with their ancestor container panel. This is also the root cause of the failure of Java components to disappear when switching tabs in a uitab.

One simple workaround for this that I often use is to link the Visible properties of the javacomponent container and the parent container:

jButton = javax.swing.JButton('click me!');
[jhButton, hContainer] = javacomponent(jButton, [100,100,60,30], hParent);
setappdata(hParent, 'linked_props__', linkprop([hParent,hContainer],'Visible'));

This has indeed been fixed in R2010b. If you ask me, this should have been standard behavior of javacomponent since the very beginning…

Although there is no need for the workaround in R2010b onward, I usually keep the workaround because it doesn’t hurt and enables backward compatibility for users who may have an older Matlab release.

Possible parent container types

javacomponent accepts parent handles that are figures, toolbars, uipanels, or uicontainers (some of these are not documented as possible parents in some Matlab releases, but they are). Since R2008a, parents of type uisplittool and uitogglesplittool can also be used. Unfortunately, frames are not uicontainers and, therefore, cannot be used as javacomponent parents.

Note: Due to a bug in R2007a, javacomponents cannot be added to uicontainers, since javacomponent.m checks if isa(hParent,'uicontainer') (and similarly for 'uiflowcontainer', 'uigridcontainer'), instead of isa(hParent,'hg.uicontainer') (and similarly for the others). If we modify javacomponent.m accordingly (add “hg.” in lines 98-100), this bug will be fixed. Since R2007b, isa(…,'hg.uicontainer') is equivalent to isa(…,'uicontainer'), so this fix is unnecessary.

Input parameters

Unlike many other Matlab functions, javacomponent does not accept optional parameter-value (P-V) pairs. If we want to customize the appearance of the Java component, it is better to create it , customize it, and only then to present it onscreen using javacomponent. If we first present the component and then customize it, there might be all sorts of undesirable flicker effects while the component is changing its properties.

One of the parameters that unfortunately cannot be customized before calling javacomponent is the component’s position onscreen. javacomponent only accepts a position vector in pixel units. To modify the component to use normalized units, we need to modify the container’s properties:

jButton = javax.swing.JButton('click me!');
[jhButton, hContainer] = javacomponent(jButton, [100,100,60,30], gcf);
set(hContainer, 'Units','norm');

Similarly, we can set the container’s UserData and ApplicationData only after the call to javacomponent.

Background color

The default background color of javacomponents is a slightly different shade of gray than the default uicontrol background color. Please refer to my recent article for a detailed discussion of this issue.

Vertical alignment

Java components are slightly mis-aligned vertically with combo-box (Style=’popup’) uicontrols, even when positioned using the same Y position. This is actually due to an apparent bug in Matlab’s implementation of the combo-box uicontrol, and not in the Java component’s: Apparently, the Matlab control does not obey its specified height and uses some other default height.

If we place javacomponents side-by-side with a regular Matlab popup uicontrols and give them all the same Y position, we can see this mis-alignment. It is only a few pixels, but the effect is visible and disturbing. To fix it, we need to add a small offset to the javacomponent‘s container’s Position property to make both the initial Y position slightly lower, and the height value slightly higher than the values for the corresponding Matlab combo-box control.

Callbacks

Unlike Matlab uicontrol callbacks, Java callbacks are activated even when the affected value does not change. Therefore, setting a value in the component’s callback could well cause an infinite loop of invoked callbacks.

Matlab programmers often use the practice of modifying component value within the callback function, as a means of fixing user-entered values to be within a certain data range, or in order to format the displayed value. This is relatively harmless in Matlab (if done correctly) since updating a Matlab uicontrol‘s value to the current value does not retrigger the callback. But since this is not the case with Java callbacks, users should beware not to use the same practice there. In cases where this cannot be avoided, users should at least implement some sort of callback re-entrancy prevention logic.

EDT

Java components typically need to use the independent Java Event processing Thread (EDT). EDT is very important for Matlab GUI, as explained in this article. Failure to use EDT properly in Matlab can lead to unexpected GUI behavior and even Matlab hangs or crashes.

If the javacomponent function is called in a very specific syntax format where the first input arg is a string (the name of the Java class to be created), then the newly-created component is placed on the EDT. However, this is not the normal manner in which javacomponent is used: A much more typical use-case is where javacomponent is passed a reference handle to a previously-created Java component. In such cases, it is the user’s responsibility to place the component on the EDT. Until R2008a this should be done using the awtcreate function; since R2008b, we can use the much simpler javaObjectEDT function (javaObjectEDT actually existed since R2008a, but was buggy on that release so I suggest using it only starting in R2008b; it became documented starting in R2009a). In fact, modern javacomponent saves us the trouble, by automatically using javaObjectEDT to auto-delegate the component onto the EDT, even if we happen to have created it on the MT.

The paragraph above may lead us to believe that we only need to worry about EDT in R2008a and earlier. Unfortunately, this is not the case. Modern GUI requires using many sub-components, that are attached to their main component (e.g., CellRenderers and CellEditors). javacomponent only bothers to place the main component on the EDT – not any of the sub-components. We need to handle these separately. Liberally auto-delegating components to the EDT seems like a safe and painless habit to have.

Categories: GUI, Java, Medium risk of breaking in future versions, Semi-documented function
Tags: , , , ,
2 Comments