function thisTab = binpnl(this,h)

import com.mathworks.toolbox.timeseries.*;
import java.awt.*
import com.mathworks.mwswing.*;

%% Build freq panel
h.Handles.BinPnl = localBuildPanel(h,this);
thisTab = struct('Name','Domain','Handles',[]);
thisTab.Name = 'Domain';
h.Tabs = [h.Tabs; thisTab];
outerBinPanel = MJPanel(BorderLayout);
outerBinPanel.add(h.Handles.BinPnl,BorderLayout.WEST);
h.Handles.TabPane.add('Define Bins',outerBinPanel);     

%% Listener to ViewChanged event which keeps the hist
%% panel updated
h.Listeners = [h.Listeners; handle.listener(this,this.findprop('Waves'),'PropertyPostSet',...
    {@localupdatebins h this})];
localupdatebins([],[],h,this)


function BinPnl = localBuildPanel(h,this)

import com.mathworks.mwswing.*;
import javax.swing.*;
import java.awt.*;

%% Build panel
BinPnl = MJPanel;

%% Create components
h.Handles.RADIOCenters = MJRadioButton('Uniform centers      ');
h.Handles.RADIOCenters.setSelected(true);
h.Handles.RADIOCustom = MJRadioButton('Custom centers      ');
BTNGRP = ButtonGroup;
BTNGRP.add(h.Handles.RADIOCenters);
BTNGRP.add(h.Handles.RADIOCustom);
LBLnumbins = MJLabel('Number of bins:');
LBLcenters = MJLabel('Vector of centers:');
h.Handles.TXTnumbins = MJTextField(12);
h.Handles.TXTnumbins.setText('50');
h.Handles.TXTcustomcenters = MJTextField(12);
h.Handles.TXTcustomcenters.setText('1:10');

%% Add callbacks
set(handle(h.Handles.RADIOCenters,'callbackproperties'),'ActionPerformedCallback',...
    {@localupdatebins h this})
set(handle(h.Handles.RADIOCustom,'callbackproperties'),'ActionPerformedCallback',...
    {@localupdatebins h this})
set(handle(h.Handles.TXTnumbins,'callbackproperties'),'ActionPerformedCallback',...
    {@localupdatebins h this})
set(handle(h.Handles.TXTnumbins,'callbackproperties'),'FocusLostCallback',...
    {@localupdatebins h this})
set(handle(h.Handles.TXTcustomcenters,'callbackproperties'),'ActionPerformedCallback',...
    {@localupdatebins h this})
set(handle(h.Handles.TXTcustomcenters,'callbackproperties'),'FocusLostCallback',...
    {@localupdatebins h this})

%% Create inner panel and add components
PNLinner = MJPanel(GridLayout(2,3,5,5));
PNLinner.add(h.Handles.RADIOCenters);
PNLinner.add(LBLnumbins);
PNLinner.add(h.Handles.TXTnumbins);
PNLinner.add(h.Handles.RADIOCustom);
PNLinner.add(LBLcenters);
PNLinner.add(h.Handles.TXTcustomcenters);

%% Finalize panel
BinPnl.add(PNLinner);

function localupdatebins(es,ed,h,this)

%% Update the bins property of the plot based on the definitions in the 
%% tsspecnode Dialog

if h.Handles.RADIOCenters.isSelected
    % Construct a uniform bin vector
    numbins = eval(char(h.Handles.TXTnumbins.getText),'[]');
    if isscalar(numbins) && numbins>1
        L = inf;
        U = -inf;
        for k=1:length(this.Waves)
            thisdata = this.Waves(k).DataSrc.Timeseries.Data;
            L = min(L,min(thisdata(:)));
            U = max(U,max(thisdata(:)));
        end
        bins = linspace(L,U,numbins);
    else % Invalid number of bins - abort and revert to prev val or default
        if ~isempty(this.Bins)
            h.Handles.TXTnumbins.setText(sprintf('%d',length(this.Bins)));
        else
            h.Handles.TXTnumbins.setText('50');
        end
        return
    end
else
    % Construct a custom bin vector
    bins = eval(h.Handles.TXTcustomcenters.getText,'[]');    
    % If bin vec is invalid abort and revert to default 
    if isempty(bins) || ~(all(isfinite(bins)) && ndims(bins)==2 && min(size(bins))==1 && ...
        issorted(bins))
        if ~isempty(this.Bins)
            h.Handles.TXTcustomcenters.setText(['[' num2str(this.Bins) ']']);
        else
            h.Handles.TXTcustomcenters.setText('1:10');
        end    
        return
    end
end

%% Apply the bin vector to the datafcn for each wave
if ~isequal(this.Bins,bins);
    this.Bins = bins;
    for k=1:length(this.Waves)
        this.Waves(k).DataSrc.send('SourceChanged')
    end
end