com.salas.bb.updates.ui.NewVersionAvailableDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.salas.bb.updates.ui.NewVersionAvailableDialog.java

Source

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program 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 of the License, or (at your option) any later version.
//
// This program 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 this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: NewVersionAvailableDialog.java,v 1.13 2006/05/31 10:53:16 spyromus Exp $
//

package com.salas.bb.updates.ui;

import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.uif.AbstractDialog;
import com.jgoodies.uif.component.UIFButton;
import com.salas.bb.updates.CheckResult;
import com.salas.bb.updates.Location;
import com.salas.bb.utils.uif.*;
import com.salas.bb.utils.i18n.Strings;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

/**
 * Dialog to display information on new version available.
 */
public class NewVersionAvailableDialog extends AbstractDialog {
    private static final MessageFormat FMT_SINGLE_SELECTION = new MessageFormat(
            Strings.message("updates.click.download.to.save.the.new.version.0.mb.to.your.desktop"));
    private static final MessageFormat FMT_MULTI_SELECTION = new MessageFormat(
            Strings.message("updates.click.download.to.save.selected.files.0.mb.to.your.desktop"));

    private CheckResult checkResult;
    private Location[] applicableDownloads;
    private boolean mainPackageAvailable;

    private PackagesTableModel packagesModel;
    private JTable packagesTable;

    private JLabel lbDownloadSuggestion;
    private JCheckBox chShowAllDownloads;
    private UIFButton btnDownload;
    private Location mainPackage;

    /**
     * Creates dialog.
     *
     * @param frame parent frame.
     */
    public NewVersionAvailableDialog(Frame frame) {
        super(frame, Strings.message("updates.new.version.dialog.title"), true);
    }

    /**
     * Creates header.
     *
     * @return header.
     */
    protected JComponent buildHeader() {
        return new HeaderPanelExt(Strings.message("updates.new.version.dialog.title"),
                Strings.message("updates.new.version.dialog.header"));
    }

    /**
     * Builds dialog content.
     *
     * @return content component.
     */
    protected JComponent buildContent() {
        JPanel panel = new JPanel(new BorderLayout());

        panel.add(buildMainPanel(), BorderLayout.CENTER);
        panel.add(buildButtonBar(), BorderLayout.SOUTH);

        return panel;
    }

