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