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

Java tutorial

Introduction

Here is the source code for de.dal33t.powerfolder.ui.dialog.BaseDialog.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 java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.*;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import de.dal33t.powerfolder.Controller;
import de.dal33t.powerfolder.ui.PFUIComponent;
import de.dal33t.powerfolder.ui.util.CursorUtils;
import de.dal33t.powerfolder.ui.util.UIUtil;
import de.dal33t.powerfolder.util.Translation;

/**
 * A basic class for all dialogs. It offers the posibility to set and icon and
 * create a customized ButtonBar.
 * <p>
 * Overwrite the abstract methods. A graphical help, how the elemnts will be
 * aligned is available at the developer documentation.
 * <p>
 * Link: http://download.powerfolder.com/development-docs/BaseDialogHelp.GIF
 *
 * @author <a href="mailto:totmacher@powerfolder.com">Christian Sprajc </a>
 * @version $Revision: 1.3 $
 */
public abstract class BaseDialog extends PFUIComponent {

    private static final AtomicInteger NUMBER_OF_OPEN_DIALOGS = new AtomicInteger();

    /**
     * Used to decide which owner the dialog gets.
     */
    public enum Senior {
        NONE, MAIN_FRAME
    }

    private final Senior senior;
    private final boolean modal;
    private boolean resizable;

    protected JDialog dialog;

    // Make sure open / close count change fires exactly once per instance.
    private final AtomicBoolean doneWizardClose = new AtomicBoolean();

    /**
     * Are there any open dilogs?
     *
     * @return
     */
    public static boolean isDialogOpen() {
        return NUMBER_OF_OPEN_DIALOGS.get() > 0;
    }

    /**
     * Initializes the base dialog.
     *
     * @param senior
     *            the component to be modal to and to locate on
     * @param controller
     *            the controller
     * @param modal
     *            if dialog should be modal
     */
    protected BaseDialog(Senior senior, Controller controller, boolean modal) {
        super(controller);
        this.senior = senior;
        this.modal = modal;
        NUMBER_OF_OPEN_DIALOGS.incrementAndGet();
        //controller.getUIController().getMainFrame().checkOnTop();
    }

    /**
     * Initializes the base dialog.
     *
     * @param senior
     *            the component to be modal to and to locate on\
     * @param controller
     *            the controller
     * @param modal
     *            if dialog should be modal
     * @param resizable
     *           if dialog is resizable
     */
    protected BaseDialog(Senior senior, Controller controller, boolean modal, boolean resizable) {
        this(senior, controller, modal);
        this.resizable = resizable;
    }

    /**
     * Make absolutely sure decrementOpenDialogs() gets called.
     * Should have been called by Window closed / closing.
     *
     * @throws Throwable
     */
    protected void finalize() throws Throwable {
        try {
            decrementOpenDialogCount();
        } finally {
            super.finalize();
        }
    }

    private void decrementOpenDialogCount() {
        if (!doneWizardClose.getAndSet(true)) {
            NUMBER_OF_OPEN_DIALOGS.decrementAndGet();
            //getController().getUIController().getMainFrame().checkOnTop();
        }
    }

    // Abstract methods *******************************************************

    /**
     * The title of this base dialog
     *
     * @return
     */
    public abstract String getTitle();

    /**
     * Returns the icon of this dialog Mehod may return null, no icon will be
     * displayed
     *
     * @return
     */
    protected abstract Icon getIcon();

    /**
     * Method should return the main content of this panel displayed on the
     * right side over the buttonbar.
     *
     * @return component
     */
    protected abstract JComponent getContent();

    /**
     * This is the button to make the default button for the dialog.
     *
     * @return default button
     */
    protected abstract JButton getDefaultButton();

    /**
     * Method should return the button bar on the lower side of the dialog
     *
     * @return the component
     */
    protected abstract Component getButtonBar();

    // Helper methods *********************************************************

    /**
     * Creates an internationlaized ok button
     *
     * @param listener
     *            the listener to be put on the button
     * @return
     */
    protected static JButton createOKButton(ActionListener listener) {
        JButton okButton = new JButton(Translation.getTranslation("general.ok"));
        okButton.setMnemonic(Translation.getTranslation("general.ok.key").trim().charAt(0));
        okButton.addActionListener(listener);
        return okButton;
    }

