function events(this)
import javax.swing.*;


if isfield(this.Handles,'EventsPanel')
    set(this.Handles.EventsPanel,'Visible','on')
    return
end
f = figure('Units','Characters','Position',[0 0 100 30]);

%% Create the node panel and components
Panel = localBuildPanel(f,this);

%% Temporary listeners to update table visibility when the enclosing panel
%% visibility is modified
h = handle(Panel);
this.addListeners(handle.listener(h,h.findprop('Visible'),'PropertyPostSet',...
    {@localSetVisible h}));

%% Listener to the events stored in the timeseries
this.addListeners(handle.listener(this.Timeseries,...
    this.Timeseries.findprop('Events'),'PropertyPostSet',...
    {@localEventsChange this.Timeseries this.Handles.eventTable}));
localEventsChange([],[],this.Timeseries,this.Handles.eventTable)

centerfig(f)
this.Handles.EventsPanel =f;

function f = localBuildPanel(thisfig, h)

import javax.swing.*;

%% Create and position the components on the panel
f = uipanel('Parent',thisfig,'Units','Characters');

%% Events panel
PNLevents = uipanel('Parent',f,'Units','Characters','Title',...
    'Define Available Events','Position',[1 1 98 28]);
h.Handles.BTNaddEvent = uicontrol('Style','pushbutton','Parent',PNLevents, ...
    'Units','Pixels','String','Add event','Callback',{@localAddEvent h.Timeseries},...
    'Units','Characters','Position',[97-18-18-4 1 18 2]);
h.Handles.BTNdelEvent = uicontrol('Style','pushbutton','Parent',PNLevents, ...
    'Units','Pixels','String','Delete event','Callback',{@localDelEvent h},... 
    'Units','Characters','Position',[97-20 1 18 2]);
[h.Handles.eventTable, h.Handles.PNLeventTable] = uitable(thisfig,cell([0,4]), ...
    {'Name','Description','Time','Time Units'});
set(h.Handles.eventTable,'DataChangedcallback',...
    {@localEventTimeChange h});
set(h.Handles.PNLeventTable,'Parent',PNLevents,'Units','Characters','Position', [1 5 96 19])
awtinvoke(h.Handles.eventTable.getTable,'setSelectionMode',...
        ListSelectionModel.SINGLE_SELECTION);
set(h.Handles.eventTable.TableScrollPane.getRowHeader,'Visible','off');
h.Handles.eventTable.setComboBoxEditor({get(findtype('TimeUnits'),'Strings')},4);
awtinvoke(h.Handles.eventTable.getTable,'setCellSelectionEnabled',false);
awtinvoke(h.Handles.eventTable.getTable,'setRowSelectionAllowed',true);
awtinvoke(h.Handles.eventTable.getTable,'setAutoResizeMode',...
    JTable.AUTO_RESIZE_ALL_COLUMNS)

function localSetVisible(es,ed,h)

children = h.find('-depth',inf);
I = strcmp(get(children,'type'),'uicontainer');
if any(I)
   set(children(I),'Visible',get(h,'Visible'));
end


function localEventsChange(eventSrc,eventData,ts,eventTable,tsparent)

%% Listener callback to @eventsnode "Events" property which keeps the event
%% table in sync
tableData = cell(length(ts.Events),4);
for k=1:length(ts.Events)
    tableData(k,:) = {ts.Events(k).Name, '', ts.Events(k).Time ts.TimeInfo.Units};
end

%% Passive table data change
tstableSetData(eventTable,tableData)

function localEventTimeChange(eventSrc,eventData,h)

%% Callback which reacts to changes in the event time made in the events
%% table

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

%% Look for the event who's time has changed
if col==3
    I = find(strcmp(h.Handles.eventTable.Data(startRow,1),get(h.Timeseries.events,{'Name'})));
    if ~isempty(I)
        evtime = h.Handles.eventTable.Data(startRow,3);
        if isnumeric(evtime)
             h.Timeseries.events(I(1)).Time = evtime;
        elseif ~isempty(evtime) && ischar(evtime)
             h.Timeseries.events(I(1)).Time = str2num(evtime);
        end
        % Send a datachange event to the affected time series
        h.Timeseries.send('datachange')
    end
end

function localAddEvent(es,ed,ts)

%% Get the properties of the new event
e = tsnewevent;

%% Update the list of events
ts.addevent(e);


function localDelEvent(es,ed,h)

selrow = h.Handles.eventTable.getTable.getSelectedRow+1;
if selrow>=1
    thiseventname = h.Handles.eventTable.Data(selrow,1);
    ind = find(strcmp(thiseventname,get(h.Timeseries.Events,{'Name'})));
        %% Update the list of events
        h.Timeseries.Events(ind) = [];
end
h.Timeseries.send('datachange')