- Undocumented Matlab - https://undocumentedmatlab.com -

Auto-completion widget

Posted By Yair Altman On April 29, 2015 | 23 Comments

Do you ever get a feeling when designing a Matlab GUI, that existing components/controls are simply not enough to achieve the desired functionality/appearance?
Such a case happened to me, when a consulting client asked me to integrate an auto-completion widget in a GUI that I designed for them. The idea was simple enough: the user selects a class of financial assets from a drop-down, then one or more actual financial securities from a dynamically-populated drop-down (based on the asset class), then the date range and analysis function, and finally the results are plotted in the main panel. The idea was for Matlab to automatically auto-complete the financial instruments matching the entered text, as it is being typed, similarly to other standard auto-completion widgets (e.g., Google’s search box), including the use of wildcards and regular expressions:

Interactive Matlab auto-completion widget
Interactive Matlab auto-completion widget

Note that in this particular case, I use the term “auto-completion” loosely. The correct term should actually be “auto-winnowing” or “auto-filtering”. Auto-completion is usually reserved for the case of the user-entered text being automatically completed as they type, whereas auto-winnowing only updates the drop-down options on-the-fly. These two functionalities are often correlated, and today’s article will discuss both.

AutoCompletionList

Before I dive into details of the implementation I ended up with, note that there are simpler alternatives. For example, we can use Matlab’s internal com.mathworks.widgets.AutoCompletionList widget:

strs = {'This','is','test1','test2'};
strList = java.util.ArrayList;
for idx = 1 : length(strs),  strList.add(strs{idx});  end
jPanelObj = com.mathworks.widgets.AutoCompletionList(strList,'');
javacomponent(jPanelObj.getComponent, [10,10,200,100], gcf);

AutoCompletionList widget
AutoCompletionList widget

The AutoCompletionList control is actually a list (rather than a drop-down), where the user types an entry in the header row. The control automatically selects the first corresponding list item and auto-completes the rest of the entry. Invalid user entries generate a beep and are not allowed by default (unless the widget’s Strict property is cleared: jPanelObj.setStrict(false)). The visible list size can be controlled by setting the widget’s VisibleRowCount property (jPanelObj.setVisibleRowCount(6)).
Items can be selected by either typing in the header row, by selecting a list item, or programmatically (jPanelObj.setSelectedValue('test1')). The currently selected item is retrieved via the same SelectedValue property (selectedValue = char(jPanelObj.getSelectedValue)). As with many other actionable Java controls, we can attach a callback on the ActionPerformed event:

set(handle(jPanelObj,'callbackproperties'), 'ActionPerformedCallback', @myMatlabCallbackFunc);

We can attach a similar callback to key-typing within the header row (text field), by accessing the widget’s internal component (which is the one that is actually being displayed via the javacomponent [1] function):

set(handle(jPanelObj.getComponent,'callbackproperties'), 'KeyTypedCallback', @myMatlabCallbackFunc);

SearchTextField

For my client’s purposes, however, AutoCompletionList could not be used. We wanted a drop-down selector that takes up far less space than a listbox. The first thought was to use a modified drop-down (editable combo-box [2]). This turned out to be less effective than hoped, because of the interference between the Matlab KeyTypedCallback function and the automatic behavior of the combo-box. I do not rule out the use of such an editable combo-box in other use-cases, but for this implementation I chose to use a different control, namely Matlab’s internal com.mathworks.widgets.SearchTextField, which has some nice additional features such as an optional light-gray prompt, and a clickable search icon that changes its appearance and behavior based on the entered text:

jPanelObj = com.mathworks.widgets.SearchTextField('Enter search term:');
[jhPanel,hContainer] = javacomponent(jPanelObj.getComponent, [10,10,150,25], gcf);
SearchTextField initial view
SearchTextField initial view
user clicks in entry box (prompt text disappears)
user clicks in entry box (prompt text disappears)
user types something (icon changes to 'x', clicking it will clear the text)
user types something
(icon changes to 'x', clicking it will clear the text)

An optical illusion

As with a regular combo-box, the dropdown-menu integration in Matlab proved a bit difficult, especially due to the auto-completion feature. Again, I do not rule out using it in other use-cases, but for this implementation I chose to use a visual illusion: an actual combo-box is placed beneath (hidden by) the SearchTextField control. So basically, we are seeing two separate parts of two different components: the edit-box of the SearchTextField, and the dropdown panel (a JPopupMenu) of the hidden combo-box. They appear attached, providing the optical illusion of being a single widget, when in fact they are not. Neat, right?