    /**
     * Builds dialog main panel.
     *
     * @return content component.
     */
    private Component buildMainPanel() {
        boolean severalPackagesAvailable = applicableDownloads.length > 1;

        BBFormBuilder builder = new BBFormBuilder("250dlu");

        builder.append(getWordingComponent(), 1, CellConstraints.FILL, CellConstraints.FILL);
        builder.appendUnrelatedComponentsGapRow(2);
        builder.append(Strings.message("updates.new.version.changes"), 1);
        builder.appendRelatedComponentsGapRow(2);
        builder.appendRow("50dlu");
        builder.append(getChangesTableComponent(), 1, CellConstraints.FILL, CellConstraints.FILL);

        // Show "Show all downloads" checkbox if several packages available.
        builder.appendRelatedComponentsGapRow(2);
        if (severalPackagesAvailable || (applicableDownloads.length == 1 && !mainPackageAvailable)) {
            final Component detailsPanel = createPackagesDetailsPanel();

            if (mainPackageAvailable) {
                builder.append(chShowAllDownloads);
            } else {
                builder.append(Strings.message("updates.new.version.availble.downloads"), 1);
            }

            builder.appendRelatedComponentsGapRow(2);
            builder.append(detailsPanel);

            detailsPanel.setVisible(!mainPackageAvailable);

            chShowAllDownloads.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    detailsPanel.setVisible(chShowAllDownloads.isSelected());
                    pack();
                }
            });
        }

        builder.append(lbDownloadSuggestion, 1);
        builder.appendUnrelatedComponentsGapRow();

        return builder.getPanel();
    }

    /**
     * Creates panel with package details.
     *
     * @return panel with packages details.
     */
    private Component createPackagesDetailsPanel() {
        BBFormBuilder builder = new BBFormBuilder("0:grow");

        builder.appendRow("50dlu");
        builder.append(getPackagesTableComponent(), 1, CellConstraints.FILL, CellConstraints.FILL);
        builder.appendRelatedComponentsGapRow();

        return builder.getPanel();
    }

    /**
     * Creates icon component.
     *
     * @return component.
     */
    private Component getIconComponent() {
        return new JLabel(IconSource.getIcon("logo.small.icon"));
    }

    /**
     * Creates component with new version wording.
     *
     * @return component.
     */
    private Component getWordingComponent() {
        CheckResult result = getCheckResult();

        return ComponentsFactory.createWrappedMultilineLabel(MessageFormat.format(
                Strings.message("updates.new.version.wording"), new Object[] { result.getRecentVersion() }));
    }

    /**
     * Creates changes table component.
     *
     * @return table.
     */
    private Component getChangesTableComponent() {
        CheckResult result = getCheckResult();

        ChangesTableModel model = new ChangesTableModel(result.getChanges());
        JTable table = new JTable(model);
        table.setShowGrid(false);
        table.setTableHeader(null);
        UifUtilities.setTableColWidth(table, 0, 20);
        table.setDefaultRenderer(Integer.class, new ChangeTypeRenderer());
        table.setEnabled(false);

        JScrollPane pane = new JScrollPane(table);
        pane.getViewport().setBackground(table.getBackground());

        return pane;
    }

    /**
     * Returns packages table.
     *
     * @return component.
     */
    private Component getPackagesTableComponent() {
        JScrollPane pane = new JScrollPane(packagesTable);
        pane.getViewport().setBackground(packagesTable.getBackground());

        return pane;
    }

    /**
     * Returns check result.
     *
     * @return check result.
     */
    private CheckResult getCheckResult() {
        return checkResult;
    }

    /**
     * Builds dialog buttons bar.
     *
     * @return content component.
     */
    private Component buildButtonBar() {
        UIFButton laterButton = createCancelButton();
        laterButton.setText(Strings.message("updates.new.version.later"));

        return ButtonBarFactory.buildRightAlignedBar(laterButton, btnDownload);
    }

    /**
     * Shows dialog.
     *
     * @param aCheckResult result of updates check with new version info.
     *
     * @throws NullPointerException if check result isn't specified.
     */
    public void open(CheckResult aCheckResult) {
        if (aCheckResult == null)
            throw new NullPointerException(Strings.error("updates.unspecified.check.result"));

        checkResult = aCheckResult;
        Map allLocations = checkResult.getLocations();
        applicableDownloads = selectApplicableDownloads(allLocations);

        List applicableTypes = Location.getApplicableTypes();
        String mainPackageType = (String) applicableTypes.get(0);
        mainPackage = (Location) allLocations.get(mainPackageType);
        mainPackageAvailable = mainPackage != null;

        initComponents();
        pack();

        super.open();
    }

    private void initComponents() {
        lbDownloadSuggestion = new JLabel();

        chShowAllDownloads = ComponentsFactory.createCheckBox(Strings.message("updates.new.version.show.all"));

        btnDownload = createOKButton(true);
        btnDownload.setText(Strings.message("updates.new.version.download"));
        btnDownload.setEnabled(getCheckResult().getLocations().size() > 0);

        packagesModel = new PackagesTableModel(applicableDownloads);
        packagesModel.addTableModelListener(new DownloadsSelectionListener());

        packagesTable = new JTable(packagesModel);
        packagesTable.setShowGrid(false);
        packagesTable.setTableHeader(null);
        UifUtilities.setTableColWidth(packagesTable, 0, 20);

        if (mainPackage != null)
            packagesModel.selectPackage(mainPackage);
        onDownloadsSelectionChange();
    }

    /**
     * Handles window events depending on the state of the <code>defaultCloseOperation</code>
     * property.
     *
     * @see #setDefaultCloseOperation
     */
    protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);

        if (e.getID() == WindowEvent.WINDOW_OPENED) {
            // Ensure that the dialog is correctly sized on opening
            pack();
        }
    }

    /**
     * Returns the list of applicable downloads.
     *
     * @param allLocations all available downloads.
     *
     * @return applicable list.
     */
    private static Location[] selectApplicableDownloads(Map allLocations) {
        Location[] locations = (Location[]) allLocations.values().toArray(new Location[0]);

        return Location.selectApplicable(locations);
    }

    /**
     * Dialog resizing hook.
     *
     * @param content dialog content.
     */
    protected void resizeHook(JComponent content) {
        //        Resizer.ONE2ONE.resizeDialogContent(content);
        super.resizeHook(content);
    }

    /**
     * Accepts only if some packages selected for download.
     */
    public void doAccept() {
        if (isPackagesSelected()) {
            super.doAccept();
        } else {
            JOptionPane.showMessageDialog(this,
                    Strings.message("updates.new.version.please.select.at.least.one.package"),
                    Strings.message("updates.new.version.dialog.title"), JOptionPane.INFORMATION_MESSAGE);
        }
    }

    /**
     * Returns <code>TRUE</code> if some packages selected.
     *
     * @return <code>TRUE</code> if some packages selected.
     */
    private boolean isPackagesSelected() {
        return getSelectedLocations().length > 0;
    }

    /**
     * Returns list of selected locations for download.
     *
     * @return list of selected locations for download.
     */
    public Location[] getSelectedLocations() {
        return packagesModel.getSelectedLocations();
    }

    private void onDownloadsSelectionChange() {
        Location[] selected = getSelectedLocations();
        boolean nothingSelected = selected.length == 0;

        String msg;

        if (nothingSelected) {
            msg = applicableDownloads.length > 0
                    ? Strings.message("updates.new.version.validation.nothing.selected")
                    : Strings.message("updates.new.version.validation.nothing.available");
        } else {
            MessageFormat format;
            if (selected.length == 1) {
                format = FMT_SINGLE_SELECTION;
            } else {
                format = FMT_MULTI_SELECTION;
            }

            msg = format.format(new Object[] { new Float(calculateTotalSizeInMegs(selected)) });
        }

        btnDownload.setEnabled(!nothingSelected);
        lbDownloadSuggestion.setText(msg);
    }

    /**
     * Returns cummulative size of downloads in megabytes.
     *
     * @param locations locations to sum.
     *
     * @return megabytes.
     */
    private static double calculateTotalSizeInMegs(Location[] locations) {
        long bytes = 0;

        for (int i = 0; i < locations.length; i++) {
            Location location = locations[i];
            bytes += location.getSize();
        }

        return bytes / 1024 / 1024;
    }

    /**
     * Listener of downloads selections changes.
     */
    private class DownloadsSelectionListener implements TableModelListener {
        /**
         * This fine grain notification tells listeners the exact range of cells, rows, or columns that
         * changed.
         */
        public void tableChanged(TableModelEvent e) {
            onDownloadsSelectionChange();
        }
    }
}