Mercurial > hg > ltpda
diff m-toolbox/m/gui/@jcontrol/jcontrol.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/m/gui/@jcontrol/jcontrol.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,235 @@ +function obj=jcontrol(Parent, Style, varargin) +% 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 + +if nargin==0 + % Default constructor + obj.hgcontrol=[]; + obj.hghandle=[]; + obj.hgcontainer=[]; + obj=class(orderfields(obj),'jcontrol'); + return +end + + +% Check parent +if ishandle(Parent) && Parent==0 + % Root given as Parent-create a new figure + container=figure('MenuBar','none'); +elseif strcmp(class(Parent),'jcontrol'); + % Parent is a jcontrol - use the hgcontainer + container=Parent.hgcontainer; +else + % Use as specified + container=Parent; +end + +% Check the Parent is a valid handle +if ishandle(container)==0 + error('Parent is not a valid handle (has the parent figure been closed?)'); +end + +% Java object +if ischar(Style) + % Create a default object + javaobject=javaObject(Style); +elseif isjava(Style) + % or use supplied object + javaobject=Style; +end + +% Check we have a valid Style +if isa(javaobject,'java.awt.Window') + error('%s is a top-level container: \n%s\n',... + Style, 'it can not have a MATLAB figure as parent/ancestor'); +end + +% If so, add callbacks and place in container +[obj.hgcontrol containerHandle]=javacomponent(javaobject,[],container); +% Put a copy of the container handle in obj.... +obj.hghandle=containerHandle; +% ... and in the control +s=schema.prop(obj.hgcontrol ,'hghandle','mxArray'); +obj.hgcontrol.hghandle=containerHandle; +s.AccessFlags.PublicSet='off'; + +% Put the container in obj +obj.hgcontainer = handle(containerHandle); + +% Construct the instance +obj=class(orderfields(obj),'jcontrol'); + +% Put a reference to the hgcontrol in the UserData area of the handle +set(containerHandle, 'UserData', obj.hgcontrol); + +% Set the properties and return +% Default to normalized +set(obj, 'Units','normalized'); +% Set values as requested +if ~isempty(varargin) + set(obj,varargin{:}); + return +end