All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.izforge.izpack.panels.PacksPanelBase Maven / Gradle / Ivy

/*
 * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
 * 
 * http://izpack.org/
 * http://izpack.codehaus.org/
 * 
 * Copyright 2002 Marcus Wolschon
 * Copyright 2002 Jan Blok
 * Copyright 2004 Klaus Bartz
 * Copyright 2007 Dennis Reil
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.izforge.izpack.panels;

import com.izforge.izpack.LocaleDatabase;
import com.izforge.izpack.Pack;
import com.izforge.izpack.gui.LabelFactory;
import com.izforge.izpack.installer.*;
import com.izforge.izpack.util.Debug;
import com.izforge.izpack.util.IoHelper;
import com.izforge.izpack.util.VariableSubstitutor;
import net.n3.nanoxml.XMLElement;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * The base class for Packs panels. It brings the common member and methods of the different packs
 * panels together. This class handles the common logic of pack selection. The derived class should
 * be create the layout and other specific actions. There are some helper methods to simplify layout
 * creation in the derived class.
 *
 * @author Julien Ponge
 * @author Klaus Bartz
 * @author Dennis Reil
 */
public abstract class PacksPanelBase extends IzPanel implements PacksPanelInterface,
        ListSelectionListener
{

    // Common used Swing fields
    /**
     * The free space label.
     */
    protected JLabel freeSpaceLabel;

    /**
     * The space label.
     */
    protected JLabel spaceLabel;

    /**
     * The tip label.
     */
    protected JTextArea descriptionArea;

    /**
     * The dependencies label.
     */
    protected JTextArea dependencyArea;

    /**
     * The packs table.
     */
    protected JTable packsTable;

    /**
     * The packs model.
     */
    protected PacksModel packsModel;

    /**
     * The tablescroll.
     */
    protected JScrollPane tableScroller;

    // Non-GUI fields
    /**
     * Map that connects names with pack objects
     */
    private Map names;

    /**
     * The bytes of the current pack.
     */
    protected long bytes = 0;

    /**
     * The free bytes of the current selected disk.
     */
    protected long freeBytes = 0;

    /**
     * Are there dependencies in the packs
     */
    protected boolean dependenciesExist = false;

    /**
     * The packs locale database.
     */
    private LocaleDatabase langpack = null;

    /**
     * The name of the XML file that specifies the panel langpack
     */
    private static final String LANG_FILE_NAME = "packsLang.xml";

    private Debugger debugger;

    /**
     * The constructor.
     *
     * @param parent The parent window.
     * @param idata  The installation data.
     */
    public PacksPanelBase(InstallerFrame parent, InstallData idata)
    {
        super(parent, idata);
        // Load langpack.
        try
        {
            this.langpack = parent.langpack;
            InputStream inputStream = ResourceManager.getInstance().getInputStream(LANG_FILE_NAME);
            this.langpack.add(inputStream);
            this.debugger = parent.getDebugger();
        }
        catch (Throwable exception)
        {
            Debug.trace(exception);
        }
        // init the map
        computePacks(idata.availablePacks);

        createNormalLayout();
    }

    /**
     * The Implementation of this method should create the layout for the current class.
     */
    abstract protected void createNormalLayout();

    /*
     * (non-Javadoc)
     * 
     * @see com.izforge.izpack.panels.PacksPanelInterface#getLangpack()
     */
    public LocaleDatabase getLangpack()
    {
        return (langpack);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.izforge.izpack.panels.PacksPanelInterface#getBytes()
     */
    public long getBytes()
    {
        return bytes;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.izforge.izpack.panels.PacksPanelInterface#setBytes(int)
     */
    public void setBytes(long bytes)
    {
        this.bytes = bytes;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.izforge.izpack.panels.PacksPanelInterface#showSpaceRequired()
     */
    public void showSpaceRequired()
    {
        if (spaceLabel != null)
        {
            spaceLabel.setText(Pack.toByteUnitsString(bytes));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.izforge.izpack.panels.PacksPanelInterface#showFreeSpace()
     */
    public void showFreeSpace()
    {
        if (IoHelper.supported("getFreeSpace") && freeSpaceLabel != null)
        {
            String msg;
            freeBytes = IoHelper.getFreeSpace(IoHelper.existingParent(
                    new File(idata.getInstallPath())).getAbsolutePath());
            if (freeBytes < 0)
            {
                msg = parent.langpack.getString("PacksPanel.notAscertainable");
            }
            else
            {
                msg = Pack.toByteUnitsString(freeBytes);
            }
            freeSpaceLabel.setText(msg);
        }
    }

    /**
     * Indicates wether the panel has been validated or not.
     *
     * @return true if the needed space is less than the free space, else false
     */
    public boolean isValidated()
    {
        if (IoHelper.supported("getFreeSpace") && freeBytes >= 0 && freeBytes <= bytes)
        {
            JOptionPane.showMessageDialog(this, parent.langpack
                    .getString("PacksPanel.notEnoughSpace"), parent.langpack
                    .getString("installer.error"), JOptionPane.ERROR_MESSAGE);
            return (false);
        }
        return (true);
    }

    /**
     * Asks to make the XML panel data.
     *
     * @param panelRoot The XML tree to write the data in.
     */
    public void makeXMLData(XMLElement panelRoot)
    {
        new ImgPacksPanelAutomationHelper().makeXMLData(idata, panelRoot);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
     */
    public void valueChanged(ListSelectionEvent e)
    {
        int selectedRow = packsTable.getSelectedRow();

        // Operations for the description
        if ((descriptionArea != null) && (selectedRow != -1))
        {
            Pack pack = (Pack) idata.availablePacks.get(selectedRow);
            String desc = "";
            String key = pack.id + ".description";
            if (langpack != null && pack.id != null && !"".equals(pack.id))
            {
                desc = langpack.getString(key);
            }
            if ("".equals(desc) || key.equals(desc))
            {
                desc = pack.description;
            }
            VariableSubstitutor vs = new VariableSubstitutor(idata.getVariables());
            desc = vs.substitute(desc, null);
            descriptionArea.setText(desc);
        }
        // Operation for the dependency listing
        if ((dependencyArea != null) && (selectedRow != -1))
        {
            Pack pack = (Pack) idata.availablePacks.get(selectedRow);
            List dep = pack.dependencies;
            String list = "";
            if (dep != null)
            {
                list += (langpack == null) ? "Dependencies: " : langpack
                        .getString("PacksPanel.dependencies");
            }
            for (int j = 0; dep != null && j < dep.size(); j++)
            {
                String name = dep.get(j);
                list += getI18NPackName(names.get(name));
                if (j != dep.size() - 1)
                {
                    list += ", ";
                }
            }

            // add the list of the packs to be excluded
            String excludeslist = (langpack == null) ? "Excludes: " : langpack
                    .getString("PacksPanel.excludes");
            int numexcludes = 0;
            if (pack.excludeGroup != null)
            {
                for (int q = 0; q < idata.availablePacks.size(); q++)
                {
                    Pack otherpack = (Pack) idata.availablePacks.get(q);
                    String exgroup = otherpack.excludeGroup;
                    if (exgroup != null)
                    {
                        if (q != selectedRow && pack.excludeGroup.equals(exgroup))
                        {

                            excludeslist += getI18NPackName(otherpack) + ", ";
                            numexcludes++;
                        }
                    }
                }
            }
            // concatenate
            if (dep != null)
            {
                excludeslist = "    " + excludeslist;
            }
            if (numexcludes > 0)
            {
                list += excludeslist;
            }
            if (list.endsWith(", "))
            {
                list = list.substring(0, list.length() - 2);
            }

            // and checkbox the result
            dependencyArea.setText(list);
        }
    }

    /**
     * This method tries to resolve the localized name of the given pack. If this is not possible,
     * the name given in the installation description file in ELEMENT  will be used.
     *
     * @param pack for which the name should be resolved
     * @return localized name of the pack
     */
    private String getI18NPackName(Pack pack)
    {
        // Internationalization code
        String packName = pack.name;
        String key = pack.id;
        if (langpack != null && pack.id != null && !"".equals(pack.id))
        {
            packName = langpack.getString(key);
        }
        if ("".equals(packName) || key == null || key.equals(packName))
        {
            packName = pack.name;
        }
        return (packName);
    }

    /**
     * Layout helper method:
* Creates an label with a message given by msgId and an icon given by the iconId. If layout and * constraints are not null, the label will be added to layout with the given constraints. The * label will be added to this object. * * @param msgId identifier for the IzPack langpack * @param iconId identifier for the IzPack icons * @param layout layout to be used * @param constraints constraints to be used * @return the created label */ protected JLabel createLabel(String msgId, String iconId, GridBagLayout layout, GridBagConstraints constraints) { JLabel label = LabelFactory.create(parent.langpack.getString(msgId), parent.icons .getImageIcon(iconId), TRAILING); if (layout != null && constraints != null) { layout.addLayoutComponent(label, constraints); } add(label); return (label); } /** * Creates a panel containing a anonymous label on the left with the message for the given msgId * and a label on the right side with initial no text. The right label will be returned. If * layout and constraints are not null, the label will be added to layout with the given * constraints. The panel will be added to this object. * * @param msgId identifier for the IzPack langpack * @param layout layout to be used * @param constraints constraints to be used * @return the created (right) label */ protected JLabel createPanelWithLabel(String msgId, GridBagLayout layout, GridBagConstraints constraints) { JPanel panel = new JPanel(); JLabel label = new JLabel(); panel.setAlignmentX(LEFT_ALIGNMENT); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.add(LabelFactory.create(parent.langpack.getString(msgId))); panel.add(Box.createHorizontalGlue()); panel.add(label); if (layout != null && constraints != null) { layout.addLayoutComponent(panel, constraints); } add(panel); return (label); } /** * Creates a text area with standard settings and the title given by the msgId. If scroller is * not null, the create text area will be added to the scroller and the scroller to this object, * else the text area will be added directly to this object. If layout and constraints are not * null, the text area or scroller will be added to layout with the given constraints. The text * area will be returned. * * @param msgId identifier for the IzPack langpack * @param scroller the scroller to be used * @param layout layout to be used * @param constraints constraints to be used * @return the created text area */ protected JTextArea createTextArea(String msgId, JScrollPane scroller, GridBagLayout layout, GridBagConstraints constraints) { JTextArea area = new JTextArea(); // area.setMargin(new Insets(2, 2, 2, 2)); area.setAlignmentX(LEFT_ALIGNMENT); area.setCaretPosition(0); area.setEditable(false); area.setEditable(false); area.setOpaque(false); area.setLineWrap(true); area.setWrapStyleWord(true); area.setBorder(BorderFactory.createTitledBorder(parent.langpack.getString(msgId))); area.setFont(getControlTextFont()); if (layout != null && constraints != null) { if (scroller != null) { layout.addLayoutComponent(scroller, constraints); } else { layout.addLayoutComponent(area, constraints); } } if (scroller != null) { scroller.setViewportView(area); add(scroller); } else { add(area); } return (area); } /** * Creates the table for the packs. All parameters are required. The table will be returned. * * @param width of the table * @param scroller the scroller to be used * @param layout layout to be used * @param constraints constraints to be used * @return the created table */ protected JTable createPacksTable(int width, JScrollPane scroller, GridBagLayout layout, GridBagConstraints constraints) { JTable table = new JTable(); table.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2)); table.setIntercellSpacing(new Dimension(0, 0)); table.setBackground(Color.white); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.getSelectionModel().addListSelectionListener(this); table.setShowGrid(false); scroller.setViewportView(table); scroller.setAlignmentX(LEFT_ALIGNMENT); scroller.getViewport().setBackground(Color.white); scroller.setPreferredSize(new Dimension(width, (idata.guiPrefs.height / 3 + 30))); if (layout != null && constraints != null) { layout.addLayoutComponent(scroller, constraints); } add(scroller); return (table); } /** * Computes pack related data like the names or the dependencies state. * * @param packs The list of packs. */ private void computePacks(List packs) { names = new HashMap(); dependenciesExist = false; for (Object pack1 : packs) { Pack pack = (Pack) pack1; names.put(pack.name, pack); if (pack.dependencies != null || pack.excludeGroup != null) { dependenciesExist = true; } } } /** * Called when the panel becomes active. If a derived class implements this method also, it is * recomanded to call this method with the super operator first. */ public void panelActivate() { try { packsModel = new PacksModel(this, idata, this.parent.getRules()) { @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } }; packsTable.setModel(packsModel); CheckBoxRenderer packSelectedRenderer = new CheckBoxRenderer(); packsTable.getColumnModel().getColumn(0).setCellRenderer(packSelectedRenderer); packsTable.getColumnModel().getColumn(0).setMaxWidth(40); packsTable.getColumnModel().getColumn(1).setCellRenderer(new PacksPanelTableCellRenderer()); PacksPanelTableCellRenderer packTextColumnRenderer = new PacksPanelTableCellRenderer(); packTextColumnRenderer.setHorizontalAlignment(RIGHT); packsTable.getColumnModel().getColumn(2).setCellRenderer(packTextColumnRenderer); packsTable.getColumnModel().getColumn(2).setMaxWidth(100); packsTable.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent event) { int row = packsTable.rowAtPoint(event.getPoint()); int col = packsTable.columnAtPoint(event.getPoint()); if (col == 0) { Integer checked = (Integer) packsModel.getValueAt(row, 0); checked = (checked == 0) ? 1 : 0; packsModel.setValueAt(checked, row, 0); packsTable.repaint(); } } }); // remove header,so we don't need more strings tableScroller.remove(packsTable.getTableHeader()); tableScroller.setColumnHeaderView(null); tableScroller.setColumnHeader(null); // set the JCheckBoxes to the currently selected panels. The // selection might have changed in another panel java.util.Iterator iter = idata.availablePacks.iterator(); bytes = 0; while (iter.hasNext()) { Pack p = (Pack) iter.next(); if (p.required) { bytes += p.nbytes; continue; } if (idata.selectedPacks.contains(p)) { bytes += p.nbytes; } } } catch (Exception e) { e.printStackTrace(); } showSpaceRequired(); showFreeSpace(); packsTable.setRowSelectionInterval(0, 0); } /* * (non-Javadoc) * * @see com.izforge.izpack.installer.IzPanel#getSummaryBody() */ public String getSummaryBody() { StringBuffer retval = new StringBuffer(256); Iterator iter = idata.selectedPacks.iterator(); boolean first = true; while (iter.hasNext()) { if (!first) { retval.append("
"); } first = false; Pack pack = (Pack) iter.next(); if (langpack != null && pack.id != null && !"".equals(pack.id)) { retval.append(langpack.getString(pack.id)); } else { retval.append(pack.name); } } if (packsModel.isModifyinstallation()) { Map installedpacks = packsModel.getInstalledpacks(); iter = installedpacks.keySet().iterator(); retval.append("
"); retval.append(langpack.getString("PacksPanel.installedpacks.summarycaption")); retval.append(""); retval.append("
"); while (iter.hasNext()) { Pack pack = (Pack) installedpacks.get(iter.next()); if (langpack != null && pack.id != null && !"".equals(pack.id)) { retval.append(langpack.getString(pack.id)); } else { retval.append(pack.name); } retval.append("
"); } } return (retval.toString()); } static class CheckBoxRenderer implements TableCellRenderer { JCheckBox checkbox = new JCheckBox(); CheckBoxRenderer() { if (com.izforge.izpack.util.OsVersion.IS_UNIX && !com.izforge.izpack.util.OsVersion.IS_OSX) { checkbox.setIcon(new LFIndependentIcon()); checkbox.setDisabledIcon(new LFIndependentIcon()); checkbox.setSelectedIcon(new LFIndependentIcon()); checkbox.setDisabledSelectedIcon(new LFIndependentIcon()); } checkbox.setHorizontalAlignment(CENTER); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { checkbox.setForeground(table.getSelectionForeground()); checkbox.setBackground(table.getSelectionBackground()); } else { checkbox.setForeground(table.getForeground()); checkbox.setBackground(table.getBackground()); } int state = (Integer) value; if (state == -2) { // condition not fulfilled checkbox.setForeground(Color.GRAY); } if (state == -3) { checkbox.setForeground(Color.RED); checkbox.setSelected(true); } checkbox.setEnabled(state >= 0); checkbox.setSelected((value != null && Math.abs(state) == 1)); return checkbox; } } public static class LFIndependentIcon implements Icon { ButtonModel buttonModel = null; protected int getControlSize() { return 13; } public void paintIcon(Component c, Graphics g, int x, int y) { ButtonModel model = ((JCheckBox) c).getModel(); buttonModel = model; int controlSize = getControlSize(); if (model.isPressed() && model.isArmed()) { g.setColor(MetalLookAndFeel.getControlShadow()); if (model.isEnabled()) { g.setColor(Color.green); } else { g.setColor(Color.gray); } g.fillRect(x, y, controlSize - 1, controlSize - 1); drawPressedBorder(g, x, y, controlSize, controlSize, model); } else { drawBorder(g, x, y, controlSize, controlSize, model); } g.setColor(Color.green); if (model.isSelected()) { drawCheck(g, x, y); } } private void drawBorder(Graphics g, int x, int y, int w, int h, ButtonModel model) { g.translate(x, y); // outer frame rectangle g.setColor(MetalLookAndFeel.getControlDarkShadow()); if (!model.isEnabled()) { g.setColor(new Color(0.4f, 0.4f, 0.4f)); } g.drawRect(0, 0, w - 2, h - 2); // middle frame g.setColor(MetalLookAndFeel.getControlHighlight()); if (!model.isEnabled()) { g.setColor(new Color(0.6f, 0.6f, 0.6f)); } g.drawRect(1, 1, w - 2, h - 2); // background if (model.isEnabled()) { g.setColor(Color.white); } else { g.setColor(new Color(0.8f, 0.8f, 0.8f)); } g.fillRect(2, 2, w - 3, h - 3); //some extra lines for FX g.setColor(MetalLookAndFeel.getControl()); g.drawLine(0, h - 1, 1, h - 2); g.drawLine(w - 1, 0, w - 2, 1); g.translate(-x, -y); } private void drawPressedBorder(Graphics g, int x, int y, int w, int h, ButtonModel model) { g.translate(x, y); drawBorder(g, 0, 0, w, h, model); g.setColor(MetalLookAndFeel.getControlShadow()); g.drawLine(1, 1, 1, h - 2); g.drawLine(1, 1, w - 2, 1); g.drawLine(2, 2, 2, h - 3); g.drawLine(2, 2, w - 3, 2); g.translate(-x, -y); } protected void drawCheck(Graphics g, int x, int y) { int controlSize = getControlSize(); if (buttonModel != null) { if (buttonModel.isEnabled()) { g.setColor(new Color(0.0f, 0.6f, 0.0f)); } else { g.setColor(new Color(0.1f, 0.1f, 0.1f)); } } g.drawLine(x + (controlSize - 4), y + 2, x + (controlSize - 4) - 4, y + 2 + 4); g.drawLine(x + (controlSize - 4), y + 3, x + (controlSize - 4) - 4, y + 3 + 4); g.drawLine(x + (controlSize - 4), y + 4, x + (controlSize - 4) - 4, y + 4 + 4); g.drawLine(x + (controlSize - 4) - 4, y + 2 + 4, x + (controlSize - 4) - 4 - 2, y + 2 + 4 - 2); g.drawLine(x + (controlSize - 4) - 4, y + 3 + 4, x + (controlSize - 4) - 4 - 2, y + 3 + 4 - 2); g.drawLine(x + (controlSize - 4) - 4, y + 4 + 4, x + (controlSize - 4) - 4 - 2, y + 4 + 4 - 2); } public int getIconWidth() { return getControlSize(); } public int getIconHeight() { return getControlSize(); } } static class PacksPanelTableCellRenderer extends DefaultTableCellRenderer { /** * Required (serializable) */ private static final long serialVersionUID = -9089892183236584242L; public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); int state = (Integer) table.getModel().getValueAt(row, 0); if (state == -2) { // condition not fulfilled renderer.setForeground(Color.GRAY); if (isSelected) { renderer.setBackground(table.getSelectionBackground()); } else { renderer.setBackground(table.getBackground()); } } else { if (isSelected) { renderer.setForeground(table.getSelectionForeground()); renderer.setBackground(table.getSelectionBackground()); } else { renderer.setForeground(table.getForeground()); renderer.setBackground(table.getBackground()); } } return renderer; } } public Debugger getDebugger() { return this.debugger; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy