de.dal33t.powerfolder.ui.dialog.GenericDialog.java Source code

Java tutorial

Introduction

Here is the source code for de.dal33t.powerfolder.ui.dialog.GenericDialog.java

Source

/*
* Copyright 2004 - 2008 Christian Sprajc. All rights reserved.
*
* This file is part of PowerFolder.
*
* PowerFolder 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.
*
* PowerFolder 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 PowerFolder. If not, see <http://www.gnu.org/licenses/>.
*
* $Id$
*/
package de.dal33t.powerfolder.ui.dialog;

import static de.dal33t.powerfolder.ui.dialog.GenericDialogType.DEFAULT;
import static de.dal33t.powerfolder.ui.dialog.GenericDialogType.ERROR;
import static de.dal33t.powerfolder.ui.dialog.GenericDialogType.INFO;
import static de.dal33t.powerfolder.ui.dialog.GenericDialogType.QUESTION;
import static de.dal33t.powerfolder.ui.dialog.GenericDialogType.WARN;

import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;

import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * Replacement class for JOptionPane.
 */
public class GenericDialog {

    /**
     * Result if user simply clicks the close button top-right on dialog
     */
    public static final int NO_BUTTON_CLICKED_INDEX = -1;

    private static final Icon INFO_ICON_ICON;
    private static final Icon WARN_ICON_ICON;
    private static final Icon ERROR_ICON_ICON;
    private static final Icon QUESTION_ICON_ICON;

    private Window parent;
    private boolean neverAskAgainMode;
    private JCheckBox neverAskAgainCheckBox;
    private String title;
    private Icon icon;
    private JPanel innerPanel;
    private int initialSelection;
    private JButton[] buttons;
    private JButton helpButton;
    private ValueModel buttonModel;
    private JDialog dialog;
    private String[] mnemonics;
    private String neverAskAgainMnemonic;

    // Cache icons from the local system.
    static {
        INFO_ICON_ICON = UIManager.getIcon("OptionPane.informationIcon");
        WARN_ICON_ICON = UIManager.getIcon("OptionPane.warningIcon");
        ERROR_ICON_ICON = UIManager.getIcon("OptionPane.errorIcon");
        QUESTION_ICON_ICON = UIManager.getIcon("OptionPane.questionIcon");
    }

    /**
     * Generic dialog.
     * Flexible replacement for JOptionPane.
     * Should only be accessed via DialogFactory.
     *
     * @param parent
     * @param title
     * @param innerPanel
     * @param type
     * @param options
     * @param initialSelection
     * @param neverAskAgainText
     * @param helpLink
     */
    public GenericDialog(Window parent, String title, JPanel innerPanel, GenericDialogType type, String[] options,
            int initialSelection, String neverAskAgainText, JButton helpButton) {

        this.parent = parent;
        this.title = title;
        this.innerPanel = innerPanel;
        this.initialSelection = initialSelection;
        this.helpButton = helpButton;

        validateArgs(options);

        resolveMnemonics(options, neverAskAgainText);

        initComponents(neverAskAgainText, type, options);
    }

    private void initComponents(String neverAskAgainText, GenericDialogType type, String[] options) {

        buttonModel = new ValueHolder(NO_BUTTON_CLICKED_INDEX);

        neverAskAgainMode = neverAskAgainText != null && neverAskAgainText.trim().length() > 0;

        if (DEFAULT == type) {
            icon = null;
        } else if (INFO == type) {
            icon = INFO_ICON_ICON;
        } else if (WARN == type) {
            icon = WARN_ICON_ICON;
        } else if (ERROR == type) {
            icon = ERROR_ICON_ICON;
        } else if (QUESTION == type) {
            icon = QUESTION_ICON_ICON;
        } else {
            throw new IllegalArgumentException("Invalid type. Could not find icon for " + type);
        }

        buttons = new JButton[options.length];
        for (int i = 0; i < options.length; i++) {
            String option = options[i];
            String mnemonic = mnemonics[i];
            final int j = i;
            Action a = new AbstractAction(option) {
                public void actionPerformed(ActionEvent e) {
                    buttonModel.setValue(j);
                    dispose();
                }
            };
            JButton b = new JButton(a);
            if (mnemonic != null && mnemonic.length() > 0) {
                a.putValue(Action.MNEMONIC_KEY, (int) mnemonic.charAt(0));
            }
            buttons[i] = b;
        }

        if (neverAskAgainText != null) {
            neverAskAgainCheckBox = new JCheckBox(neverAskAgainText);
            if (neverAskAgainMnemonic != null) {
                neverAskAgainCheckBox.setMnemonic(neverAskAgainMnemonic.charAt(0));
            }
        }
    }

