com.google.appinventor.client.explorer.commands.ShowProgressBarCommand.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.client.explorer.commands.ShowProgressBarCommand.java

Source

// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.client.explorer.commands;

import java.util.Date;

import com.google.appinventor.client.Ode;
import com.google.appinventor.client.OdeAsyncCallback;

import static com.google.appinventor.client.Ode.MESSAGES;
import com.google.appinventor.shared.rpc.RpcResult;
import com.google.appinventor.shared.rpc.project.ProjectNode;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.appinventor.client.output.MessagesOutput;
import com.google.appinventor.client.explorer.commands.MiniProgressBar;

/**
 * Command for displaying a barcode for the target of a project.
 *
 * <p/>This command is often chained with SaveAllEditorsCommand and BuildCommand.
 *
 * @author markf@google.com (Mark Friedman)
 */
public class ShowProgressBarCommand extends ChainableCommand {

    // The build target
    private int counter = 0;
    private int currentProgress = 0;
    // 0 means just initialize, 1 means click once, 2 means click twice
    private int progressBarShow = 0;
    private String target;
    private ChainableCommand nextCommand;
    private final String buildRequestTime;
    private static final int WAIT_INTERVAL_MILLIS = 5000;
    private ProjectNode projectNode;
    private ProgressBarDialogBox minPB;
    private String serviceName;

    /**
     * Creates a new command for showing a barcode for the target of a project.
     *
     * @param target the build target
     * @param nextCommand
     * @param serviceName
     */
    public ShowProgressBarCommand(String target, ChainableCommand nextCommand, String serviceName) {
        // Since we don't know when the barcode dialog is finished, we can't
        // support a command after this one.
        super(nextCommand); // no next command
        this.target = target;
        this.nextCommand = nextCommand;
        this.buildRequestTime = DateTimeFormat.getMediumDateTimeFormat().format(new Date());
        this.serviceName = serviceName;
    }

    @Override
    public boolean willCallExecuteNextCommand() {
        return true;
    }

    @Override
    //the main function to be called
    public void execute(final ProjectNode node) {
        final Ode ode = Ode.getInstance();
        if (counter < 1) {
            projectNode = node;
            minPB = new ProgressBarDialogBox();
            minPB.center();
            executeNextCommand(node);
        }
        counter++;
        //call back function - dynamic DialogBox
        OdeAsyncCallback<RpcResult> callback = new OdeAsyncCallback<RpcResult>(MESSAGES.buildError()) // failure message
        {
            @Override
            public void onSuccess(RpcResult result) {
                minPB.addMessages(node.getName(), result);
                if (result.succeeded()) {
                    minPB.hide();
                } else if (progressBarShow != 2) {
                    // Build isn't done yet
                    Timer timer = new Timer() {
                        @Override
                        public void run() {
                            execute(node);
                        }
                    };
                    // TODO(user): Maybe do an exponential backoff here.
                    timer.schedule(WAIT_INTERVAL_MILLIS);
                }
            }

            @Override
            public void onFailure(Throwable caught) {
                super.onFailure(caught);
                executionFailedOrCanceled();
            }
        };
        ode.getProjectService().getBuildResult(node.getProjectId(), target, callback);
    }

    class ProgressBarDialogBox extends DialogBox {
        public ClickHandler buttonHandler;
        public Button dismissButton = new Button(MESSAGES.dismissButton());
        public HTML warningLabel;
        public VerticalPanel contentPanel;
        public HorizontalPanel buttonPanel = new HorizontalPanel();
        public HorizontalPanel warningPanel = new HorizontalPanel();
        public MiniProgressBar mpb = new MiniProgressBar(0, 100, 0);

        //constructor
        ProgressBarDialogBox() {
            super(false, true);
            setStylePrimaryName("ode-DialogBox");
            setText(projectNode.getName() + " " + MESSAGES.ProgressBarFor());

            //click handler for the mini html buttons
            buttonHandler = new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    hide();
                    progressBarShow++;
                }
            };

            //declare the ok button
            dismissButton.addClickHandler(buttonHandler);
            buttonPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
            dismissButton.setVisible(false); // we don't need the button unless we get an error

            //warning label
            warningLabel = new HTML("");
            warningLabel.setWordWrap(true);
            warningLabel.setWidth("60em"); // set width to get the text to wrap

            //warning panel
            warningPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_LEFT);
            warningPanel.add(warningLabel);

            // button panel
            buttonPanel.add(dismissButton);
            buttonPanel.setSize("100%", "24px");

            //content panel
            contentPanel = new VerticalPanel();
            contentPanel.add(mpb);
            contentPanel.add(warningPanel);
            contentPanel.add(buttonPanel);
            setWidget(contentPanel);
        }

        public void clear() {
            warningLabel.setHTML("");
        }

        public void addMessages(String projectName, RpcResult result) {
            if (result.succeeded()) {
                show();
                mpb.setProgress(100);
                if (serviceName == "DownloadAction") {
                    warningLabel.setHTML("<br />The APK file will be saved in the download folder.");
                } else if (serviceName == "DownloadToPhoneAction") {
                    warningLabel.setHTML("<br />The APK file will be installed in the phone.");
                } else {
                    warningLabel.setHTML("<br />Waiting for the barcode.");
                }
            } else {
                try {
                    currentProgress = Math.max(currentProgress, Integer.parseInt(result.getOutput()));
                    mpb.setProgress(currentProgress);
                    if (currentProgress <= 10) {
                        warningLabel.setHTML("<br />Preparing application icon");
                    } else if (currentProgress < 15) {
                        warningLabel.setHTML("<br />Determining permissions");
                    } else if (currentProgress < 20) {
                        warningLabel.setHTML("<br />Generating application information");
                    } else if (currentProgress < 35) {
                        warningLabel.setHTML("<br />Compiling part 1");
                    } else if (currentProgress < 85) {
                        warningLabel.setHTML("<br />Compiling part 2 (please wait)");
                    } else if (currentProgress < 90) {
                        warningLabel.setHTML("<br />Preparing final package");
                    } else if (currentProgress <= 95) {
                        warningLabel.setHTML("<br />Building APK");
                    } else {
                        if (serviceName == "DownloadAction") {
                            warningLabel.setHTML("<br />The APK file will be saved in your downloads folder.");
                        } else if (serviceName == "DownloadToPhoneAction") {
                            warningLabel.setHTML("<br />The APK file will be installed in the phone.");
                        } else {
                            warningLabel.setHTML("<br />Waiting for the barcode.");
                        }
                    }
                } catch (NumberFormatException e) {
                    // If the result is an error message, then the number parse will fail,
                    // so we pick up the case of a compilation failure here.
                    mpb.setProgress(0);
                    // show the dismiss button to dismiss error
                    dismissButton.setVisible(true);
                    warningLabel.setHTML(MESSAGES.unableToCompile(result.getOutput()));
                }
            }
        }
    }
}