    /**
     * Creates an internationlaized cancel button
     *
     * @param listener
     *            the listener to be put on the button
     * @return
     */
    protected static JButton createCancelButton(ActionListener listener) {
        JButton cancelButton = new JButton(Translation.getTranslation("general.cancel"));
        cancelButton.setMnemonic(Translation.getTranslation("general.cancel.key").trim().charAt(0));
        cancelButton.addActionListener(listener);
        return cancelButton;
    }

    /**
     * Creates an internationlaized close button
     *
     * @param listener
     *            the listener to be put on the button
     * @return
     */
    protected static JButton createCloseButton(ActionListener listener) {
        JButton closeButton = new JButton(Translation.getTranslation("general.close"));
        closeButton.setMnemonic(Translation.getTranslation("general.close.key").trim().charAt(0));
        closeButton.addActionListener(listener);
        return closeButton;
    }

    /**
     * Shows (and builds) the dialog.
     */
    public JDialog open() {
        Window window = getUIController().getActiveFrame();
        Cursor c = CursorUtils.setWaitCursor(window);
        try {
            createUIComponent();
            UIUtil.putOnScreen(dialog);
            dialog.setVisible(true);
            return dialog;
        } finally {
            CursorUtils.returnToOriginal(window, c);
        }
    }

    /**
     * Disposes the dialog.
     */
    public void close() {
        if (dialog != null) {
            dialog.dispose();
            dialog = null;
        }
    }

    private class CloseAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            close();
        }
    }

    protected void rePack() {
        if (dialog == null) {
            throw new IllegalStateException("Must be open to rePack");
        }
        dialog.pack();
    }

    /**
     * Build
     *
     * @return
     */
    private void createUIComponent() {
        Window owner = null;
        if (senior == Senior.MAIN_FRAME) {
            owner = getUIController().getMainFrame().getUIComponent();
        }
        dialog = new JDialog(owner, getTitle(), modal ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS);
        dialog.setResizable(resizable);
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        FormLayout layout = new FormLayout("pref, pref:grow", "fill:pref:grow, 10dlu, fill:pref");
        PanelBuilder builder = new PanelBuilder(layout);
        CellConstraints cc = new CellConstraints();

        Icon icon = getIcon();
        JLabel iconLabel = icon != null ? new JLabel(getIcon()) : null;
        if (iconLabel != null) {
            iconLabel.setBorder(Borders.createEmptyBorder("3dlu, 3dlu, 3dlu, 3dlu"));
            builder.add(iconLabel, cc.xywh(1, 1, 1, 1, "right, top"));
        }

        JComponent content = getContent();
        content.setBorder(Borders.createEmptyBorder("3dlu, 3dlu, 3dlu, 3dlu"));
        builder.add(content, cc.xy(2, 1));
        Component buttonBar = getButtonBar();
        ((JComponent) buttonBar).setBorder(Borders.createEmptyBorder("3dlu, 3dlu, 3dlu, 3dlu"));
        builder.add(buttonBar, cc.xyw(1, 3, 2));

        // Add panel to component
        dialog.getContentPane().add(builder.getPanel());

        dialog.getRootPane().setDefaultButton(getDefaultButton());

        // Add escape key as close
        KeyStroke strokeEsc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        JComponent rootPane = dialog.getRootPane();
        rootPane.registerKeyboardAction(new CloseAction(), strokeEsc, JComponent.WHEN_IN_FOCUSED_WINDOW);

        dialog.pack();
        int ownerX;
        int ownerY;
        int ownerWidth;
        int ownerHeight;

        if (owner != null && owner.isVisible() && senior == Senior.MAIN_FRAME) {
            ownerX = owner.getX();
            ownerY = owner.getY();
            ownerWidth = owner.getWidth();
            ownerHeight = owner.getHeight();
        } else {
            // Senior.NONE centers dialog on the screen.
            ownerX = 0;
            ownerY = 0;
            ownerWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
            ownerHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        }
        int x = ownerX + (ownerWidth - dialog.getWidth()) / 2;
        int y = ownerY + (ownerHeight - dialog.getHeight()) / 2;
        dialog.setLocation(x, y);

        // Decrement open dialog count on close.
        dialog.addWindowListener(new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
                decrementOpenDialogCount();
            }

            public void windowClosing(WindowEvent e) {
                decrementOpenDialogCount();
            }
        });
    }
}