function tstable(h)

import javax.swing.*;

%% Syncs the timeseries table with the tsseriesview node. Used by the
%% listener to the tschanged event to update the list of time series in the
%% view

if ~isempty(h.Plot)
    % Initilize vars
    tsList = h.Plot.getTimeSeries;
    tableData = cell([size(tsList,1),4]);
    
    % Update the time series table from the time series list and waveforms
    for k=1:length(tsList)
        tableData{k,1} = tsList{k}.Name;
        tableData{k,2} = sprintf('%d x %d',size(tsList{k}.Data,1),size(tsList{k}.Data,2));
        tableData{k,3} = sprintf('[ %s ]',num2str(h.Plot.Waves(k).Rowindex(:)'));
        tableData{k,4} = strcmp(h.Plot.waves(k).Visible,'on');
    end    
else
    tableData = cell(0,4);
end

%% Populate the table - if necessary creating it
if ~isfield(h.Handles,'tsTable') || isempty(h.Handles.tsTable)
    headings = {'Time series','Size','Axes Indices','Visible?'};
    [h.Handles.tsTable, h.Handles.PNLTsTable] = ... 
        tsuitable(ancestor(h.Handles.PNLTs,'figure'),'Position',[0 0 1 1]);
    tsCustomizeUitable(h.Handles.tsTable,[1,2]);
    h.Handles.tsTable.setData(tableData);
    h.Handles.tsTable.setColumnNames(headings);
    set(h.Handles.PNLTsTable,'Parent',h.Handles.PNLTs)
    % Single select only
    awtinvoke(h.Handles.tsTable.getTable,'setSelectionMode(I)',...
        ListSelectionModel.SINGLE_SELECTION);
    awtinvoke(java(h.Handles.tsTable),'setCheckBoxEditor(I)',4);
    %h.Handles.tsTable.setCheckBoxEditor(4);
    awtinvoke(h.Handles.tsTable.getTable,'setCellSelectionEnabled(Z)',false);
    awtinvoke(h.Handles.tsTable.getTable,'setRowSelectionAllowed(Z)',true);
    
    % DataChange listener
    set(h.Handles.tsTable,'DataChangedCallback',{@localDataChange h})
else
    h.Handles.tsTable.setData(tableData);
end

%% Pack the table
awtinvoke(h.Handles.tsTable.getTable,'setAutoResizeMode(I)',...
    JTable.AUTO_RESIZE_ALL_COLUMNS)

function localDataChange(eventSrc,eventData,h)

%% Normalization table callback - updates the wavefor Data max and Min
%% props

%% Find the data which was changed
row = eventData.getEvent.getFirstRow+1;
col = eventData.getEvent.getColumn+1;

%% Get current table data
tableData = cell(h.Handles.tsTable.Data);

%% Get data objects and find the max # of cols
maxcols = 0;
maxrowinds = 0;
if ~isempty(h.Plot)
    dataobjs = get(h.Plot.Waves,{'Data'});
    for k=1:length(dataobjs)
        thissize = h.Plot.Waves(k).Data.getsize;
        maxcols = max(thissize(1),maxcols);
        if k~=row % Maximum row ind, excluding this row
            maxrowinds = max(maxrowinds,max(h.Plot.Waves(k).RowIndex));
        end
    end
end
        
if col==3 % Axes index update
    newIndices = eval(tableData{row,col},'[]');
    if isempty(newIndices) || ~isnumeric(newIndices) || any(isnan(newIndices)) || ...
            any(~isfinite(newIndices)) || any(floor(newIndices)<=0) || ...
            any(abs(newIndices-floor(newIndices))>0)
        errordlg('Invalid axes position specification','Time Series Tools',...
            'modal')
        % Revert
        h.Handles.tsTable.setDataAt(['[' num2str(h.Plot.waves(row).RowIndex(:)') ']'],...
             row-1,col-1);
        return
    end
    
    rsize = h.Plot.Waves(row).Data.getsize;
    if length(newIndices)~=rsize(1)
         msg = sprintf('The length of the axes index vector must equal the number of columns in the time series (%d)',...
             rsize(1));
         errordlg(msg,'Time Series Tools','modal')
         % Revert
         h.Handles.tsTable.setDataAt(['[' num2str(h.Plot.waves(row).RowIndex(:)') ']'],...
             row-1,col-1);
         return       
    end

    if max(newIndices)>maxcols
         msg = sprintf('The largest axes index vector must not exceed the maximum number of columns in any of the time series (%d)',...
             maxcols);
         errordlg(msg,'Time Series Tools','modal')
         % Revert
         h.Handles.tsTable.setDataAt(['[' num2str(h.Plot.waves(row).RowIndex(:)') ']'],...
             row-1,col-1);
         return       
    end        
        
    if isempty(h.Plot)
        h.tstable;
    elseif max(newIndices)>h.Plot.AxesGrid.size(1)
       % Add axes
       for k=1:(max(newIndices)-h.Plot.AxesGrid.size(1))
          h.Plot.addaxes;
       end
       h.Plot.Waves(row).RowIndex = newIndices;
    elseif max(maxrowinds,max(newIndices))<h.Plot.AxesGrid.size(1)
       h.Plot.Waves(row).RowIndex = newIndices;
       delind = (max(newIndices)+1):h.Plot.AxesGrid.size(1);
       for k=length(delind):-1:1
            h.Plot.rmaxes(delind(k));
       end     
    else
        h.Plot.Waves(row).RowIndex = newIndices;
    end
elseif col==4 % Visibility update
    offon = {'off','on'};
    h.Plot.waves(row).Visible = offon{double(eventSrc.Data(row,4))+1};
end