function createMainGUI()
   ...
   handles.cbAssetSearch = createAssetSelector(hAssetSearchPanel);
   ...
end
% Create the asset-name selector control within a parent container (panel/figure/tab/...)
function hContainer = createAssetSelector(hParent)
    % Create a uipanel to hold both sub-components below, one occluding the other:
    hContainer = handle(uipanel('BorderType','none', 'Parent',hParent));
    % Create a standard editable combo-box (drop-down) control
    callback = {@searchComboUpdated,hContainer};  % set to [] to disable asset combo selection callback
    hContainer1 = createComboSelector(hContainer, {'All'}, callback, true);
    set(hContainer1, 'Units','pixels', 'Position',[1,1,2,2]);
    % Create a SearchTextField control on top of the combo-box
    jAssetChooser = com.mathworks.widgets.SearchTextField('Enter search:');
    jAssetComponent = jAssetChooser.getComponent;
    [jhAssetComponent, hContainer2] = javacomponent(jAssetComponent,[],hContainer);
    hContainer2 = handle(hContainer2);
    set(hContainer2, 'tag','hAssetContainer', 'UserData',jAssetChooser, 'Units','norm', 'Position',[0,0,1,1]);
    setappdata(hContainer,'jAssetChooser',jAssetChooser);
    % Expand the SearchTextField component to max available width
    jSize = java.awt.Dimension(9999, 20);
    jAssetComponent.getComponent(0).setMaximumSize(jSize);
    jAssetComponent.getComponent(0).setPreferredSize(jSize);
    % Add callback handlers
    hjSearchButton = handle(jAssetComponent.getComponent(1), 'CallbackProperties');
    set(hjSearchButton, 'MouseClickedCallback', {@updateSearch,jCombo,jAssetChooser});
    hjSearchField = handle(jAssetComponent.getComponent(0), 'CallbackProperties');
    set(hjSearchField, 'KeyPressedCallback', {@updateSearch,jCombo,jAssetChooser});
    jCombo = handle(hContainer1.UserData, 'CallbackProperties');
    jComboField = handle(jCombo.getComponent(2), 'CallbackProperties');
    set(jComboField, 'KeyPressedCallback', {@updateSearch,jCombo,[]});
    set(jCombo, 'FocusLostCallback', @(h,e)jCombo.hidePopup);  % hide the popup when another component is selected
    % Return the containing panel handle
    hContainer.UserData = [jCombo, jhAssetComponent, handle(jAssetChooser)];
end  % createAssetSelector
function hContainer = createComboSelector(hParent, strings, callback, isEditable)
   % Note: MJComboBox is better than JComboBox: the popup panel has more width than the base control if needed
   jComboBox = com.mathworks.mwswing.MJComboBox(strings);  % =javax.swing.JComboBox(strings);
   jComboBox.setEditable(isEditable);
   jComboBox.setBackground(java.awt.Color.white); % unfortunately, this only affects editable combos
   [jhComboBox, hContainer] = javacomponent(jComboBox, [], hParent);
   set(jhComboBox, 'ActionPerformedCallback', callback);
   hContainer = handle(hContainer);
   set(hContainer, 'tag','hAssetContainer', 'UserData',jComboBox);
end

where the callback function for item selection might look something like this (here’s an example of the callback for the asset-search selector):

% Callback function for the asset selector combo
function searchComboUpdated(jCombo, eventData, hPanel)
    selectedItem = regexprep(char(jCombo.getSelectedItem),'<[^>]*>','');  % strip away HTML tags
    jSearchTextField = hPanel.UserData(2).getComponent(0);
    jSearchTextField.setText(selectedItem);
    jSearchTextField.repaint; drawnow; pause(0.01);
    jAssetChooser = getappdata(hPanel,'jAssetChooser');
    updateSearch([],[],jCombo,jAssetChooser);
end  % searchComboUpdated

Callback events are used to synchronize the components, update the combo-box’s dropdown options and display the dropdown panel. We attach the same callback function, updateSearch(), to 3 separate events: MouseClickedCallback on the SearchTextField‘s search button (icon), KeyPressedCallback on the search text-box, and another KeyPressedCallback on the combo-box’s text-box (which is not visible, but automatically receives focus when the user interacts with the popup menu (drop-down panel):

% Create the SearchTextField component (after the hidden combo was created)
jAssetChooser = com.mathworks.widgets.SearchTextField('Enter search:');
jAssetComponent = jAssetChooser.getComponent;
[jhAssetComponent, hContainer] = javacomponent(jAssetComponent,[],hPanel);
% Set callbacks:
% 1) search icon mouse-click
hjSearchButton = handle(jAssetComponent.getComponent(1), 'CallbackProperties');
set(hjSearchButton, 'MouseClickedCallback', {@updateSearch,jCombo,jAssetChooser});
% 2) search textbox key-click
hjSearchField = handle(jAssetComponent.getComponent(0), 'CallbackProperties');
set(hjSearchField, 'KeyPressedCallback', {@updateSearch,jCombo,jAssetChooser});
% 3) popup panel key-click
jComboField = handle(jCombo.getComponent(2), 'CallbackProperties');
set(jComboField, 'KeyPressedCallback', {@updateSearch,jCombo,[]});

(note that these callbacks were included in the createAssetSelector() example above)
The user can now select an item either from the combo-box’s dropdown panel, or by typing in the search text-box. Here is the implementation of the updateSearch() callback function:

% Asset search popup combo button click callback
function updateSearch(hObject, eventData, jCombo, jAssetChooser) %#ok
    persistent lastSearchText
    if isempty(lastSearchText),  lastSearchText = '';  end
    try
        % event occurred on the search field component
        try
            searchText = jAssetChooser.getSearchText;
            jSearchTextField = jAssetChooser.getComponent.getComponent(0);
        catch
            % Came via asset change - always update
            jSearchTextField = jAssetChooser.getComponent(0);
            searchText = jSearchTextField.getText;
            lastSearchText = '!@#$';
        end
    catch
        try
            % event occurred on the jCombo-box itself
            searchText = jCombo.getSelectedItem;
        catch
            % event occurred on the internal edit-field sub-component
            searchText = jCombo.getText;
            jCombo = jCombo.getParent;
        end
        jSearchTextField = jCombo.getComponent(jCombo.getComponentCount-1);
    end
    searchText = strrep(char(searchText), '*', '.*');  % turn into a valid regexp
    searchText = regexprep(searchText, '<[^>]+>', '');
    if strcmpi(searchText, lastSearchText) && ~isempty(searchText)
        jCombo.showPopup;
        return;  % maybe just clicked an arrow key or Home/End - no need to refresh the popup panel
    end
    lastSearchText = searchText;
    assetClassIdx = getappdata(handles.cbAssetClass, 'assetClassIdx');
    if isempty(assetClassIdx)
        jCombo.hidePopup;
        return;
    elseif isempty(searchText)
        assetNamesIdx = assetClassIdx;
    else
        searchComponents = strsplit(searchText, ' - ');
        assetCodeIdx = ~cellfun('isempty',regexpi(data.header.AssetCode(assetClassIdx),searchComponents{1}));
        assetNameIdx = ~cellfun('isempty',regexpi(data.header.AssetName(assetClassIdx),searchComponents{end}));
        if numel(searchComponents) > 1
            assetNamesIdx = assetClassIdx(assetCodeIdx & assetNameIdx);
        else
            assetNamesIdx = assetClassIdx(assetCodeIdx | assetNameIdx);
        end
    end
    setappdata(handles.cbAssetSearch, 'assetNameIdx', assetNamesIdx);
    if isempty(assetNamesIdx)
        jCombo.hidePopup;
        jSearchTextField.setBackground(java.awt.Color.yellow);
        jSearchTextField.setForeground(java.awt.Color.red);
        newFont = jSearchTextField.getFont.deriveFont(uint8(java.awt.Font.BOLD));
        jSearchTextField.setFont(newFont);
        return;
    else
        jSearchTextField.setBackground(java.awt.Color.white);
        jSearchTextField.setForeground(java.awt.Color.black);
        newFont = jSearchTextField.getFont.deriveFont(uint8(java.awt.Font.PLAIN));
        jSearchTextField.setFont(newFont);
    end
    % Compute the filtered asset names (highlight the selected search term)
    assetNames = strcat(data.header.AssetCode(assetNamesIdx), ' -=', data.header.AssetName(assetNamesIdx));
    assetNames = regexprep(assetNames, '(.+) -=', '$1', 'ignorecase');
    assetNames = unique(strrep(assetNames, ' -=', ' - '));
    if ~isempty(searchText)
        assetNames = regexprep(assetNames, ['(' searchText ')'], '$1', 'ignorecase');
        assetNames = strcat('', assetNames);
    end
    % Redisplay the updated combo-box popup panel
    jCombo.setModel(javax.swing.DefaultComboBoxModel(assetNames));
    jCombo.showPopup;
