Java tutorial
/* * 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(); } }); } }