/* * Copyright 2009 Alexis Wilhelm. This program is free software: you can do * anything, but lay off of my blue suede shoes. */ package com.izforge.izpack.panels; import java.util.List; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import com.izforge.izpack.LocaleDatabase; import com.izforge.izpack.gui.IzPanelLayout; import com.izforge.izpack.installer.InstallData; import com.izforge.izpack.installer.InstallerFrame; import com.izforge.izpack.installer.IzPanel; import com.sun.pkg.client.Fmri; import com.sun.pkg.client.Image; import com.sun.pkg.client.Image.FmriState; /** * A panel that allows the end user to upgrade or remove the software. It should * look like a IPSPanel. * <p> * Don't forget to put at least one IPSInstallPanel before this panel, and at * least one IPSInstallPanel after. Typical sequences implying this panel are * [IPSPacksPanel, IPSInstallPanel, IPSUpdatePanel, IPSInstallPanel] or * [IPSInstallPanel, IPSUpdatePanel, IPSPacksPanel, IPSInstallPanel]. * </p> * * @author Alexis Wilhelm * @since February 2009 * @see IPSPacksPanel * @see IPSInstallPanel */ public class IPSUpdatePanel extends IzPanel { /** * A table model useful for displaying the state of installed packages in an * IPS image. */ private static class FmriStateTableModel extends AbstractTableModel { /** * This allows this table to get serialized. */ private static final long serialVersionUID = 1L; /** * The names for the columns of this table's. */ private final String[] columnNames; /** * A list of the packages to be displayed in this table. */ private final List<FmriState> pkgs; /** * @param lang The localized strings. * @param pkgs A list of the packages to be displayed and their current * state. * @see Image#getInventory(String[], boolean) */ public FmriStateTableModel (LocaleDatabase lang, List<FmriState> pkgs) { this.pkgs = pkgs; columnNames = new String[] { lang.getString(this, "name"), lang.getString(this, "installed"), lang.getString(this, "upgradable") }; } /** * This is used for rendering strings as text, booleans as checkboxes, * and so forth... * * @param col The index of the queried column. * @return The data type displayed in the queried column. * @see AbstractTableModel#getColumnClass(int) */ @Override public Class<?> getColumnClass (int col) { return getValueAt(0, col).getClass(); } /** * {@inheritDoc} */ public int getColumnCount () { return columnNames.length; } /** * {@inheritDoc} */ @Override public String getColumnName (int col) { return columnNames[col]; } /** * {@inheritDoc} */ public int getRowCount () { return pkgs.size(); } /** * {@inheritDoc} */ public Object getValueAt (int row, int col) { switch (col) { case 0: Fmri pkg = pkgs.get(row).fmri; return String.format("%s (%s)", pkg.getName(), pkg.getAuthority()); case 1: return pkgs.get(row).installed; case 2: return pkgs.get(row).upgradable; default: return null; } } /** * Any column but the first is editable. The first column displays the * package's name while the others contain checkboxes. * * @param row The ordinate of the cell. * @param col The abscissa of the cell. * @return True when the user is allowed to edit the cell, false * otherwise. * @see AbstractTableModel#isCellEditable(int, int) */ @Override public boolean isCellEditable (int row, int col) { return col > 0; } /** * This allows the user to edit what's displayed in this table, that is, * whether a listed package should be installed/upgraded or not. * * @param value The new value for the selected cell. * @param row The ordinate of the selected cell. * @param col The abscissa of the selected cell. * @see AbstractTableModel#setValueAt(Object, int, int) */ @Override public void setValueAt (Object value, int row, int col) { switch (col) { case 1: pkgs.get(row).installed = (Boolean) value; break; case 2: pkgs.get(row).upgradable = (Boolean) value; break; default: return; } fireTableCellUpdated(row, col); } } /** * This allows this panel to get serialized. */ private static final long serialVersionUID = 1L; /** * Draw this panel. * * @param parent The frame hosting this panel. * @param data The all important object describing everything we need for * the installation. */ public IPSUpdatePanel (InstallerFrame parent, InstallData data) { super(parent, data, new IzPanelLayout()); add(new JScrollPane(new JTable(new FmriStateTableModel(idata.langpack, idata.installedIPSPackages)))); } /** * Draw this panel, or skip to the next panel if no package is installed. * This method gets called when this panel becomes active. * * @see IzPanel#panelActivate() */ @Override public void panelActivate () { super.panelActivate(); if (idata.installedIPSPackages.isEmpty()) { parent.skipPanel(); } } /** * Mark the selected packages either for update or for removal. The actual * update/removal will be done in the next IPSUnpacker. * * @see IzPanel#panelDeactivate() */ @Override public void panelDeactivate () { idata.selectedIPSPackages.clear(); idata.unwantedIPSPackages.clear(); for (FmriState pkg: idata.installedIPSPackages) { if (!pkg.installed) { idata.unwantedIPSPackages.add(pkg.fmri); } else if (pkg.upgradable) { idata.selectedIPSPackages.add(pkg.fmri); } } } }