end  % updateSearch

Here is what the final result looks like and behaves:

Matlab GUI with integrated auto-completion & date selection widgets
Matlab GUI with integrated auto-completion & date selection widgets

Would you believe that this entire program is only 400 lines of code?!

Conclusion

I’ve heard it say on occasion that Matlab GUI is not really suited for professional applications. I completely disagree, and hope that today’s article proves otherwise. You can make Matlab GUI do wonders, in various different ways. Matlab does have limitations, but they are nowhere close to what many people believe. If you complain that your GUI sucks, then it is likely not because of Matlab’s lack of abilities, but because you are only using a very limited portion of them. This is no different than any other programming environment (admittedly, such features are much better documented in other environments).
In short, to improve your GUI’s functionality and appearance, you just need to spend a bit of time searching for the right components (possibly using my book [3]), or hire a professional consultant to do it for you. But of course, just bitching about Matlab’s supposed limitations is much easier…
Do you have a GUI that you find hard to believe can be done (or improved) in Matlab? Contact me for a consulting proposal and let me surprise you!

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


23 Comments (Open | Close)

23 Comments To "Auto-completion widget"

#1 Comment By Robert Cumming On April 30, 2015 @ 08:37

Hi Yair,

Another excellent example of what you can do with Matlab GUI’s. With some cool tricks and stretching the core Matlab capability you can design highly professional GUI’s, something that I have also done for many years.
I agree with you that the opinion of so many users is that Matlab cannot produce high quality graphical applications, its a real shame.

Regards

#2 Comment By lou On May 4, 2015 @ 11:50

I think what most people mean when bitching about MATLAB’s GUI are the limitations of the standard programming language. Most of your great tricks involve the java miracle (or nightmare) under the hood of MATLAB, which for most people might qualify as getting your hands dirty. You can learn to produce decent and efficient MATLAB code in a relatively short time; getting to grips with the standard GUI takes longer; but for someone who’s java-illiterate (like me) it seems like overkill to learn java for the sole purpose of exploiting undocumented MATLAB functionality. So I totally understand those who bitch about MATLAB, especially GUI-wise 🙂

That said, your solutions are awesome and clear in retrospect, but I don’t think a non-MATLAB-guru could develop such codes (defining a MATLAB-guru as someone who doesn’t only rely on the native functions of MATLAB, but tackles the java backend as well), hence comments about MATLAB’s (standard) functionalities.

#3 Comment By Ulrik On May 5, 2015 @ 01:52

Thanks for the inspiration….

I totally agree. Matlab does not limit the creativity regarding UI design. It is really nice to see that it integrates Swing UI components so well. I am now in the process of extending a program written in Matlab with custom components. It really makes the possibilities endless (Only limited by time)

It would be nice to see Mathworks upgrade Matlab to Java 8 and add JavaFX.

#4 Comment By Malcolm Lidierth On May 5, 2015 @ 17:18

@Ulrik

You can upgrade Java by copying the Java 8 JRE to your MATLAB app folder with many fewer problems than occurred with Java 6 -> Java 7.

To enable JavaFX, add javafxrt.jar (from the JRE) to your Java path using javaaddpath, then create an instance of javafx.embed.swing.JFXPanel. This will cause the JRE to do the work for you and initialise the JavaFX application thread.

If you create a JavaFX application, be sure to prevent javafx.application.Platform.exit() being called when you close it. The JavaFX thread will not robustly initialise twice in a given MATLAB instance. See [10]

There are threading issues between the the AWT/Swing EDT and the JavaFX application thread but I understand that these have been reduced for contents of a JFXPanel in the latest Java 8 releases. JFXPanel is a Swing component able to display JavaFX and can be added to a MATLAB GUI using [11] (or Yair’s [12] or my [13], which build on that).

