com.anrisoftware.prefdialog.miscswing.dialogsworker.OpenDialogAction.java Source code

Java tutorial

Introduction

Here is the source code for com.anrisoftware.prefdialog.miscswing.dialogsworker.OpenDialogAction.java

Source

/*
 * Copyright 2013-2016 Erwin Mller <erwin.mueller@deventm.org>
 *
 * This file is part of prefdialog-misc-swing.
 *
 * prefdialog-misc-swing is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * prefdialog-misc-swing is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with prefdialog-misc-swing. If not, see <http://www.gnu.org/licenses/>.
 */
package com.anrisoftware.prefdialog.miscswing.dialogsworker;

import static java.awt.Cursor.DEFAULT_CURSOR;
import static java.awt.Cursor.WAIT_CURSOR;
import static javax.swing.SwingUtilities.invokeLater;
import static javax.swing.SwingUtilities.isEventDispatchThread;
import static org.apache.commons.lang3.Validate.isTrue;
import static org.apache.commons.lang3.Validate.notNull;

import java.awt.Component;
import java.awt.Container;
import java.util.Locale;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

import javax.inject.Inject;

import com.anrisoftware.prefdialog.miscswing.cursor.CursorWorker;
import com.anrisoftware.resources.texts.api.Texts;

/**
 * Opens a dialog on the AWT event thread and waits for the user to close it.
 *
 * @author Erwin Mueller, erwin.mueller@deventm.org
 * @since 3.2
 */
public abstract class OpenDialogAction<DialogType extends Container, ResultType> implements Callable<ResultType> {

    private final AbstractCreateDialogWorker<DialogType> dialogWorker;

    @Inject
    private OpenDialogActionLogger log;

    @Inject
    private CursorWorker cursorWorker;

    private CountDownLatch dialogLatch;

    private Component parentComponent;

    private ResultType dialogResult;

    protected OpenDialogAction(AbstractCreateDialogWorker<DialogType> dialogWorker) {
        this.dialogWorker = dialogWorker;
    }

    @SuppressWarnings("unchecked")
    public <T extends AbstractCreateDialogWorker<DialogType>> T getDialogWorker() {
        return (T) dialogWorker;
    }

    public void setParentComponent(Component parentComponent) {
        this.parentComponent = parentComponent;
        cursorWorker.setParentWindow(parentComponent);
    }

    public Component getComponentParent() {
        return parentComponent;
    }

    public void setLocale(Locale locale) {
        dialogWorker.setLocale(locale);
    }

    public Locale getLocale() {
        return dialogWorker.getLocale();
    }

    public void setTexts(Texts texts) {
        dialogWorker.setTexts(texts);
    }

    public Texts getTexts() {
        return dialogWorker.getTexts();
    }

    public void setDialogTitleResourceName(String name) {
        dialogWorker.setDialogTitleResourceName(name);
    }

    public void setDialogTitle(String dialogTitle) {
        dialogWorker.setDialogTitle(dialogTitle);
    }

    /**
     * Opens the dialog on the AWT event thread and waits for the user to close
     * the dialog.
     * <p>
     * <h2>AWT Thread</h2>
     * Should be called <i>outside</i> the AWT event dispatch thread.
     * </p>
     *
     * @return the result value or {@code null}.
     */
    @Override
    public synchronized ResultType call() throws Exception {
        isTrue(!isEventDispatchThread(), "Cannot block the AWT event dispatch thread");
        notNull(dialogWorker, "dialogWorker");
        cursorWorker.setCursor(WAIT_CURSOR);
        DialogType dialog = createDialog(dialogWorker);
        dialogLatch = new CountDownLatch(1);
        openDialog(dialog, dialogWorker);
        cursorWorker.setCursor(DEFAULT_CURSOR);
        dialogLatch.await();
        return dialogResult;
    }

    /**
     * Opens the dialog on the AWT event thread.
     *
     * @param dialog
     *            the dialog.
     *
     * @param dialogWorker
     *            the {@link AbstractCreateDialogWorker}.
     *
     * @return the return value.
     *
     * @throws CreateDialogWorkerException
     *             if there was any error opening the dialog.
     *
     * @since 3.5
     */
    protected abstract ResultType openDialogAWT(DialogType dialog,
            AbstractCreateDialogWorker<DialogType> dialogWorker) throws CreateDialogWorkerException;

    /**
     * Setups the dialog worker to create the dialog.
     *
     * @param dialogWorker
     *            the {@link AbstractCreateDialogWorker}.
     *
     * @return the created dialog.
     *
     * @throws CreateDialogWorkerException
     *             if there were any errors creating the dialog.
     *
     * @see AbstractCreateDialogWorker#getDialog()
     *
     * @since 3.5
     */
    protected DialogType createDialog(AbstractCreateDialogWorker<DialogType> dialogWorker)
            throws CreateDialogWorkerException {
        return dialogWorker.getDialog();
    }

    private void openDialog(final DialogType dialog, final AbstractCreateDialogWorker<DialogType> dialogWorker) {
        setupDialog(dialog, dialogWorker);
        invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    dialogResult = openDialogAWT(dialog, dialogWorker);
                } catch (Throwable e) {
                    log.errorOpenDialog(e);
                }
                dialogLatch.countDown();
            }

        });
    }

    /**
     * Setups the dialog before opening it.
     *
     * @param dialog
     *            the dialog.
     *
     * @param dialogWorker
     *            the {@link AbstractCreateDialogWorker}.
     *
     * @since 3.5
     */
    protected void setupDialog(DialogType dialog, AbstractCreateDialogWorker<DialogType> dialogWorker) {
    }

}