package com.srbenoit.ui;

import java.util.logging.Level;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import com.srbenoit.log.LoggedObject;

/**
 * A class to execute a <code>GuiBuilder</code> from the AWT event thread.
 */
public final class GuiBuilderRunner extends LoggedObject implements Runnable {

    /** the <code>GuiBuilder</code> whose build method is to be called */
    private final transient GuiBuilder owner;

    /** the frame to which to add menus if needed */
    private transient JFrame frame;

    /**
     * Constructs a new <code>GuiBuilderRunner</code>.
     *
     * @param  theOwner  the <code>GuiBuilder</code> whose build method is to be called
     */
    public GuiBuilderRunner(final GuiBuilder theOwner) {

        super();
        this.owner = theOwner;
    }

    /**
     * Execute the <code>buildUI</code> method on the owner object in the AWT event thread, waiting
     * for that to complete before returning.
     *
     * @param  menuFrame  the frame to which to add menus if needed
     */
    public void buildUI(final JFrame menuFrame) {

        this.frame = menuFrame;

        if (SwingUtilities.isEventDispatchThread()) {
            run();
        } else {

            try {
                SwingUtilities.invokeAndWait(this);
            } catch (Exception ex1) {
                LOG.log(Level.WARNING, "Failed to invoke UI builder: ", ex1);
            }
        }
    }

    /**
     * Runnable method to call the owner's <code>buildUI</code> method from within the AWT event
     * dispatcher thread.
     */
    public void run() {

        this.owner.buildUI(this.frame);
    }
}