M

#5 Comment By ikc On June 10, 2015 @ 14:35

Thank you for your post.
I am using combobox and editbox to do the same thing right now. However, Matlab will report
java.lang.OutOfMemoryError: GC overhead limit exceeded

So I am looking for another solution to approach my goal.
I try to reproduce your code on my machine. But I have question on the following statement.

assetClassIdx = getappdata(handles.cbAssetClass, 'assetClassIdx');

What is “handles” here for? jCombo? jAssetChooser? Or something else?

#6 Comment By Yair Altman On June 11, 2015 @ 03:39

@ikc – here’s a pared-down code-snippet that explains how cbAssetClass was created:

function createMainGUI()
   ...
   handles.cbAssetClass = createComboSelector(hPanel, ['All'; assetClassNames], @assetClassUpdatedCallback, false);
   ...
end

function hContainer = createComboSelector(hParent, strings, callback, isEditable)
   % Note: MJComboBox is better than JComboBox: the popup panel has more width than the base control if needed
   jComboBox = com.mathworks.mwswing.MJComboBox(strings);  % =javax.swing.JComboBox(strings);
   jComboBox.setEditable(isEditable);
   jComboBox.setBackground(java.awt.Color.white); % unfortunately, this only affects editable combos
   ...  % fixing the gray bgcolor of non-editable combos
   [jhComboBox, hContainer] = javacomponent(jComboBox, [], hParent);
   set(jhComboBox, 'ActionPerformedCallback', callback);
   hContainer = handle(hContainer);
   set(hContainer, 'tag','hAssetContainer', 'UserData',jComboBox);
end

#7 Comment By ikc On June 16, 2015 @ 07:24

@Yair
Thank you for your reply.
I think I have figured out how it works.
This could be a fancy search method we can use in MATLAB.

However,
I still encounter the Java OutOfMemory Error.
My MATLAB Java Heap Memory is 384 MB (Default).

What my Java script doing here is reading the description from the database and display the description on the GUI.
When user press and release the down arrow on the keyboard, selection will be moved to next item and description will be updated.
The challenge is, when user holding the down arrow, selection will be moved to next item very quickly, but the description update speed can’t catch up with the selection move speed.
I am using the following statement to capture the memory usage.

 
free = java.lang.Runtime.getRuntime.freeMemory
total = java.lang.Runtime.getRuntime.totalMemory
max = java.lang.Runtime.getRuntime.maxMemory

I can see the Java is consuming a ton of memory.
Do you have any thought on releasing the Java memory or only way we can do is increasing the heap size?

Thanks a lot.

#8 Comment By Rami On October 24, 2015 @ 14:51

Hello,

I’m trying to implement simple Auto Completion box in my simplistic GUI. And I have few Questions as a newbie to this area. I hope you would be patient enough to help me.

1. Can I implement these objects in my GUIDE built GUI? I started with GUIDE since it’s very easy to start going with. But I found that I don’t have this component. So How I get along?
2. As a follow-up to the last question, should I try to program my GUI from scratch? what are the advantages compared to the workload of creating everything manually?
3. Can you explain what each of the following commands in your example mean? I read your javacomponent article but I don’t understand how each argument affects the output.

 
jPanelObj = com.mathworks.widgets.AutoCompletionList(strList,'');
javacomponent(jPanelObj.getComponent, [10,10,200,100], gcf);

4. While playing around I tried to update the list. Updating the array was easy but I couldn’t find the object / property to update nor any proper update function to use. I tried different get options but it didn’t get me far enough.

Thanks,
Rami

#9 Comment By Yair Altman On October 26, 2015 @ 01:31

@Rami – This blog discusses advanced Matlab topics, which are typically way beyond the basics. GUIDE only includes basic controls in its designer. However, you can add any control, including all the ones that I highlight in this blog, within the m-file that is generated by GUIDE. Advanced Matlab users often find that it becomes easier to generate the entire GUI by hand, without using GUIDE at all, but you can add the advanced controls in either. The [14] will include more advanced controls than GUIDE, but there will always be a place for custom-made GUIs for professional appearance and functionality.

In the 2 code rows you provided, the first command created the Java component jPanelObj, and the second command placed this component in the GUI figure using the [11].

If you wish to learn more about creating advanced Matlab GUIs and/or working with Java in Matlab, get my [15]. If you have a commercial need, consider [16].

