Skip to content
This repository has been archived by the owner on Nov 25, 2018. It is now read-only.

Conversion of App Designer uielements to "regular ones" #6

Open
Dev-iL opened this issue Apr 19, 2016 · 8 comments
Open

Conversion of App Designer uielements to "regular ones" #6

Dev-iL opened this issue Apr 19, 2016 · 8 comments

Comments

@Dev-iL
Copy link
Member

Dev-iL commented Apr 19, 2016

It is no secret that designing a UI in App Designer is much more convenient (one might even say fun) than using GUIDE. However, this comes at the price of lower customizability among other things.

It would be very useful to be able to design a UI in App Designer and then export it using "regular" elements (uicontrol).

This functionality can conceptually be achieved by mapping various App Designer Component names to their corresponding uicontrol/figure/axes counterparts.

sco1 added a commit that referenced this issue Apr 25, 2016
The XML processing code has been split into individual components and
wrapped for better portability in the code. No change to functionality
has been made.

Framework has been added to support additional conversion parameters.

Inline documentation updated with new syntax.

See: #6
@sco1
Copy link
Member

sco1 commented Apr 25, 2016

A caveat to this conversion is that the GUIs will still likely require R2014b or newer. The App Designer makes extensive use of dot notation to access properties of UI objects rather than set or get. A warning to this effect will be included for users running mlapp2classdef in MATLAB versions prior to R2014b.

Though a fun project idea on its own, creating a parser to robustly handle these compatibility issues is beyond the scope of this project.

sco1 added a commit that referenced this issue Apr 25, 2016
@sco1
Copy link
Member

sco1 commented Apr 25, 2016

Another consideration is that a lot of the object properties and callbacks are new to R2016a, which isn't something that can be reliably caught without significant effort

@Dev-iL
Copy link
Member Author

Dev-iL commented Apr 25, 2016

For posterity: it may be possible to convert some App Designer elements to Java Swing components, e.g.:

%% List of JComponents:
% https://docs.oracle.com/javase/8/docs/api/javax/swing/JComponent.html

%% Spinner - https://docs.oracle.com/javase/8/docs/api/javax/swing/JSpinner.html
jSp = javaObjectEDT('javax.swing.JSpinner');
% Get available methods & fields:
M = methods(jSp); 
F = fields(jSp); % fields often contain the allowable settings for methods.
% Set some properties:
jSp.setAlignmentX(jSp.LEFT_ALIGNMENT);
% Display component
[jSpinner, hSpContainer] = javacomponent(jSp,'South');
% https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingConstants.html

%% Scrollbar (example based on Altman-2012)
% Create and initialize a JScrollBar object 
jSb = javaObjectEDT('javax.swing.JScrollBar');
% Set some properties:
jSb.setOrientation(jSb.HORIZONTAL);
% Display component
[jScrollbar, hSbContainer] = javacomponent(jSb,'North');

sco1 added a commit that referenced this issue Apr 27, 2016
Add conversion for callbacks introduced with the new UI elements in
R2016a (e.g. ValueChanged, SelectionChanged). These have been replaced
with "regular" callbacks.

Add regex removal of the registerApp function, introduced in R2016a.
This has been replaced with a comment indicating function call removal.

See: #6
sco1 added a commit that referenced this issue May 4, 2016
Starting in R2016a, the documented method to declare class property
types is to specify them after the property declaration with a space in
between (e.g. HeaderLength uint16). This is different from the previous
(undocumented) approach of separating them with the @ symbol (e.g.
HeaderLength@uint16). While the old undocumented approach continues to
function in R2016a, the documented R2016a convention is not backwards
compatible. For m-code loaded in as an array of cells (<R2014b), an
algorithm has been added to locate the property definition blocks and
run a regex to convert all type specifications to the legacy syntax.

See #6, #7
@Dev-iL
Copy link
Member Author

Dev-iL commented May 9, 2016

Here's a better demo of how to make a spinner and attach a callback to it:

function hFig = spinnerDemo
%% javacomponent "docs": Delete lines 2-3 from javacomponent.m to get access to docs using F1 (help browser)
%% Spinner - https://docs.oracle.com/javase/8/docs/api/javax/swing/JSpinner.html
hFig = figure(); 
% Create a spinner (w/o model): 
jJSpinnerNM = javacomponent(javax.swing.JSpinner,[50,40,80,30],hFig);
jJSpinnerNM.StateChangedCallback = @(hObject,eventdata)onSpinnerValueChanged(hObject,eventdata);
% Create a spinner (w/ model): 
spModel = javax.swing.SpinnerListModel({'item1','item2','item3'});
  % https://docs.oracle.com/javase/8/docs/api/javax/swing/SpinnerModel.html
jJSpinnerM = javacomponent(javax.swing.JSpinner(spModel),[50,80,80,30],hFig);
jJSpinnerM.StateChangedCallback = @(hObject,eventdata)onSpinnerValueChanged(hObject,eventdata);

%% Get available methods & fields, and set some properties:
M = methods(jJSpinnerM); 
F = fields(jJSpinnerM); % fields often contain the allowable settings for methods.

% Set some arbitrary property:
jJSpinnerNM.getEditor.getTextField.setHorizontalAlignment(javax.swing.JTextField.LEFT);
  % https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingConstants.html
jJSpinnerM.setComponentOrientation(java.awt.ComponentOrientation.RIGHT_TO_LEFT);

% Crazier demo: http://www.mathworks.com/matlabcentral/fileexchange/26970-spinnerdemo
end

function onSpinnerValueChanged(hObject, eventdata)
  disp(['Spinner value is now: ' num2str(hObject.Value)]);
end

@altmany
Copy link

altmany commented Nov 27, 2017

For the record, HG1 (R2014a and older) also supports dot-notation, if you simply ensure that all the relevant GUI/graphic handles are handle() objects rather than numeric. For example, the following code runs ok on HG1:

hFig = handle(gcf);  % trick to enable dot-notation on GUI/graphic objects
hFig.Color = 'w';
hFig.CloseRequestFcn = @myCallback;

The nice thing about this is that it's fully backward-compatible, meaning that hFig=handle(gcf) is transparent to HG2 and meaningful to HG1, so it can be used in Matlab code on both HG1 and HG2.

@sco1
Copy link
Member

sco1 commented Nov 27, 2017

Whoa, I didn't know that, very interesting! When I get some time this week I'll poke around and test out some changes. Haven't looked at this in a while...

@altmany
Copy link

altmany commented Nov 27, 2017

It actually even improves performance in some cases:
https://undocumentedmatlab.com/blog/performance-accessing-handle-properties

@altmany
Copy link

altmany commented Nov 28, 2017

Before you modify stuff, note that the @Dev-iL's fork is 11 commits ahead, so you might want to merge his fixes first before proceeding. I'm just mentioning it since both of you did these changes 2 years ago and probably forgot about it...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants