function hToolGroup = toolstrip_demo1
    % toolstrip_demo1 - Demo for basic Matlab toolstrip customizations
    % (c) Yair Altman 12/2018 http://UndocumentedMatlab.com

    % based on:  matlab.ui.internal.desktop.showcaseToolGroup()
    %   %matlabroot%\toolbox\matlab\toolstrip\+matlab\+ui\+internal\+desktop\
    %   %matlabroot%\toolbox\matlab\toolstrip\+matlab\+ui\+internal\+toolstrip\

    % Create an app with a built-in toolstrip (widget: DesktopGroup)
    hToolGroup = matlab.ui.internal.desktop.ToolGroup('Toolstrip example on UndocumentedMatlab.com');

    % Listen to close event (need to ensure that strcmp(event.EventData.EventType,'CLOSED'))
    %addlistener(hToolGroup, 'GroupAction',@(src,event) delete(hToolGroup));

    % Discard the Data-browser left panel
    hToolGroup.disableDataBrowser();

    % show the app (some things only work after the app is shown)
    hToolGroup.open();

    % create a tab group
    %tabgroup = matlab.ui.internal.desktop.showcaseBuildTabGroup('swing');
    import matlab.ui.internal.toolstrip.*
    hTabGroup = TabGroup();

    % Add the tab group to the built-in toolstrip
    hToolGroup.addTabGroup(hTabGroup);

    % Add tabs to the TabGroup
    hTabGroup.add(createDataTab());

    % Dock figure(s) into the tool-group
    hFig1 = figure('Name','3D');  surf(peaks);
    hToolGroup.addFigure(hFig1);
    %hFig2 = figure('Name','2D');  plot(rand(5));
    %hToolGroup.addFigure(hFig2);

    % Store toolgroup reference handle so that app will stay in memory
    jToolGroup = hToolGroup.Peer;
    internal.setJavaCustomData(jToolGroup, hToolGroup);
    %{
    % Get Matlab wrapper with CallbackProperties
    hc = handle(jToolGroup,'CallbackProperties');
    if isempty(findprop(hc,'CustomData'))
        % If property does not exist create it
        schema.prop(hc,'CustomData','MATLAB array');
    end
    set(hc,'CustomData',hToolGroup);    
    %}
end

% Tabs
function hTab = createDataTab()
    % Create the "Data" tab
    % Adapted from %matlabroot%\toolbox\matlab\toolstrip\+matlab\+ui\+internal\+desktop\showcaseBuildTab_Buttons.m
    import matlab.ui.internal.toolstrip.*
    %% Create new tab
    hTab = Tab('Data');
    %hTab.Tag = 'data tab';

    %% Create push buttons section
    section1 = hTab.addSection('Push buttons');

    column1a = section1.addColumn();
    %icon = Icon(fullfile(matlabroot,'toolbox','shared','controllib','general','resources','toolstrip_icons','New_16.png')); % image file
    icon = Icon.REFRESH_24; % built-in: see Icon.showStandardIcons()
    button = Button('Refresh all',icon);
    button.Description = 'Refresh the charted data - all axes';
    button.ButtonPushedFcn = @refreshAllData;
    column1a.add(button);
    function refreshAllData(hAction,hEventData)
        hAxes = gca;
        hChildren = hAxes.Children;
        for idx = 1 : numel(hChildren)
            hChild = hChildren(idx);
            hChild.XData = -hChild.XData;
            hChild.YData = -hChild.YData;
            hChild.ZData = -hChild.ZData;
        end
    end

    column1b = section1.addColumn();
    addRefresh2Button('X','Y');
    addRefresh2Button('Y','Z');
    function addRefresh2Button(type1, type2)
        import matlab.ui.internal.toolstrip.*
        hButton = Button(['Refresh ' type1 ',' type2], Icon.RESTORE_16);
        hButton.Description = ['Refresh the charted data - ' type1 ',' type2 ' axes'];
        hButton.ButtonPushedFcn = {@refres2AxisData, type1, type2};
        column1b.add(hButton);

        function refres2AxisData(~,~,type1,type2)
            hAxes = gca;
            hChildren = hAxes.Children;
            for idx = 1 : numel(hChildren)
                hChild = hChildren(idx);
                hChild.([type1 'Data']) = -hChild.([type1 'Data']);
                hChild.([type2 'Data']) = -hChild.([type2 'Data']);
            end
        end
    end

    column1c = section1.addColumn();
    addRefresh1Button('X');
    addRefresh1Button('Y');
    addRefresh1Button('Z');
    function addRefresh1Button(type)
        import matlab.ui.internal.toolstrip.*
        hButton = Button(['Refresh ' type], Icon.REDO_16);
        hButton.Description = ['Refresh the charted data - ' type ' axes'];
        addlistener(hButton, 'ButtonPushed', @refres1AxisData);  % {} not supported!
        column1c.add(hButton);

        function refres1AxisData(h,e)
            hAxes = gca;
            hChildren = hAxes.Children;
            for idx = 1 : numel(hChildren)
                hChild = hChildren(idx);
                hChild.([type 'Data']) = -hChild.([type 'Data']);
            end
        end
    end

    %% Create toggle buttons section (individual)
    section2 = hTab.addSection('Toggle buttons');
    section2.CollapsePriority = 2;

    column1 = Column();
    section2.add(column1);
    %icon = Icon.LEGEND_24;
    icon = Icon(fullfile(matlabroot,'toolbox','shared','controllib','general','resources','toolstrip_icons','Legend_24.png')); % PNG/JPG image file (not GIF!)
    button = ToggleButton('Legend',icon);
    button.Description = 'Toggle legend display';
    addlistener(button, 'ValueChanged', @(h,e)legend('toggle'));
    column1.add(button);
    
    column2 = section2.addColumn();
    imagefile = fullfile(matlabroot,'toolbox','matlab','icons','tool_colorbar.png');
    jIcon = javax.swing.ImageIcon(imagefile); % ImageIcon from file (inc. GIF)
    %jIcon = javax.swing.ImageIcon(jIcon.getImage.getScaledInstance(24,24,jIcon.getImage.SCALE_SMOOTH))
    icon = Icon(jIcon);
    button = ToggleButton('Colorbar',icon);
    button.Description = 'Toggle colorbar display';
    button.ValueChangedFcn = @toggleColorbar;
    column2.addEmptyControl();
    column2.add(button);
    column2.addEmptyControl();
    function toggleColorbar(hAction,hEventData)
        if hAction.Selected
            colorbar;
        else
            colorbar('off');
        end
    end

    %% Checkboxes section
    section3 = Section('Checkboxes');
    section3.CollapsePriority = 1;
    hTab.add(section3, 2);
    column3 = section3.addColumn('HorizontalAlignment','left', 'Width',150);
    button = CheckBox('Axes borders', true);
    button.ValueChangedFcn = @toggleAxes;
    button.Description = 'Axes borders';
    column3.add(button);
    button = CheckBox('Log scaling', false);
    button.addlistener('ValueChanged',@toggleLogY);
    button.Description = 'Log scaling';
    column3.add(button);
    button = CheckBox('Inverted Y', false);
    button.addlistener('ValueChanged',@toggleInvY);
    button.Description = 'Invert Y axis';
    column3.add(button);
    function toggleAxes(hAction,hEventData)
        if hAction.Selected
            set(gca,'Visible','on');
        else
            set(gca,'Visible','off');
        end
    end
    function toggleLogY(hCheckbox,~)
        if hCheckbox.Value, type = 'log'; else, type = 'linear'; end
        set(gca, 'XScale',type, 'YScale',type, 'ZScale',type);
    end
    function toggleInvY(hCheckbox,hEventData)
        if hCheckbox.Value, type = 'reverse'; else, type = 'normal'; end
        set(gca, 'YDir',type);
    end
end

% callback function
function PropertyChangedCallback(~, data)
    eventData = data.EventData;
    oldValue = eventData.OldValue;
    newValue = eventData.NewValue;
    if isempty(oldValue) && ~isempty(newValue)
        fprintf('Property "%s" is changed from [] to "%s".\n', eventData.Property, newValue.Title);
    elseif ~isempty(oldValue) && isempty(newValue)
        fprintf('Property "%s" is changed from "%s" to [].\n', eventData.Property, oldValue.Title);
    elseif ~isempty(oldValue) && ~isempty(newValue)
        fprintf('Property "%s" is changed from "%s" to "%s".\n', eventData.Property, oldValue.Title, newValue.Title);
    end
end
function ActionPerformedCallback(~, data)
    if isempty(data.EventName)
        fprintf('Event "%s" occurs from the UI.\n', data.EventData.EventType);
    else
        fprintf('Event "%s" occurs from the UI.\n', data.EventName);
    end
end