#10 Comment By Efraïm Salari On February 18, 2016 @ 18:17

Hi Yair,
I’m looking for an edit box which gives suggestions of what you might want to type (It’s a form that people need to fill out), but is not limited to the predefined options. I was thinking the auto-completion function might be an option (or are there other options for this?).

I tried to go through your code but it seems I missed something. The variables hPanel and jCombo could not be found. Is there some code I missed?

#11 Comment By Yair Altman On February 18, 2016 @ 19:27

@Efraim – I’m not sure what you want. I showed exactly how to do this in the main article above. If you did not understand my code then try to read it carefully and test the code in your Matlab, step-by-step. Good luck!

#12 Comment By Efraïm Salari On February 19, 2016 @ 15:51

Hi Yair,
Sorry for the unclarity. I’m making a form with edit boxes which people need to fill out.
I would like to show underneath the edit box some suggestions of commonly used input, based on what somebody is typing. However, like you suggested, I copied your code in my Matlab and tried to run it. I got two errors: The variables hPanel and jCombo could not be found. I went through all your code on this page but these two variables are not created. Do I need some code from another page maybe(e.g. where you explain the Editable combo-box)?

#13 Comment By Yair Altman On February 21, 2016 @ 17:12

@Efraim – hPanel is (of course) the panel handle that should contain the search-text field component; jCombo is the left-most combo-box that contains the asset names. If you need any assistance with getting it all to work in your specific project, consider hiring me for a short consultancy.

#14 Comment By Stefano On December 22, 2016 @ 11:47

Hi Yair,

I’m trying to implement your Autocomplete widget in my GUI (more simple than yours).
I’ve decided to split the code to better understand it, but i have two problems:

1) I can’t select the word from the combobox dropdown panel or by typing in the search text-box

How can i do that? How can i get the selected word to use it?
I’ve tried with jAssetChooser.getSearchText or jCombo.getSelectedItem but it didn’t work.
Must i use the setappdata comand?

2) If the word doesn’t match with my the list i get this Java error:

Error using provaaa/updateSearch (line 94)
Java exception occurred:
java.lang.NullPointerException
	at javax.swing.DefaultComboBoxModel.(Unknown Source)

I’m using matlab 2016a.

This is my example code:
[*** very large code section removed ***]

Thanks in advance.
Stefano

#15 Comment By Yair Altman On December 23, 2016 @ 12:57

@Stefano – answering this is beyond the time that I can spend on a blog comment. You’re invited to email me (altmany at gmail) for a short consultancy on your specific program.

#16 Comment By Johan On March 5, 2017 @ 02:26

Hello Yair,

Im having a problem with getting a keypress callback on R2015b for the simpe autocompletewidget:

strs = {'This','is','test1','test2'};
strList = java.util.ArrayList;
for idx = 1 : length(strs),  strList.add(strs{idx});  end
jPanelObj = com.mathworks.widgets.AutoCompletionList(strList,'');
javacomponent(jPanelObj.getComponent, [10,10,200,100], gcf);
set(handle(jPanelObj.getComponent,'callbackproperties'), 'KeyTypedCallback', @myMatlabCallbackFunc);

I would like to have this callback to register a ‘enter’ keystroke signifying a completed selection.

Any help would be greatly appreciated!

#17 Comment By Stev On October 5, 2018 @ 09:03

Hello together,

I am iteressted in the same point. I can implemement

set(handle(jPanelObj,'callbackproperties'), 'ActionPerformedCallback', @myMatlabCallbackFunc);
 

and this works fine, but with this callback I can not trigger on return or enter.

Do anybody have an idea to this topic.

Best Regards Stev

#18 Comment By Eric Alexander On March 27, 2018 @ 20:35

Yair,

I am trying to implement something very similar in a GUI I am making but after creating the Combo Box and running your above code, I am getting an error at the line:

assetClassIdx = getappdata(handles.cbAssetClass, 'assetClassIdx');

because there is no variable “handles.” What does this variable need to be?

#19 Comment By Yair Altman On March 27, 2018 @ 20:55

@Eric – read [17]

#20 Comment By Peter On May 13, 2018 @ 02:14

This looks great but as others have pointed out, the example is incomplete. Could you provide an actual working code as the code snippets you provide does not work by them self?

Thanks.

