Package lcmc.common.ui

Source Code of lcmc.common.ui.WizardDialog

/*
* This file is part of DRBD Management Console by LINBIT HA-Solutions GmbH
* written by Rasto Levrinc.
*
* Copyright (C) 2009, LINBIT HA-Solutions GmbH.
* Copyright (C) 2011-2012, Rastislav Levrinc.
*
* DRBD Management Console is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* DRBD Management Console 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 General Public License
* along with drbd; see the file COPYING.  If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/


package lcmc.common.ui;

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;

import lcmc.cluster.ui.widget.Check;
import lcmc.common.domain.Application;
import lcmc.common.domain.CancelCallback;
import lcmc.common.ui.utils.MyButton;
import lcmc.common.domain.util.Tools;

/**
* An implementation of a wizard dialog with next, back, finish and cancel
* buttons.
* The dialogs that are in a row of dialog steps should extend this class
* and overwrite at least * body() and nextDialog() methods.
*/
public abstract class WizardDialog extends ConfigDialog {
    static final ImageIcon CANCEL_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.CancelIcon"));
    static final ImageIcon FINISH_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.FinishIcon"));
    private static final ImageIcon NEXT_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.NextIcon"));
    private static final ImageIcon BACK_ICON = Tools.createImageIcon(Tools.getDefault("Dialog.Dialog.BackIcon"));
    /** Previous dialog object. A dialog that will be displayed after clicking on the back button */
    private WizardDialog previousDialog;
    private ProgressBar progressBar = null;
    @Inject
    private Application application;
    @Inject
    private Provider<ProgressBar> progressBarProvider;

    /**
     * Returns previous dialog. It is used to get with the back button to
     * the dialog before this one.
     */
    public WizardDialog getPreviousDialog() {
        return previousDialog;
    }

    /**
     * Returns previous dialog. It is used to get with the back button to
     * the dialog before this one.
     */
    protected final void setPreviousDialog(final WizardDialog previousDialog) {
        this.previousDialog = previousDialog;
    }

    public String nextButton() {
        return buttonString("Next");
    }

    public final String backButton() {
        return buttonString("Back");
    }

    public String finishButton() {
        return buttonString("Finish");
    }

    final String retryButton() {
        return buttonString("Retry");
    }

    public final boolean isPressedCancelButton() {
        return isPressedButton(cancelButton());
    }

    public final boolean isPressedFinishButton() {
        return isPressedButton(finishButton());
    }

    /**
     * Array of buttons that are used in the dialog. Wrapper function
     * like nextButton() should be used instead of simple "Next", so
     * it can be localized. In TextResources.java file it can be than
     * redifined with Dialog.Dialog.Next.
     */
    @Override
    protected final String[] buttons() {
        return new String[]{retryButton(), // this one is hidden.
                            backButton(),
                            nextButton(),
                            finishButton(),
                            cancelButton()};
    }

    /**
     * Returns the listener for the skip button, that enables "next" button if
     * it is checked.
     */
    @Override
    protected final ItemListener skipButtonListener() {
        return new ItemListener() {
            @Override
            public void itemStateChanged(final ItemEvent e) {
                buttonClass(nextButton()).setEnabled(true);
                skipButtonSetEnabled(false);
            }
        };
    }

