/*
 * Torutk Learning Project for Swing Application Framework.
 *
 * $Id: SleepyTaskApplication.java 102 2007-10-08 12:35:52Z toru $
 */
import org.jdesktop.application.Action;
import org.jdesktop.application.ApplicationContext;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.Task;
import java.awt.BorderLayout;
import javax.swing.ActionMap;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.jdesktop.application.Application;

public class SleepyTaskApplication extends SingleFrameApplication {

    @Override
    protected void startup() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        messageLabel = new JLabel();
        messageLabel.setName("messageLabel");
        panel.add(messageLabel, BorderLayout.CENTER);

        startButton = new JButton();
        startButton.setName("startButton");
        panel.add(startButton, BorderLayout.SOUTH);

        ActionMap map = getContext().getActionMap();
        startButton.setAction(map.get("startSleepyTask"));
        show(panel);
    }

    /**
     * 時間のかかる処理はTaskオブジェクトを返すアクションを定義します。
     * このアクションは、開始されるとメッセージラベルのアイコンと文字列を
     * 変更します。
     */
    @Action public Task startSleepyTask() {
        ResourceMap map = getContext().getResourceMap(SleepyTaskApplication.class);

        messageLabel.setText(map.getString("asleepMessage"));
        messageLabel.setIcon(map.getIcon("asleepIcon"));

        return new SleepyTask(this, map.getInteger("asleepMillis"), messageLabel);
    }

    public static void main(final String[] args) {
        launch(SleepyTaskApplication.class, args);
    }

    private JLabel messageLabel;
    private JButton startButton;
}

/**
 * SwingのEvent Dispatch Thread(EDT)では時間のかかる処理は実行できないため、
 * EDTとは別スレッドで処理するTaskを定義します。
 */
class SleepyTask extends Task<Void, Void> {
    SleepyTask(Application anApplication, int aSleepMillis, JLabel aLabel) {
        super(anApplication);
        sleepMillis = aSleepMillis;
        label = aLabel;
    }

    /**
     * 別スレッドで実行されるメソッド。
     * Taskクラスで定義されるメソッドをオーバーライドします。
     * Taskクラスでは、throws Exceptionで定義されています。なので、
     * Exceptionのサブクラスをthrows宣言で定義するのは問題ない(かな)
     */
    @Override protected Void doInBackground() throws InterruptedException {
        Thread.sleep(sleepMillis);
        return null;
    }

    /**
     * 時間のかかる処理が終了したときに呼ばれる、GUIを更新するメソッド。
     * GUI更新はEDT上で行う必要があるため、doInBackgroundメソッドの中で
     * GUIを更新してはならない。
     */
    @Override protected void finished() {
        ResourceMap map = getContext().getResourceMap(SleepyTaskApplication.class);
        label.setText(map.getString("getupMessage"));
        label.setIcon(map.getIcon("getupIcon"));
    }

    private int sleepMillis;
    private JLabel label;
}


