Home > functions > gui > batch > batch_variable_table > createTable.m

createTable

PURPOSE ^

createTable - create nice-looking table based on javax.swing.JTable

SYNOPSIS ^

function [mtable, buttons] = createTable(pnContainer,headers,data,buttonsFlag,varargin)

DESCRIPTION ^

 createTable - create nice-looking table based on javax.swing.JTable

 Syntax:
    [mtable, buttons] = createTable (pnContainer, headers, data, buttonsFlag, 'PropName',PropValue, ...)

 Input Parameters:
    pnContainer - optional handle to container uipanel or figure. If empty/unsupplied then current figure will be used
    headers     - optional cell array of column header strings. If unsupplied then = {'A','B','C'}
    data        - optional vector/matrix (either scalar or cell array) of data values
    buttonsFlag - optional flag indicating whether to create the table-manipulation buttons. Default = true
    'PropName',PropValue - 
                  optional list of property pairs (e.g., 'AutoResizeMode',4,'Editable',false,'Position',[.1,.1,.5,.5])
                  Note: PropName must be either an mtable property ('Visible','Editable','Position','Units',
                        'DataChangedCallback',...) or otherwise a Javax.swing.JTable property ('ShowGrid','Name',...).
                        Abbreviated PropNames are unsupported for mtable properties (which are few) - only for JTable

 Output parameters:
    mtable      - handle to mtable object (a Matlab object)
    buttons     - handles to table manipulation buttons: [<appendRow> <insertRow> <deleteRow> <deleteAll> <printAll>]

 Examples:
    [mtable, buttons] = createTable;
    [mtable, buttons] = createTable(gcf,'column name');
    mtable = createTable([],{'a','b','c','d'},{false,1.3,uint16(45),'ert'; true,pi,uint16(-4),'defrgt'})
    mtable = createTable([],{'a','b','c','d'},magic(4),false,'AutoResizeMode',javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS)
    mtable = createTable([],{'rads','sin','cos'},[pi,sin(pi),cos(pi)],'SelectionMode',javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION)

 Usage:
    The table automatically resizes to fill the pnContainer (you may modify this via the 'Position' property).
    The table automatically sets the columns' cell editor and renderer based on the supplied data. Logical values are
       given a checkbox, strings are left-aligned (numbers are right-aligned). You can always override the defaults.
    You can change column widths by dragging the column borders on the header row.
    You can sort columns by clicking the column header (once to sort descending, once again to sort ascending and once
       more for the unsorted view). Sorting multiple columns is done by control-clicking all relevant columns (the
       sorting icon is decreased in size for each additional minor sort col).
    You can copy/paste any consecutive region of table cells, just as in Excel. You can select entire rows or columns
       by right-clicking their header. You can also paste Excel data directly, with Ctrl-Shift-V (or use the context
       menu by right-clicking) at the target table cell.
    For additional tips about how to set multiple aspects of the table, refer to:
       <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/table.html">http://java.sun.com/docs/books/tutorial/uiswing/components/table.html</a>

 Programming tips/cues/examples:
    mtable = creatTable(...)
    jtable = mtable.getTable;
    mtable.setVisible(false);
    mtable.setCheckBoxEditor(1);  % Set first column to a checkbox (see Note 2 below)
    cb = javax.swing.JComboBox({'First','Last'}); cb.setEditable(true);  % prepare an editable drop-down CellEditor
    editor = javax.swing.DefaultCellEditor(cb);
    jtable.getColumnModel.getColumn(1).setCellEditor(editor);  % assign this editor to second column (see Note 2)
    jtable.getColumnModel.getColumn(0).setMaxWidth(20);  % Limit width of first (checkbox) column (see Note 2)
    mtable.setEditable(0,false);  % Disable editing first column (see note 2 below)
    renderer = javax.swing.table.DefaultTableCellRenderer;  % or: renderer = jtable.getColumnModel.getColumn(1).getCellRenderer
    renderer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);  % useful for numbers rendered as strings e.g.: jtable.setValueAt(sprintf('%.1f',pi,rowIdx,colIdx))
    jtable.getColumnModel.getColumn(1).setCellRenderer(renderer);  % right-align second column (see note 2)
    data = cell(mtable.getData);  % a cell matrix (mtable.getData is a java.lang.Object[][] object, using base-1 indexing)
    data = mtable.getTableModel.getDataVector;  % a java.util.Vector object ([[false, 1.3, 45, ert], [true, 3.14,...]])
    jtable.setValueAt(value,rowIdx,colIdx);  % 0-based Idx - see Note 2 below
    jtable.getModel.addRow({true, pi, int16(45), 'test'});  % appends a row to the bottom of the table
    mtable.DataChangedCallback = [];  % used to temporarily disable data-change callbacks
    mtable.DataChangedCallback = @myDataChange_Callback;  % myDataChange_Callback is a Matlab function

    % Sample dataChange_Callback function
    function dataChange_Callback(mtable, eventdata)
       if ~ishandle(mtable),  return;  end
          % Prevent re-entry here if the callback is not thread-safe - see Note 3 below
       eventDetails = eventdata.getEvent;
       modifiedColIdx = eventDetails.getColumn;
       modifiedRowIdx = eventDetails.getFirstRow;
       if modifiedColIdx>=0 && modifiedRowIdx>=0
          data = mtable.getData;
          newValue = data(modifiedRowIdx+1,modifiedColIdx+1);  % see Note 2 below
          switch modifiedColIdx
            case ...
          end
       end

 Notes:
    1. Some (very few) JTable features are inconsistent or unavailable in different jave versions. Type 
       '<a href="matlab:version -java">version -java</a>' at the command prompt to see your specific java version.
    2. Note that java uses 0-based indexing, while Matlab is 1-based. The returned mtable parameter is a Matlab object
       (so use 1-base), while mtable.getXXX returns java objects (0-based). jtable above is an example of a java object.
    3. Modifying mtable.DataChangedCallback within the callback doesn't work - you need to use some global flag/mutex
    4. The <Print> button uses Excel to parse and print the table
    5. Due to Matlab limitations (specifically, of uitable/UitablePeer) the table is created as a direct child of
       the container figure (although it is visually positioned within pnContainer)
    6. To enable sorting functionality, the attached TableSorter.jar file must be located in the java classpath.
       See the Matlab documentation for <a href="matlab:doc javaclasspath">javaclasspath</a>. Note that using 
       javaaddpath(...) to set the path has a nasty side-effect (at least since Matlab 7.2) of clearing all globals!
       An alternative is to place the pathname for TableSorter.jar in the <a href="matlab:which classpath.txt">classpath.txt</a> file

 Known issues/limitations:
    - Column alignment not preserved during Print
    - Print fails if Excel unavailable (maybe directly print tab-separated text data)
    - Unable to add/delete rows or to print via context menu (right-click)
    - Table is created as a direct child of figure, not pnContainer (see Note 5 above)

 Bugs and suggestions:
    Please send to Yair Altman (altmany at gmail dot com)

 See also:
    uitable, java, javaclasspath

 Release history:
    1.0 2007-03-09: initial version
    1.1 2007-03-22: fixed selected row# on deletion of bottom row, main comment, missing option; added header tooltip

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [mtable, buttons] = createTable(pnContainer,headers,data,buttonsFlag,varargin)
0002 % createTable - create nice-looking table based on javax.swing.JTable
0003 %
0004 % Syntax:
0005 %    [mtable, buttons] = createTable (pnContainer, headers, data, buttonsFlag, 'PropName',PropValue, ...)
0006 %
0007 % Input Parameters:
0008 %    pnContainer - optional handle to container uipanel or figure. If empty/unsupplied then current figure will be used
0009 %    headers     - optional cell array of column header strings. If unsupplied then = {'A','B','C'}
0010 %    data        - optional vector/matrix (either scalar or cell array) of data values
0011 %    buttonsFlag - optional flag indicating whether to create the table-manipulation buttons. Default = true
0012 %    'PropName',PropValue -
0013 %                  optional list of property pairs (e.g., 'AutoResizeMode',4,'Editable',false,'Position',[.1,.1,.5,.5])
0014 %                  Note: PropName must be either an mtable property ('Visible','Editable','Position','Units',
0015 %                        'DataChangedCallback',...) or otherwise a Javax.swing.JTable property ('ShowGrid','Name',...).
0016 %                        Abbreviated PropNames are unsupported for mtable properties (which are few) - only for JTable
0017 %
0018 % Output parameters:
0019 %    mtable      - handle to mtable object (a Matlab object)
0020 %    buttons     - handles to table manipulation buttons: [<appendRow> <insertRow> <deleteRow> <deleteAll> <printAll>]
0021 %
0022 % Examples:
0023 %    [mtable, buttons] = createTable;
0024 %    [mtable, buttons] = createTable(gcf,'column name');
0025 %    mtable = createTable([],{'a','b','c','d'},{false,1.3,uint16(45),'ert'; true,pi,uint16(-4),'defrgt'})
0026 %    mtable = createTable([],{'a','b','c','d'},magic(4),false,'AutoResizeMode',javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS)
0027 %    mtable = createTable([],{'rads','sin','cos'},[pi,sin(pi),cos(pi)],'SelectionMode',javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION)
0028 %
0029 % Usage:
0030 %    The table automatically resizes to fill the pnContainer (you may modify this via the 'Position' property).
0031 %    The table automatically sets the columns' cell editor and renderer based on the supplied data. Logical values are
0032 %       given a checkbox, strings are left-aligned (numbers are right-aligned). You can always override the defaults.
0033 %    You can change column widths by dragging the column borders on the header row.
0034 %    You can sort columns by clicking the column header (once to sort descending, once again to sort ascending and once
0035 %       more for the unsorted view). Sorting multiple columns is done by control-clicking all relevant columns (the
0036 %       sorting icon is decreased in size for each additional minor sort col).
0037 %    You can copy/paste any consecutive region of table cells, just as in Excel. You can select entire rows or columns
0038 %       by right-clicking their header. You can also paste Excel data directly, with Ctrl-Shift-V (or use the context
0039 %       menu by right-clicking) at the target table cell.
0040 %    For additional tips about how to set multiple aspects of the table, refer to:
0041 %       <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/table.html">http://java.sun.com/docs/books/tutorial/uiswing/components/table.html</a>
0042 %
0043 % Programming tips/cues/examples:
0044 %    mtable = creatTable(...)
0045 %    jtable = mtable.getTable;
0046 %    mtable.setVisible(false);
0047 %    mtable.setCheckBoxEditor(1);  % Set first column to a checkbox (see Note 2 below)
0048 %    cb = javax.swing.JComboBox({'First','Last'}); cb.setEditable(true);  % prepare an editable drop-down CellEditor
0049 %    editor = javax.swing.DefaultCellEditor(cb);
0050 %    jtable.getColumnModel.getColumn(1).setCellEditor(editor);  % assign this editor to second column (see Note 2)
0051 %    jtable.getColumnModel.getColumn(0).setMaxWidth(20);  % Limit width of first (checkbox) column (see Note 2)
0052 %    mtable.setEditable(0,false);  % Disable editing first column (see note 2 below)
0053 %    renderer = javax.swing.table.DefaultTableCellRenderer;  % or: renderer = jtable.getColumnModel.getColumn(1).getCellRenderer
0054 %    renderer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);  % useful for numbers rendered as strings e.g.: jtable.setValueAt(sprintf('%.1f',pi,rowIdx,colIdx))
0055 %    jtable.getColumnModel.getColumn(1).setCellRenderer(renderer);  % right-align second column (see note 2)
0056 %    data = cell(mtable.getData);  % a cell matrix (mtable.getData is a java.lang.Object[][] object, using base-1 indexing)
0057 %    data = mtable.getTableModel.getDataVector;  % a java.util.Vector object ([[false, 1.3, 45, ert], [true, 3.14,...]])
0058 %    jtable.setValueAt(value,rowIdx,colIdx);  % 0-based Idx - see Note 2 below
0059 %    jtable.getModel.addRow({true, pi, int16(45), 'test'});  % appends a row to the bottom of the table
0060 %    mtable.DataChangedCallback = [];  % used to temporarily disable data-change callbacks
0061 %    mtable.DataChangedCallback = @myDataChange_Callback;  % myDataChange_Callback is a Matlab function
0062 %
0063 %    % Sample dataChange_Callback function
0064 %    function dataChange_Callback(mtable, eventdata)
0065 %       if ~ishandle(mtable),  return;  end
0066 %          % Prevent re-entry here if the callback is not thread-safe - see Note 3 below
0067 %       eventDetails = eventdata.getEvent;
0068 %       modifiedColIdx = eventDetails.getColumn;
0069 %       modifiedRowIdx = eventDetails.getFirstRow;
0070 %       if modifiedColIdx>=0 && modifiedRowIdx>=0
0071 %          data = mtable.getData;
0072 %          newValue = data(modifiedRowIdx+1,modifiedColIdx+1);  % see Note 2 below
0073 %          switch modifiedColIdx
0074 %            case ...
0075 %          end
0076 %       end
0077 %
0078 % Notes:
0079 %    1. Some (very few) JTable features are inconsistent or unavailable in different jave versions. Type
0080 %       '<a href="matlab:version -java">version -java</a>' at the command prompt to see your specific java version.
0081 %    2. Note that java uses 0-based indexing, while Matlab is 1-based. The returned mtable parameter is a Matlab object
0082 %       (so use 1-base), while mtable.getXXX returns java objects (0-based). jtable above is an example of a java object.
0083 %    3. Modifying mtable.DataChangedCallback within the callback doesn't work - you need to use some global flag/mutex
0084 %    4. The <Print> button uses Excel to parse and print the table
0085 %    5. Due to Matlab limitations (specifically, of uitable/UitablePeer) the table is created as a direct child of
0086 %       the container figure (although it is visually positioned within pnContainer)
0087 %    6. To enable sorting functionality, the attached TableSorter.jar file must be located in the java classpath.
0088 %       See the Matlab documentation for <a href="matlab:doc javaclasspath">javaclasspath</a>. Note that using
0089 %       javaaddpath(...) to set the path has a nasty side-effect (at least since Matlab 7.2) of clearing all globals!
0090 %       An alternative is to place the pathname for TableSorter.jar in the <a href="matlab:which classpath.txt">classpath.txt</a> file
0091 %
0092 % Known issues/limitations:
0093 %    - Column alignment not preserved during Print
0094 %    - Print fails if Excel unavailable (maybe directly print tab-separated text data)
0095 %    - Unable to add/delete rows or to print via context menu (right-click)
0096 %    - Table is created as a direct child of figure, not pnContainer (see Note 5 above)
0097 %
0098 % Bugs and suggestions:
0099 %    Please send to Yair Altman (altmany at gmail dot com)
0100 %
0101 % See also:
0102 %    uitable, java, javaclasspath
0103 %
0104 % Release history:
0105 %    1.0 2007-03-09: initial version
0106 %    1.1 2007-03-22: fixed selected row# on deletion of bottom row, main comment, missing option; added header tooltip
0107 
0108 % License to use and modify this code is granted freely to all interested, as long as the original author is
0109 % referenced and attributed as such. The original author maintains the right to be solely associated with this work.
0110 
0111 % Programmed and Copyright by Yair M. Altman: altmany(at)gmail.com
0112 % $Revision: 1.1 $  $Date: 2007/03/20 09:50:49 $
0113 import javax.swing.* java.awt.*;
0114 
0115 
0116 javaFont = javaObject('javax.swing.plaf.FontUIResource','Tahoma', 0, 18);
0117 
0118 %try
0119       % Ensure that java swing is enabled...
0120       if ~usejava('swing')
0121           error('createTable:NeedSwing','Java tables require Java Swing.');
0122       end
0123 
0124       % Create a panel spanning entire figure area, if panel handle was not supplied
0125       if (nargin < 1) || isempty(pnContainer) || ~ishandle(pnContainer)
0126           pnContainer = uipanel('parent',gcf,'tag','TablePanel');
0127       end
0128       pnContainerPos = getpixelposition(pnContainer,1);
0129       if isa(handle(pnContainer), 'figure')
0130           pnContainerPos(1:2) = 0;
0131       end
0132 
0133       % Get handle to parent figure
0134       hFig = ancestor(pnContainer,'figure');
0135 
0136       % Determine whether table manipulation buttons are requested
0137       if nargin < 4 || isempty(buttonsFlag) || ~(isnumeric(buttonsFlag) || islogical(buttonsFlag))
0138           if nargin >= 4,  varargin = {buttonsFlag, varargin{:}};  end
0139           buttonsFlag = true;
0140       end
0141       if buttonsFlag
0142           margins = [1,30,0,-30];  % With buttons
0143       else
0144           margins = [1,1,0,0];   % No buttons
0145       end
0146 
0147       % Get the uitable's required position within pnContainer
0148       tablePosition = pnContainerPos + margins;    % Relative to the figure
0149 
0150       % Set default header names, if not supplied
0151       if nargin < 2
0152           headers = {'A','B','C'};  % 3 columns by default
0153       elseif isempty(headers)
0154           headers = {' '};
0155       elseif ischar(headers)
0156           headers = {headers};
0157       end
0158 
0159       % Start with dummy data, just so that uitable can be initialized (or use supplied data, if available)
0160       if nargin < 3 || isempty(data)
0161           numRows = 0;
0162           numCols = length(headers);
0163           data = zeros(1,numCols);
0164       else
0165           numRows = size(data,1);
0166           numCols = size(data,2);
0167       end
0168       % Convert to cell-format (if not so already)
0169       if ~iscell(data)
0170           data = mat2cell(data,ones(1,size(data,1)),ones(1,numCols));
0171       end
0172 
0173       % Create a sortable uitable within pnHandle
0174       if vb_matlab_version('>=', '7.6')
0175           mtable = uitable('v0', hFig, 'position',tablePosition, 'Data',data, 'ColumnNames',headers);
0176       else
0177           mtable = uitable(hFig, 'position',tablePosition, 'Data',data, 'ColumnNames',headers);
0178       end
0179       mtable.setNumRows(numRows);
0180       set(mtable,'units','normalized');  % this will resize the table whenever its container is resized
0181 
0182       % jtable is the underlying java JTable - access to lots more functionality...
0183       % Note: actually, jtable is a com.mathworks.hg.peer.UitablePeer$PeerSpreadsheetTable object, but this extends
0184       % ^^^^  javax.swing.JTable, so for all practical purposes you may use it as a JTable
0185       jtable = mtable.getTable;
0186       jtable.setFont(javaFont);
0187       hdr = jtable.getTableHeader;
0188       hdr.setFont(javaFont)
0189 
0190       % Auto adjust column width
0191       fm = jtable.getFontMetrics(jtable.getFont);
0192        for k=1:size(data,2)
0193            width_max = 0;
0194            for j=1:jtable.getRowCount
0195                w = javax.swing.SwingUtilities.computeStringWidth(fm, jtable.getValueAt(j-1,k-1));
0196                if width_max < w
0197                    width_max = w;
0198                end
0199            end
0200            if width_max < 90
0201                width_max = 90;
0202            end
0203            jtable.getColumnModel.getColumn(k-1).setPreferredWidth(width_max + 10);
0204        end
0205       
0206       % Fix for JTable focus bug : see http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4709394
0207       % Taken from: http://xtargets.com/snippets/posts/show/37
0208       jtable.putClientProperty('terminateEditOnFocusLost', java.lang.Boolean.TRUE);
0209 
0210       % We want to use sorter, not data model...
0211       % unfortunately, UitablePeer expects DefaultTableModel (not TableSorter) so we need a modified UitablePeer class
0212       % however, UitablePeer is a Matlab class, so instead let's use a modified TableSorter and attach it to the Model
0213       %sorter = com.mathworks.toolbox.dasstudio.util.TableSorter;  % Failed attempt...
0214       %sorter = com.mathworks.mwswing.DefaultSortableTable;        % ...another failed attempt...
0215       if ~isempty(which('TableSorter'))
0216           % Add TableSorter as TableModel listener
0217           sorter = TableSorter(jtable.getModel);  %(table.getTableModel);
0218           %tablePeer = UitablePeer(sorter);  % This is not accepted by UitablePeer... - see comment above
0219           jtable.setModel(sorter);
0220           sorter.setTableHeader(jtable.getTableHeader);
0221 
0222           % Set the header tooltip (with sorting instructions)
0223           jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to sort up; <b>Shift-click</b> to sort down<br>&nbsp;<b>Ctrl-click</b> (or <b>Ctrl-Shift-click</b>) to sort secondary&nbsp;<br>&nbsp;<b>Click again</b> to change sort direction<br>&nbsp;<b>Click a third time</b> to return to unsorted view<br>&nbsp;<b>Right-click</b> to select entire column</html>');
0224       else
0225           % Set the header tooltip (no sorting instructions...)
0226           jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to select entire column<br>&nbsp;<b>Ctrl-click</b> (or <b>Shift-click</b>) to select multiple columns&nbsp;</html>');
0227       end
0228 
0229       % Store the uitable's handle within the pnContainer's userdata, for later use
0230       set(pnContainer,'userdata',[get(pnContainer,'userdata'), mtable]);  % add to parent userdata, so we have a handle for deletion
0231 
0232       % Enable multiple row selection, auto-column resize, and auto-scrollbars
0233       scroll = mtable.TableScrollPane;
0234       scroll.setVerticalScrollBarPolicy(scroll.VERTICAL_SCROLLBAR_AS_NEEDED);
0235       scroll.setHorizontalScrollBarPolicy(scroll.HORIZONTAL_SCROLLBAR_AS_NEEDED);
0236       jtable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0237 %      jtable.setAutoResizeMode(jtable.AUTO_RESIZE_SUBSEQUENT_COLUMNS)
0238 %      jtable.setAutoResizeMode(jtable.AUTO_RESIZE_OFF)
0239       jtable.setAutoResizeMode(jtable.AUTO_RESIZE_OFF);
0240 
0241       % Set the jtable name based on the containing panel's tag
0242       basicTagName = get(pnContainer,'tag');
0243       jtable.setName([basicTagName 'Table']);
0244 
0245       % Move the selection to first table cell (if any data available)
0246       if (jtable.getRowCount > 0)
0247           jtable.changeSelection(0,0,false,false);
0248       end
0249 
0250       % Process optional args
0251       for argIdx = 1 : 2 : length(varargin)
0252           if argIdx<2
0253               % We need this pause to let java complete all table rendering
0254               % TODO: We should really use calls to awtinvoke() instead, though...
0255               pause(0.05);
0256           end
0257           if (length(varargin) > argIdx)   % ensure the arg value is there...
0258               varargin{argIdx}(1) = upper(varargin{argIdx}(1));  % property names always start with capital letters...
0259               propMethodName = ['set' varargin{argIdx}];
0260               if ismethod(mtable,propMethodName)
0261                   set(mtable,varargin{argIdx},varargin{argIdx+1});
0262               else
0263                   %javaMethod(propMethodName, jtable, varargin{argIdx+1});
0264                   set(jtable,varargin{argIdx},varargin{argIdx+1});
0265               end
0266           end
0267       end  % for argIdx
0268 
0269       % Create table manipulation buttons
0270       if buttonsFlag
0271           buttons = createManipulationButtons(pnContainer,mtable);
0272       else
0273           buttons = [];
0274       end
0275   %catch
0276       % Insert your code here
0277       %handleError;
0278   %end
0279 
0280 
0281 %% --- Executes on button press in btInsert.
0282 function buttons = createManipulationButtons(pnContainer, mtable)
0283 % pnContainer  handle to container uipanel
0284 % mtable       handle to mtable (Matlab) object
0285   %try
0286       btAppendRow = uicontrol('tag','btTableAppendRow', 'callback',@btTableAppendRow_Callback, 'position',  [10,5,60,20], 'string','Append',     'parent',pnContainer, 'userdata',mtable);
0287       btInsertRow = uicontrol('tag','btTableInsertRow', 'callback',@btTableInsertRow_Callback, 'position',  [80,5,60,20], 'string','Insert',     'parent',pnContainer, 'userdata',mtable);
0288       btDeleteRow = uicontrol('tag','btTableDeleteRow', 'callback',@btTableDeleteRow_Callback, 'position', [150,5,60,20], 'string','Delete',     'parent',pnContainer, 'userdata',mtable);
0289       btDeleteAll = uicontrol('tag','btTableDeleteAll', 'callback',@btTableDeleteAll_Callback, 'position', [220,5,60,20], 'string','Delete All', 'parent',pnContainer, 'userdata',mtable);
0290       btPrintAll  = uicontrol('tag','btTablePrintAll',  'callback',@btTablePrintAll_Callback,  'position', [290,5,60,20], 'string','Print',      'parent',pnContainer, 'userdata',mtable);
0291       buttons = [btInsertRow btAppendRow btDeleteRow btDeleteAll btPrintAll];
0292       if mtable.getNumRows < 1
0293           setVisibility(pnContainer, 'off');
0294       end
0295   %catch
0296       % Insert your code here
0297       %handleError;
0298   %end
0299 
0300 
0301 %% --- Executes on button press in btInsert.
0302 % Insert a new row immediately before the current row
0303 function btTableInsertRow_Callback(hObject, eventdata, handles)  %#ok
0304 % hObject    handle to btTableInsertRow (see GCBO)
0305 % eventdata  reserved - to be defined in a future version of MATLAB
0306 % handles    structure with handles and user data (see GUIDATA)
0307   %try
0308       mtable = get(hObject,'userdata');
0309       jtable = mtable.getTable;
0310 
0311       % Stop any current editing
0312       stopEditing(jtable);
0313 
0314       % Insert the new row immediately before the current row
0315       newRowData = cell(1,mtable.getNumColumns);  % empty data
0316       mtable.getTableModel.insertRow(max(0,jtable.getSelectedRow), newRowData);
0317   %catch
0318       % Insert your code here
0319       %handleError;
0320   %end
0321 
0322 
0323 %% --- Executes on button press in btAppend.
0324 % Insert a new row as the last row in the table
0325 function btTableAppendRow_Callback(hObject, eventdata, handles)  %#ok
0326 % hObject    handle to btTableAppendRow (see GCBO)
0327 % eventdata  reserved - to be defined in a future version of MATLAB
0328 % handles    structure with handles and user data (see GUIDATA)
0329   %try
0330       mtable = get(hObject,'userdata');
0331       jtable = mtable.getTable;
0332 
0333       % Stop any current editing
0334       stopEditing(jtable);
0335 
0336       % Add a new row at the bottom of the data table
0337       newRowData = cell(1,mtable.getNumColumns);  % empty data
0338       mtable.getTableModel.addRow(newRowData);
0339 
0340       % Move the selection to Column A of this new row
0341       jtable.changeSelection(jtable.getRowCount-1,0,false,false);
0342 
0343       % There must be at least one table row now, so display the table in any case
0344       mtable.setVisible(true);
0345       setVisibility(hObject, 'on');
0346   %catch
0347       % Insert your code here
0348       %handleError;
0349   %end
0350 
0351 
0352 %% --- Executes on button press in btDelete.
0353 % If there are any rows displayed, then delete the currently-selected row
0354 function btTableDeleteRow_Callback(hObject, eventdata, handles)  %#ok
0355 % hObject    handle to btTableDeleteRow (see GCBO)
0356 % eventdata  reserved - to be defined in a future version of MATLAB
0357 % handles    structure with handles and user data (see GUIDATA)
0358   %try
0359       mtable = get(hObject,'userdata');
0360       jtable = mtable.getTable;
0361 
0362       % Stop any current editing
0363       stopEditing(jtable);
0364 
0365       % If there are any rows displayed, then delete the currently-selected row
0366       rowCount = jtable.getRowCount;
0367       if (rowCount > 0)  % might be==0 during slow processing & user double-click
0368           currentRow = max(0,jtable.getSelectedRow);
0369           currentCol = max(0,jtable.getSelectedColumn);
0370           mtable.getTableModel.removeRow(currentRow);
0371           if currentRow >= rowCount-1
0372               jtable.changeSelection(currentRow-1, currentCol, false, false);
0373           end
0374       end
0375       if (jtable.getRowCount <= 0)
0376           %table.setVisible(false);
0377           setVisibility(hObject, 'off');
0378       end
0379   %catch
0380       % Insert your code here
0381       %handleError;
0382   %end
0383 
0384 
0385 %% --- Executes on button press in btDeleteAll.
0386 % Deletes all table rows
0387 function btTableDeleteAll_Callback(hObject, eventdata, handles)  %#ok
0388 % hObject    handle to btTableDeleteAll (see GCBO)
0389 % eventdata  reserved - to be defined in a future version of MATLAB
0390 % handles    structure with handles and user data (see GUIDATA)
0391   %try
0392       mtable = get(hObject,'userdata');
0393       jtable = mtable.getTable;
0394 
0395       % Stop any current editing
0396       stopEditing(jtable);
0397 
0398       % Delete all table rows
0399       mtable.setNumRows(0);
0400 
0401       % Hide irrelevant controls
0402       %mtable.setVisible(false);
0403       setVisibility(hObject, 'off');
0404   %catch
0405       % Insert your code here
0406       %handleError;
0407   %end
0408 
0409 
0410 %% --- Executes on button press in btPrint.
0411 % Prints the table via Excel
0412 function btTablePrintAll_Callback(hObject, eventdata, handles)  %#ok
0413 % hObject    handle to btTablePrintAll (see GCBO)
0414 % eventdata  reserved - to be defined in a future version of MATLAB
0415 % handles    structure with handles and user data (see GUIDATA)
0416   persistent hExcel
0417   try
0418       mtable = get(hObject,'userdata');
0419 
0420       % Try to open an Excel COM server
0421       % Note: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_2003_ta/html/odc_landoffice03_vba.asp
0422       try
0423           % try to reuse an existing (pre-opened) COM server
0424           % If we can't access the ActiveX parent, it means it's closed
0425           parent = hExcel.parent;  %#ok
0426       catch
0427           hExcel = actxserver('excel.application');
0428       end
0429 
0430       % Try to open the requested document
0431       hExcel.Workbooks.Add;
0432 
0433       % Format field headers
0434       headers = cell(mtable.getColumnNames)';
0435       if ~isempty(headers)
0436           hExcel.Range(['A1:' n2a(length(headers)) '1']).Select;
0437           hExcel.Selection.Value = headers;
0438           hExcel.Selection.Font.Bold = true;                   % bold
0439           hExcel.Selection.Font.Color = hex2dec('0000FF');     % Red
0440           hExcel.Selection.Border.Item(4).Weight = 3;          % underline
0441           hExcel.Selection.Cells.HorizontalAlignment = -4108;  % =xlCenter
0442       end
0443 
0444       % Set the data from the table
0445       data = cell(mtable.data);
0446       if ~isempty(headers)
0447           hExcel.Range(['A2:' n2a(size(data,2)) num2str(1+size(data,1))]).Select;
0448           hExcel.Selection.Value = data;
0449       end
0450 
0451       % TODO: Change checkbox fields to boolean (TRUE/empty)
0452 
0453       % Other formats
0454       %hExcel.Cells.HorizontalAlignment = -4108;  % =xlCenter  % TODO: preserve original jtable column alignment
0455       hExcel.Cells.EntireColumn.AutoFit;
0456       hExcel.ActiveSheet.DisplayRightToLeft = false;
0457       set(hExcel.ActiveSheet.PageSetup, 'LeftMargin',  hExcel.InchesToPoints(0.1), ...
0458                                         'RightMargin', hExcel.InchesToPoints(0.1), ...
0459                                         'HeaderMargin',hExcel.InchesToPoints(0), ...
0460                                         'FooterMargin',hExcel.InchesToPoints(0.1), ...
0461                                         'TopMargin',120, ...
0462                                         'FitToPagesWide',1, ...
0463                                         'FitToPagesTall',1, ...
0464                                         'Orientation','xlPortrait', ...
0465                                         'LeftHeader','&D  &T', ...
0466                                         'CenterHeader',char(mtable.getTable.getName), ...
0467                                         'RightHeader','&G');
0468 
0469       % Send to printer
0470       hExcel.ActiveWindow.SelectedSheets.PrintOut;
0471 
0472       % Close the workbook
0473       invoke(hExcel.ActiveWindow,'close',false);
0474   catch
0475       % Insert your code here
0476       %handleError;
0477       err = lasterror;
0478       try  invoke(hExcel.ActiveWindow,'close',false);  catch  end;  % just in case of a printing error
0479       rethrow(err);
0480   end
0481 
0482 
0483 %% --- Convert col # format to 'A','B','C','AA',... format
0484 % Thanks Brett Shoelson, via CSSM
0485 function colStr = n2a(c)
0486   t = [floor((c-1)/26)+64, rem(c-1,26)+65];
0487   if (t(1)<65), t(1) = []; end
0488   colStr = char(t);
0489 
0490 
0491 %% --- Executes on button press in btInsert.
0492 function stopEditing(jtable)
0493   %try
0494       component = jtable.getEditorComponent;
0495       if ~isempty(component)
0496           event = javax.swing.event.ChangeEvent(component);
0497           jtable.editingStopped(event);
0498       end
0499   %catch
0500       % Insert your code here
0501       %handleError;
0502   %end
0503 
0504   
0505 %% --- Utility function to set visibility of row manipulation buttons
0506 function setVisibility(hObject, enableStr)
0507 % hObject    handle to some element within the figure
0508 % enableStr  'on' or 'off'
0509   %try
0510       hParent = ancestor(hObject,'figure');
0511       set(findall(hParent,'tag','btTableInsertRow'),'enable',enableStr);
0512       set(findall(hParent,'tag','btTableDeleteRow'),'enable',enableStr);
0513       set(findall(hParent,'tag','btTableDeleteAll'),'enable',enableStr);
0514       set(findall(hParent,'tag','btTablePrintAll'), 'enable',enableStr);
0515   %catch
0516       % Insert your code here
0517       %handleError;
0518   %end

Generated on Tue 27-Aug-2013 11:46:04 by m2html © 2005