    /** Enable next button, with skip button logic. */
    protected final void nextButtonSetEnabled(final Check check) {
        if (!skipButtonIsSelected()) {
            if (check.isCorrect()) {
                skipButtonSetEnabled(false);
            } else {
                skipButtonSetEnabled(true);
            }
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(nextButton()).setEnabledCorrect(check);
                    if (check.isCorrect()) {
                        makeDefaultAndRequestFocus(buttonClass(nextButton()));
                    }
                }
            });
        }
    }

    /** Returns icons for the buttons. */
    @Override
    protected final ImageIcon[] getIcons() {
        return new ImageIcon[]{null, BACK_ICON, NEXT_ICON, FINISH_ICON, CANCEL_ICON};
    }

    @Override
    protected final String defaultButton() {
        return null;
    }

    /** After next or finish buttons are pressed, this function is called. */
    protected final boolean checkAfterNextFinish() {
        return true;
    }

    /** After next or finish buttons are pressed, this function is called. */
    protected void finishDialog() {
        /* no action */
    }

    /** Returns next dialog, that follows after pressing next button. */
    public abstract WizardDialog nextDialog();

    /**
     * Enables components except the ones that are passed as the argument.
     */
    @Override
    protected final void enableComponents(final JComponent[] componentsToDisable) {
        super.enableComponents(componentsToDisable);
        application.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (buttonClass(retryButton()) != null
                    && buttonClass(retryButton()).isVisible()
                    && buttonClass(retryButton()).isEnabled()) {
                    makeDefaultAndRequestFocus(buttonClass(retryButton()));
                } else if (buttonClass(nextButton()) != null && buttonClass(nextButton()).isEnabled()) {
                    makeDefaultAndRequestFocus(buttonClass(nextButton()));
                } else if (buttonClass(finishButton()) != null && buttonClass(finishButton()).isEnabled()) {
                    makeDefaultAndRequestFocus(buttonClass(finishButton()));
                }
            }
        });
    }

    /** Requests focus. */
    protected final void makeDefaultAndRequestFocus(final java.awt.Component button) {
        if (button instanceof JButton) {
            getDialogPanel().getRootPane().setDefaultButton((JButton) button);
        }
        button.requestFocus();
    }

    protected final void makeDefaultAndRequestFocusLater(final java.awt.Component b) {
        application.invokeLater(new Runnable() {
            @Override
            public void run() {
                makeDefaultAndRequestFocus(b);
            }
        });
    }

    protected final void makeDefaultButton(final JButton b) {
        getDialogPanel().getRootPane().setDefaultButton(b);
    }

    @Override
    protected final void enableComponents() {
        enableComponents(new JComponent[]{});
    }

    @Override
    protected void initDialogBeforeVisible() {
        /* align buttons to the right */
        final FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.TRAILING);

        if (buttonClass(cancelButton()) != null) {
            buttonClass(cancelButton()).getParent().setLayout(layout);
        }

        /* disable back button if there is no previous dialog */
        if (previousDialog == null && buttonClass(backButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(backButton()).setEnabled(false);
                }
            });
        }

        /* disable next and finish buttons */
        if (buttonClass(nextButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(nextButton()).setEnabled(false);
                }
            });
        }
        if (buttonClass(finishButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(finishButton()).setEnabled(false);
                }
            });
        }
        if (buttonClass(retryButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(retryButton()).setVisible(false);
                    buttonClass(retryButton()).setBackgroundColor(Color.RED);
                }
            });
        }
        disableComponents();
    }

    /** if retry button was pressed this method will be executed. */
    protected final void retryWasPressed() {
        /* no action */
    }

    /** if back button was pressed this method will be executed. */
    protected final void backButtonWasPressed() {
        /* no action */
    }

    /**
     * Check which button was pressed. Return previous dialog if back button
     * was pressed. Call checkAfterNextFinish() if next or back button were
     * pressed. If checkAfterNextFinish() returns true return next dialog,
     * if next button was pressed.
     */
    @Override
    protected final ConfigDialog checkAnswer() {
        if (isPressedButton(backButton())) {
            backButtonWasPressed();
            return getPreviousDialog();
        }
        if (isPressedButton(nextButton()) || isPressedButton(finishButton()) || isPressedButton(retryButton())) {
            if (checkAfterNextFinish()) {
                finishDialog();
                if (isPressedButton(nextButton())) {
                    return nextDialog();
                } else if (isPressedButton(retryButton())) {
                    retryWasPressed();
                    setDialogPanel(null);
                    return this;
                } else {
                    return null;
                }
            } else {
                return this;
            }
        }
        return dialogAfterCancel();
    }

    /**
     * prints error text in the answer pane, reenables
     * buttons and adds retry button.
     */
    public void printErrorAndRetry(final String text) {
        printErrorAndRetry(text, null, 0);
    }

    /**
     * prints error text in the answer pane, reenables
     * buttons and adds retry button.
     */
    public final void printErrorAndRetry(String text, final String errorMessage, final int exitCode) {
        if (errorMessage != null) {
            text += '\n' + Tools.getString("Dialog.Dialog.PrintErrorAndRetry") + exitCode + '\n' + errorMessage;
        }
        answerPaneSetTextError(text);
        addRetryButton();
        if (buttonClass(retryButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(retryButton()).requestFocus();
                }
            });
        }
        final List<String> incorrect = new ArrayList<String>();
        incorrect.add(text);
        final List<String> changed = new ArrayList<String>();
        if (buttonClass(nextButton()) != null) {
            enableComponents(new JComponent[]{buttonClass(nextButton())});
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(nextButton()).setEnabledCorrect(new Check(incorrect, changed));
                }
            });
        }
    }

    /** Reenables buttons and adds retry button. */
    public final void retry() {
        addRetryButton();
        if (buttonClass(retryButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(retryButton()).requestFocus();
                }
            });
            if (buttonClass(nextButton()) != null) {
                enableComponents(new JComponent[]{buttonClass(nextButton())});
                application.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        buttonClass(nextButton()).setEnabled(false);
                    }
                });
            }
        }
    }

    /** Adds the retry button. */
    final void addRetryButton() {
        if (buttonClass(retryButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    getOptionPane().setInitialValue(buttonClass(retryButton()));
                }
            });
        }
        // setInitialValue destroys layout, so once
        // again...
        final FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.TRAILING);

        if (buttonClass(cancelButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    final Container parent = buttonClass(cancelButton()).getParent();
                    if (parent != null) {
                        buttonClass(cancelButton()).getParent().setLayout(layout);
                    }
                }
            });
        }

        if (buttonClass(retryButton()) != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    buttonClass(retryButton()).setVisible(true);
                    buttonClass(retryButton()).setEnabled(true);
                }
            });
        }
    }

    public final void hideRetryButton() {
        final MyButton retryButton = buttonClass(retryButton());

        if (retryButton != null && retryButton.isVisible()) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    retryButton.setVisible(false);
                }
            });
        }
    }

    public final void pressNextButton() {
        final MyButton nextButton = buttonClass(nextButton());
        if (nextButton != null) {
            application.invokeLater(new Runnable() {
                @Override
                public void run() {
                    if (nextButton.isVisible() && nextButton.isEnabled()) {
                        nextButton.pressButton();
                    }
                }
            });
        }
    }

    /**
     * Creates progress bar that can be used during connecting to the host
     * and returns pane, where the progress bar is displayed.
     */
    public JPanel getProgressBarPane(final CancelCallback cancelCallback) {
        progressBar = progressBarProvider.get();
        progressBar.init(cancelCallback);
        final JPanel progressPane = progressBar.getProgressBarPane();
        progressPane.setBackground(Tools.getDefaultColor("ConfigDialog.Background.Dark"));
        return progressPane;
    }

    /** Is called after failed connection. */
    public final void progressBarDoneError() {
        progressBar.doneError();
    }

    /** Is called after successful connection. */
    public final void progressBarDone() {
        progressBar.done();
    }

    public final ProgressBar getProgressBar() {
        return progressBar;
    }

    /**
     * Creates progress bar that can be used during connecting to the host
     * and returns pane, where the progress bar is displayed.
     */
    public final JPanel getProgressBarPane(final String title, final CancelCallback cancelCallback) {
        progressBar = progressBarProvider.get();
        progressBar.init(title, cancelCallback);
        final JPanel progressPane = progressBar.getProgressBarPane();
        progressPane.setBackground(Tools.getDefaultColor("ConfigDialog.Background.Dark"));
        return progressPane;
    }

    protected WizardDialog dialogAfterCancel() {
        return null;
    }
}
TOP

Related Classes of lcmc.common.ui.WizardDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.