#21 Comment By Yair Altman On May 22, 2018 @ 12:22

@Peter – My aim in this post, as in my entire blog, is to provide general guidelines, code snippets and sample output. I expect my readers to fill in the missing blanks. Admittedly, not all readers can do this, but I aim high, unapologetically. I rarely spoon-feed users with complete code programs. This would be quite beyond the scope of a typical blog post, or the amount of time that I can spend pro-bono. Remember that this blog has 400 articles, so if I had to spend a full day on each one, this would translate to almost two full work-years!

I have now added some extra code and explanations to the main text, which should be more than enough for most Matlab developers. If it’s still not enough for you, then consider asking a professional Matlab developer to assist you.

#22 Comment By Peter On January 7, 2019 @ 20:34

Hi!

This is quite elegant. Unfortunately, there is a problem with Matlab hanging (matlab 2018b, windows 8.1) in the searchComboUpdated(obj, jCombo, eventData, hPanel) function. The hang occurs at jSearchTextField.setText(selectedItem). From other articles on your blog I learned that it could be EDT related and I hence added the drawnow; pause(0.1); that sometimes solves this. In this case it doesn’t help. In a newly started Matlab I get a hang everytime. It doesn’t hang in debug mode, but as soon as I run it without a breakpoint, it hangs. So frustrating.. and so unfortunate that Matlab has all these issues. I tried longer pause-times as well..didn’t help. Do you have any ideas?

Best,
Peter

PS: the code:

function searchComboUpdated(obj, jCombo, eventData, hPanel)
    ptime = 0.1;
    selectedItem = regexprep(char(jCombo.getSelectedItem),']*>','');  % strip away HTML tags
    fprintf('1');

    jSearchTextField = hPanel.UserData(2).getComponent(0);
    fprintf('2');
    drawnow; pause(ptime);

    str = java.lang.String(selectedItem);
    drawnow; pause(ptime);
    fprintf('2b');
    drawnow; pause(ptime);

    jSearchTextField.setText(str);
    drawnow; pause(ptime);
    fprintf('3');
    drawnow; pause(ptime);

    jSearchTextField.repaint; drawnow; pause(0.01);
    fprintf('4');

    jAssetChooser = getappdata(hPanel,'jAssetChooser');
    fprintf('5');

    obj.updateSearch([],[],jCombo,jAssetChooser);
    fprintf('6');
end  % searchComboUpdated

#23 Comment By Peter On January 7, 2019 @ 23:29

It seems i solved the issue i reported a couple of hours ago. I use [18] (thanks for explaining that in your other post) on jSearchTextField before the setText invocation..


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/auto-completion-widget

URLs in this post:

[1] javacomponent: http://undocumentedmatlab.com/blog/javacomponent

[2] editable combo-box: http://undocumentedmatlab.com/blog/editable-combo-box

[3] my book: http://undocumentedmatlab.com/books/matlab-java

[4] Builtin PopupPanel widget : https://undocumentedmatlab.com/articles/builtin-popuppanel-widget

[5] Auto-scale image colors : https://undocumentedmatlab.com/articles/auto-scale-image-colors

[6] Class object tab completion & improper field names : https://undocumentedmatlab.com/articles/class-object-tab-completion-and-improper-field-names

[7] Programmatic shortcuts manipulation – part 2 : https://undocumentedmatlab.com/articles/programmatic-shortcuts-manipulation-part-2

[8] Font selection components : https://undocumentedmatlab.com/articles/font-selection-components

[9] uigetfile/uiputfile customizations : https://undocumentedmatlab.com/articles/uigetfile-uiputfile-customizations

[10] : https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html

[11] : https://undocumentedmatlab.com/blog/javacomponent

[12] : http://www.mathworks.com/matlabcentral/fileexchange/14583-uicomponent-expands-uicontrol-to-all-java-classes

[13] : http://www.mathworks.com/matlabcentral/fileexchange/15580-using-java-swing-components-in-matlab

[14] : https://undocumentedmatlab.com/blog/sliders-in-matlab-gui#AppDesigner

[15] : https://undocumentedmatlab.com/books/matlab-java

[16] : https://undocumentedmatlab.com/consulting

[17] : https://undocumentedmatlab.com/blog/auto-completion-widget#comment-351076

[18] : https://undocumentedmatlab.com/blog/matlab-and-the-event-dispatch-thread-edt

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.