JCONTROL constructor for JCONTROL class JCONTROL provides an easy way to integrate a full range of java GUIs from the java.awt and javax.swing libraries into MATLAB. Example: obj=JCONTROL(Parent, Style); obj=JCONTROL(Parent, Style, PropertyName1, PropertyValue1,... PropertyName2, ProeprtyValue2....); Inputs: Parent: the handle of a Matlab figure or other container for the resulting component Style: string describing a java component e.g. 'javax.swing.JPanel', 'javax.swing.JButton' or a variable containing a java object PropertName/PropertyValue pairs: these are automatically assigned to the HG container or the java component as appropriate. Pre-create the java object if you need to pass arguments to the constructor e.g. javaobj=javax.swing...(...............); obj=jcontrol(Parent, javaobj) By default, JCONTROLs are returned with Units set to 'normalized'. USE: Build a GUI with repeated calls to JCONTROL in much the same way as with MATLAB's uicontrol function e.g.: h=jcontrol(gcf,'javax.swing.JPanel',... 'Position',[100 100 200 150],... 'Units','normalized') h(2)=jcontrol(h(1),'javax.swing.JComboBox',... 'Position',[0.1 0.8 0.8 0.1]); h(2).addItem('Item1'); h(2).addItem('Item2'); h(3)=jcontrol(h(1),'javax.swing.JCheckBox',... 'Position',[0.1 0.1 0.1 0.1],... 'Label','My check box'); See the jcontrolDemo() for a fuller example. A JCONTROL aggregates the MATLAB handle graphics container and the Java component (as returned by MATLAB's JAVACOMPONENT function) into a single object. Access to the JCONTROL's properties is provided by GET/SET calls. These automatically determine whether the target property is in the HG container or java object. myobject=jcontrol(gcf,'javax.swing.JPanel',... 'Units', 'normalized',... 'Name', 'MyPanel'); set(myobject, 'Position', [0.4 0.4 0.4 0.2],... 'Enabled', 0); pos=get(myobject,'Units'); Note that you can mix HG container properties (e.g. Units, Position) and java component properties (e.g. Name, Enabled) in single calls to JCONTROL and SET. Use the HG container to control the Units, Position, and Visible properties MATLAB dot notation may also be used. This notation also provides access to the java object's methods pos=myobject.Position; sz=myObject.getSize; myobject.setEnabled(1); myobject.setToolTipText('My tip'); myobject.setOpaque(1); -------------------------------------------------------------------------- UNITS, POSITION and VISIBLE properties Set these by accessing the JCONTROL or its container (not the hgcontrol). MATLAB links these properties between the container and the java control, but unidirectionally. Note that JCONTROL methods always act on/return the Visible property of the container ('on' or 'off') which will also update the java control. Do not use the setVisible() methods. -------------------------------------------------------------------------- Overloaded class methods are case-insensitive for properties but case-sensitive for java methods CALLBACKS Setting up callbacks The simplest way to set up a callback is through the SET method myPanel=jcontrol(gcf,'javax.swing.JPanel',... 'Units','normalized',... 'Position',[0.3 0.3 0.5 0.5]); set(myPanel, 'MouseClickedCallback', 'MyCallback') or set(myPanel, 'MouseClickedCallback', @MyCallback); or set(myPanel ,'MouseClickedCallback', {@MyCallback A B C...}); The callback then takes the usual MATLAB form, e.g. function MyCallback(hObject, EventData) function MyCallback(hObject, EventData, varargin) Accessing JCONTROL objects in callbacks: The handle received by a callback will be that of the java control object contained in the JCONTROL, not the JCONTROL itself. In addition, GCO will return empty and GCBO will not return the parent figure handle. However, the JCONTROL constructor adds the HG container handle to the java component's properties. This can be used to access the container and its parent figure from within the callback e.g. get(hObject.hghandle);% gets the HG container ancestor(hObject.hghandle,'figure')% gets the parent figure handle To cross-reference from the container, JCONTROL places a reference to the java control in the container's UserData area e.g. hgc=findobj('Tag','MyCustomTag') javacontrol=get(hgc, 'UserData'); Accessing data in callbacks Data can be passed to a callback, as above, with optional input arguments. In addition, data that is specific to the control can be stored in the application data area of the control e.g. to return values dependent on the selection of a popup menu data=getappdata(hObject,'data'); returnvalues=data(hObject.getSelectedItem+1); Note: +1 because the item numbering is zero based for the java object. The HG container has a separate application data area. R2006a or higher only: GETAPPDATA, SETAPPDATA ISAPPDATA and RMAPPDATA methods have been overloaded for JCONTROL objects. These place/return data from the application data area of the java control. Take care if removing the whole application data area - TMW may place data in there too. The HG container has a separate application data area. Notes: If a property name occurs in both the HG container and the java object, the JCONTROL methods can not unambiguously identify the source/target and it must be defined explicitly by the user e.g. get(myobject.hgcontainer,'Opaque'); set(myobject.hgcontrol, 'Opaque',0); The JCONTROL methods test for ambiguity and issue an error message when it arises. Note that the test uses MATLAB's isprop and is case insensitive. It may also detect properties not listed by the MATLAB builtin GET function for the hgcontrol such as Visible. The JCONTROL methods always act on the Visible property of the hgcontainer, letting MATLAB update the object automatically (see above). The DeleteFcn property of the hgcontainer is set by the JAVACOMPONENT function. If this property is changed, the new callback must explicitly delete the hgcontrol. See also: jcontrol/get, jcontrol/set, jcontrol/subsasgn, jcontrol/subsref jcontrol/setappdata, jcontrol/getappdata, jcontrol/isappdata jcontrol/rmappdata, jcontrol/delete javacomponent, gco, gcbo -------------------------------------------------------------------------- Acknowledgements: The JCONTROL class was partly inspired by Yair Altman's <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=14583&objectType=file">uicomponent</a> function. The functions take different routes to achieve similar ends. JCONTROL is rather faster - which is significant when building complex GUIs, but UICOMPONENT accepts the same calling conventions as MATLAB's UICONTROL while JCONTROL does not. -------------------------------------------------------------------------- ------------------------------------------------------------------------- Author: Malcolm Lidierth 07/07 Copyright © The Author & King's College London 2007- ------------------------------------------------------------------------- Revisions: 12.09.07 Allow pre-contructed java objects on input
0001 function obj=jcontrol(Parent, Style, varargin) 0002 % JCONTROL constructor for JCONTROL class 0003 % 0004 % JCONTROL provides an easy way to integrate a full range of java GUIs 0005 % from the java.awt and javax.swing libraries into MATLAB. 0006 % 0007 % Example: 0008 % obj=JCONTROL(Parent, Style); 0009 % obj=JCONTROL(Parent, Style, PropertyName1, PropertyValue1,... 0010 % PropertyName2, ProeprtyValue2....); 0011 % Inputs: 0012 % Parent: the handle of a Matlab figure or other container for the resulting 0013 % component 0014 % Style: string describing a java component e.g. 'javax.swing.JPanel', 0015 % 'javax.swing.JButton' or a variable containing a java object 0016 % PropertName/PropertyValue pairs: these are automatically assigned to the 0017 % HG container or the java component as appropriate. 0018 % 0019 % Pre-create the java object if you need to pass arguments to the 0020 % constructor e.g. 0021 % javaobj=javax.swing...(...............); 0022 % obj=jcontrol(Parent, javaobj) 0023 % 0024 % By default, JCONTROLs are returned with Units set to 'normalized'. 0025 % 0026 % USE: 0027 % Build a GUI with repeated calls to JCONTROL in much the same way as with 0028 % MATLAB's uicontrol function e.g.: 0029 % h=jcontrol(gcf,'javax.swing.JPanel',... 0030 % 'Position',[100 100 200 150],... 0031 % 'Units','normalized') 0032 % h(2)=jcontrol(h(1),'javax.swing.JComboBox',... 0033 % 'Position',[0.1 0.8 0.8 0.1]); 0034 % h(2).addItem('Item1'); 0035 % h(2).addItem('Item2'); 0036 % h(3)=jcontrol(h(1),'javax.swing.JCheckBox',... 0037 % 'Position',[0.1 0.1 0.1 0.1],... 0038 % 'Label','My check box'); 0039 % See the jcontrolDemo() for a fuller example. 0040 % 0041 % A JCONTROL aggregates the MATLAB handle graphics container and the Java 0042 % component (as returned by MATLAB's JAVACOMPONENT function) into a single 0043 % object. 0044 % Access to the JCONTROL's properties is provided by GET/SET calls. 0045 % These automatically determine whether the target property is in 0046 % the HG container or java object. 0047 % myobject=jcontrol(gcf,'javax.swing.JPanel',... 0048 % 'Units', 'normalized',... 0049 % 'Name', 'MyPanel'); 0050 % set(myobject, 'Position', [0.4 0.4 0.4 0.2],... 0051 % 'Enabled', 0); 0052 % pos=get(myobject,'Units'); 0053 % Note that you can mix HG container properties (e.g. Units, Position) and 0054 % java component properties (e.g. Name, Enabled) in single calls to 0055 % JCONTROL and SET. 0056 % Use the HG container to control the Units, Position, and Visible 0057 % properties 0058 % 0059 % MATLAB dot notation may also be used. This notation also provides access 0060 % to the java object's methods 0061 % pos=myobject.Position; 0062 % sz=myObject.getSize; 0063 % myobject.setEnabled(1); 0064 % myobject.setToolTipText('My tip'); 0065 % myobject.setOpaque(1); 0066 % 0067 %-------------------------------------------------------------------------- 0068 % UNITS, POSITION and VISIBLE properties 0069 % Set these by accessing the JCONTROL or its container (not the hgcontrol). 0070 % MATLAB links these properties between the container and the java control, 0071 % but unidirectionally. 0072 % Note that JCONTROL methods always act on/return the Visible property of 0073 % the container ('on' or 'off') which will also update the java control. 0074 % Do not use the setVisible() methods. 0075 %-------------------------------------------------------------------------- 0076 % 0077 % Overloaded class methods are case-insensitive for properties but 0078 % case-sensitive for java methods 0079 % 0080 % CALLBACKS 0081 % Setting up callbacks 0082 % The simplest way to set up a callback is through the SET method 0083 % myPanel=jcontrol(gcf,'javax.swing.JPanel',... 0084 % 'Units','normalized',... 0085 % 'Position',[0.3 0.3 0.5 0.5]); 0086 % set(myPanel, 'MouseClickedCallback', 'MyCallback') 0087 % or 0088 % set(myPanel, 'MouseClickedCallback', @MyCallback); 0089 % or 0090 % set(myPanel ,'MouseClickedCallback', {@MyCallback A B C...}); 0091 % 0092 % The callback then takes the usual MATLAB form, e.g. 0093 % function MyCallback(hObject, EventData) 0094 % function MyCallback(hObject, EventData, varargin) 0095 % 0096 % Accessing JCONTROL objects in callbacks: 0097 % The handle received by a callback will be that of the java control 0098 % object contained in the JCONTROL, not the JCONTROL itself. In addition, 0099 % GCO will return empty and GCBO will not return the parent figure handle. 0100 % However, the JCONTROL constructor adds the HG container handle to the 0101 % java component's properties. This can be used to access the container and 0102 % its parent figure from within the callback e.g. 0103 % get(hObject.hghandle);% gets the HG container 0104 % ancestor(hObject.hghandle,'figure')% gets the parent figure handle 0105 % To cross-reference from the container, JCONTROL places a reference to 0106 % the java control in the container's UserData area e.g. 0107 % hgc=findobj('Tag','MyCustomTag') 0108 % javacontrol=get(hgc, 'UserData'); 0109 % 0110 % Accessing data in callbacks 0111 % Data can be passed to a callback, as above, with optional input 0112 % arguments. In addition, data that is specific to the control can be stored 0113 % in the application data area of the control e.g. to return values 0114 % dependent on the selection of a popup menu 0115 % data=getappdata(hObject,'data'); 0116 % returnvalues=data(hObject.getSelectedItem+1); 0117 % Note: +1 because the item numbering is zero based for the java object. 0118 % The HG container has a separate application data area. 0119 % 0120 % R2006a or higher only: 0121 % GETAPPDATA, SETAPPDATA ISAPPDATA and RMAPPDATA methods have been 0122 % overloaded for JCONTROL objects. These place/return data from the 0123 % application data area of the java control. Take care if removing the whole 0124 % application data area - TMW may place data in there too. The HG container 0125 % has a separate application data area. 0126 % 0127 % Notes: 0128 % If a property name occurs in both the HG container and the java object, 0129 % the JCONTROL methods can not unambiguously identify the source/target 0130 % and it must be defined explicitly by the user e.g. 0131 % get(myobject.hgcontainer,'Opaque'); 0132 % set(myobject.hgcontrol, 'Opaque',0); 0133 % The JCONTROL methods test for ambiguity and issue an error message when 0134 % it arises. Note that the test uses MATLAB's isprop and is case 0135 % insensitive. 0136 % It may also detect properties not listed by the MATLAB builtin GET 0137 % function for the hgcontrol such as Visible. The JCONTROL methods always 0138 % act on the Visible property of the hgcontainer, letting MATLAB update the 0139 % object automatically (see above). 0140 % 0141 % The DeleteFcn property of the hgcontainer is set by the JAVACOMPONENT 0142 % function. If this property is changed, the new callback must explicitly 0143 % delete the hgcontrol. 0144 % 0145 % See also: 0146 % jcontrol/get, jcontrol/set, jcontrol/subsasgn, jcontrol/subsref 0147 % jcontrol/setappdata, jcontrol/getappdata, jcontrol/isappdata 0148 % jcontrol/rmappdata, jcontrol/delete 0149 % javacomponent, gco, gcbo 0150 % 0151 %-------------------------------------------------------------------------- 0152 % Acknowledgements: The JCONTROL class was partly inspired by Yair Altman's 0153 % <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=14583&objectType=file">uicomponent</a> function. 0154 % The functions take different routes to achieve similar ends. JCONTROL is rather 0155 % faster - which is significant when building complex GUIs, but UICOMPONENT 0156 % accepts the same calling conventions as MATLAB's UICONTROL while JCONTROL 0157 % does not. 0158 %-------------------------------------------------------------------------- 0159 % 0160 % ------------------------------------------------------------------------- 0161 % Author: Malcolm Lidierth 07/07 0162 % Copyright © The Author & King's College London 2007- 0163 % ------------------------------------------------------------------------- 0164 % 0165 % Revisions: 0166 % 12.09.07 Allow pre-contructed java objects on input 0167 0168 if nargin==0 0169 % Default constructor 0170 obj.hgcontrol=[]; 0171 obj.hghandle=[]; 0172 obj.hgcontainer=[]; 0173 obj=class(orderfields(obj),'jcontrol'); 0174 return 0175 end 0176 0177 0178 % Check parent 0179 if ishandle(Parent) && Parent==0 0180 % Root given as Parent-create a new figure 0181 container=figure('MenuBar','none'); 0182 elseif strcmp(class(Parent),'jcontrol'); 0183 % Parent is a jcontrol - use the hgcontainer 0184 container=Parent.hgcontainer; 0185 else 0186 % Use as specified 0187 container=Parent; 0188 end 0189 0190 % Check the Parent is a valid handle 0191 if ishandle(container)==0 0192 error('Parent is not a valid handle (has the parent figure been closed?)'); 0193 end 0194 0195 % Java object 0196 if ischar(Style) 0197 % Create a default object 0198 javaobject=javaObject(Style); 0199 elseif isjava(Style) 0200 % or use supplied object 0201 javaobject=Style; 0202 end 0203 0204 % Check we have a valid Style 0205 if isa(javaobject,'java.awt.Window') 0206 error('%s is a top-level container: \n%s\n',... 0207 Style, 'it can not have a MATLAB figure as parent/ancestor'); 0208 end 0209 0210 % If so, add callbacks and place in container 0211 [obj.hgcontrol containerHandle]=javacomponent(javaobject,[],container); 0212 % Put a copy of the container handle in obj.... 0213 obj.hghandle=containerHandle; 0214 % ... and in the control 0215 s=schema.prop(obj.hgcontrol ,'hghandle','mxArray'); 0216 obj.hgcontrol.hghandle=containerHandle; 0217 s.AccessFlags.PublicSet='off'; 0218 0219 % Put the container in obj 0220 obj.hgcontainer = handle(containerHandle); 0221 0222 % Construct the instance 0223 obj=class(orderfields(obj),'jcontrol'); 0224 0225 % Put a reference to the hgcontrol in the UserData area of the handle 0226 set(containerHandle, 'UserData', obj.hgcontrol); 0227 0228 % Set the properties and return 0229 % Default to normalized 0230 set(obj, 'Units','normalized'); 0231 % Set values as requested 0232 if ~isempty(varargin) 0233 set(obj,varargin{:}); 0234 return 0235 end