    public int display() {
        dialog = new JDialog(parent, title, Dialog.ModalityType.APPLICATION_MODAL);

        FormLayout layout = new FormLayout("3dlu, pref, 3dlu, pref:grow, 3dlu",
                "3dlu, pref:grow, 3dlu, pref, 3dlu, pref, 3dlu");

        PanelBuilder builder = new PanelBuilder(layout);
        CellConstraints cc = new CellConstraints();

        if (icon != null) {
            builder.add(new JLabel(icon), cc.xy(2, 2, "center, top"));
        }
        builder.add(innerPanel, cc.xy(4, 2, "center, center"));

        if (neverAskAgainCheckBox != null) {
            builder.add(neverAskAgainCheckBox, cc.xywh(2, 4, 3, 1));
        }

        FormLayout barLayout;
        if (helpButton == null) {
            barLayout = new FormLayout("pref", "pref");
        } else {
            barLayout = new FormLayout("pref, 3dlu, pref", "pref");
        }
        PanelBuilder barBuilder = new PanelBuilder(barLayout);
        ButtonBarBuilder bar = ButtonBarBuilder.createLeftToRightBuilder();
        int i = 0;
        for (JButton button : buttons) {
            bar.addRelatedGap();
            bar.addGridded(button);
            if (initialSelection == i++) {
                dialog.getRootPane().setDefaultButton(button);
            }
        }
        barBuilder.add(bar.getPanel(), cc.xy(1, 1));
        if (helpButton != null) {
            barBuilder.add(helpButton, cc.xy(3, 1));
        }
        builder.add(barBuilder.getPanel(), cc.xywh(2, 6, 3, 1, "center, center"));

        dialog.getContentPane().add(builder.getPanel());
        dialog.getContentPane().setSize(innerPanel.getPreferredSize().width, innerPanel.getPreferredSize().height);
        dialog.pack();
        if (parent != null && parent.isVisible()) {
            int x = parent.getX() + (parent.getWidth() - dialog.getWidth()) / 2;
            int y = parent.getY() + (parent.getHeight() - dialog.getHeight()) / 2;
            dialog.setLocation(x, y);
        } else {
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (int) (screenSize.getWidth() - dialog.getWidth()) / 2;
            int y = (int) (screenSize.getHeight() - dialog.getHeight()) / 2;
            dialog.setLocation(x, y);
        }

        dialog.setVisible(true);

        return (Integer) buttonModel.getValue();
    }

    public boolean isNeverAskAgain() throws IllegalStateException {
        if (!neverAskAgainMode) {
            throw new IllegalStateException("You cannot request the NeverAskAgain state "
                    + "for GenericDialogs that did not set " + "neverAskAgainText in the constructor");
        }
        return neverAskAgainCheckBox.isSelected();
    }

    private void validateArgs(String[] options) {

        if (innerPanel == null) {
            throw new IllegalArgumentException("Expected a innerPanel to display");
        }

        if (title == null || title.trim().length() == 0) {
            throw new IllegalArgumentException("Expected a title to display");
        }

        if (options == null) {
            throw new IllegalArgumentException("Missing options");
        } else if (initialSelection < 0 || initialSelection >= options.length) {
            throw new IllegalArgumentException("Invalid initialSelection");
        }
    }

    private void dispose() {
        if (dialog != null) {
            dialog.setVisible(false);
            dialog.dispose();
        }
    }

    /**
     * Automatically create mnemonics for the options.
     * Prevernts the nightmare of i18n mnemonic collisions.
     * First tries to find the first available capital leter,
     * then lower case letters.
     *
     * @param options
     */
    private void resolveMnemonics(String[] options, String neverAskAgainText) {

        mnemonics = new String[options.length];

        // First pass, look for capitals.
        for (int i = 0; i < options.length; i++) {
            String option = options[i];
            for (int j = 0; j < option.length(); j++) {
                String c = option.substring(j, j + 1);
                if (!c.equals(" ") && c.toUpperCase().equals(c)) {
                    // See if this is in the mnemonics.
                    if (!inMnemonics(c)) {
                        mnemonics[i] = c;
                        break;
                    }
                }
            }
        }

        // Second pass, look for any case.
        for (int i = 0; i < options.length; i++) {
            if (mnemonics[i] == null) {
                String option = options[i];
                for (int j = 0; j < option.length(); j++) {
                    String c = option.substring(j, j + 1);
                    // See if this is in the mnemonics.
                    if (!c.equals(" ") && !inMnemonics(c)) {
                        mnemonics[i] = c;
                        break;
                    }
                }
            }
        }

        // Try to set mnemonic for neverAsk.
        if (neverAskAgainText != null && neverAskAgainText.trim().length() > 0) {
            for (int j = 0; j < neverAskAgainText.length(); j++) {
                String c = neverAskAgainText.substring(j, j + 1);
                if (!c.equals(" ") && c.toUpperCase().equals(c)) {
                    // See if this is in the mnemonics.
                    if (!inMnemonics(c)) {
                        neverAskAgainMnemonic = c;
                        return;
                    }
                }
            }
            for (int j = 0; j < neverAskAgainText.length(); j++) {
                String c = neverAskAgainText.substring(j, j + 1);
                // See if this is in the mnemonics.
                if (!c.equals(" ") && !inMnemonics(c)) {
                    neverAskAgainMnemonic = c;
                    return;
                }
            }
        }
    }

    private boolean inMnemonics(String c) {
        for (String mnemonic : mnemonics) {
            if (mnemonic != null && mnemonic.equals(c)) {
                return true;
            }
        }
        return false;
    }

}