Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* $Id$
* IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
*
* http://izpack.org/
* http://izpack.codehaus.org/
*
* Copyright 2002 Jan Blok
*
* 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.installer.gui;
import com.izforge.izpack.api.data.Info;
import com.izforge.izpack.api.data.Panel;
import com.izforge.izpack.api.data.Variables;
import com.izforge.izpack.api.event.ProgressListener;
import com.izforge.izpack.api.exception.ResourceException;
import com.izforge.izpack.api.exception.ResourceNotFoundException;
import com.izforge.izpack.api.resource.Locales;
import com.izforge.izpack.api.resource.Messages;
import com.izforge.izpack.api.rules.RulesEngine;
import com.izforge.izpack.core.resource.ResourceManager;
import com.izforge.izpack.gui.ButtonFactory;
import com.izforge.izpack.gui.EtchedLineBorder;
import com.izforge.izpack.gui.IconsDatabase;
import com.izforge.izpack.gui.log.Log;
import com.izforge.izpack.installer.base.InstallerBase;
import com.izforge.izpack.installer.data.GUIInstallData;
import com.izforge.izpack.installer.data.UninstallData;
import com.izforge.izpack.installer.data.UninstallDataWriter;
import com.izforge.izpack.installer.debugger.Debugger;
import com.izforge.izpack.installer.unpacker.IUnpacker;
import com.izforge.izpack.util.Debug;
import com.izforge.izpack.util.Housekeeper;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.izforge.izpack.api.GuiId.BUTTON_HELP;
/**
* The IzPack installer frame.
*
* @author Julien Ponge created October 27, 2002
* @author Fabrice Mirabile added fix for alert window on cross button, July 06 2005
* @author Dennis Reil, added RulesEngine November 10 2006, several changes in January 2007
* @author Bill Root added per-panel quit confirmation control, Feb 2015
*/
public class InstallerFrame extends JFrame implements InstallerBase, InstallerView
{
private static final long serialVersionUID = 3257852069162727473L;
private static final transient Logger logger = Logger.getLogger(InstallerFrame.class.getName());
private static final String ICON_RESOURCE = "Installer.image";
/**
* Name of the variable where to find an extension to the resource name of the icon resource
*/
private static final String ICON_RESOURCE_EXT_VARIABLE_NAME = "installerimage.ext";
/**
* Heading icon resource name.
*/
private static final String HEADING_ICON_RESOURCE = "Heading.image";
/**
* The installation data.
*/
private final GUIInstallData installdata;
/**
* The icons database.
*/
private IconsDatabase icons;
/**
* The panels container.
*/
protected JPanel panelsContainer;
/**
* The frame content pane.
*/
protected JPanel contentPane;
/**
* The help button.
*/
protected JButton helpButton = null;
/**
* The panel navigator.
*/
private final DefaultNavigator navigator;
/**
* Registered GUICreationListener.
*/
protected final ArrayList guiListener;
/**
* Heading major text.
*/
protected JLabel[] headingLabels;
/**
* Panel which contains the heading text and/or icon
*/
protected JPanel headingPanel;
/**
* The heading counter component.
*/
protected JComponent headingCounterComponent;
/**
* Image
*/
private JLabel iconLabel;
/**
* Count for discarded interrupt trials.
*/
private int interruptCount = 1;
/**
* Maximum of discarded interrupt trials.
*/
private static final int MAX_INTERRUPT = 3;
/**
* conditions
*/
protected final RulesEngine rules;
private Debugger debugger;
// If a heading image is defined should it be displayed on the left
private boolean imageLeft = false;
/**
* The panels.
*/
private final IzPanels panels;
/**
* The resources.
*/
private final ResourceManager resourceManager;
/**
* Manager for writing uninstall data
*/
private final UninstallDataWriter uninstallDataWriter;
/**
* The variables.
*/
private final Variables variables;
private final UninstallData uninstallData;
/**
* The unpacker.
*/
private IUnpacker unpacker;
/**
* The house keeper.
*/
private final Housekeeper housekeeper;
/**
* The log.
*/
private final Log log;
/**
* The supported locales that contains the localised messages.
*/
private final Locales locales;
/**
* Constructs an InstallerFrame.
*
* @param installData the installation data
* @param rules the rules engine
* @param icons the icons database
* @param panels the panels
* @param uninstallDataWriter the uninstallation data writer
* @param resourceManager the resources
* @param uninstallData the uninstallation data
* @param housekeeper the house-keeper
* @param navigator the panel navigator
* @param log the log
*/
public InstallerFrame(GUIInstallData installData, RulesEngine rules, IconsDatabase icons,
IzPanels panels, UninstallDataWriter uninstallDataWriter,
ResourceManager resourceManager, UninstallData uninstallData, Housekeeper housekeeper,
DefaultNavigator navigator, Log log, Locales locales)
{
super();
guiListener = new ArrayList();
this.installdata = installData;
this.rules = rules;
this.resourceManager = resourceManager;
this.uninstallDataWriter = uninstallDataWriter;
this.uninstallData = uninstallData;
this.panels = panels;
this.variables = installData.getVariables();
this.housekeeper = housekeeper;
this.log = log;
this.locales = locales;
this.setIcons(icons);
this.navigator = navigator;
navigator.setInstallerFrame(this);
// Sets the window events handler
addWindowListener(new WindowHandler(navigator));
}
/**
* Sets the unpacker.
*
* @param unpacker the unpacker
*/
public void setUnpacker(IUnpacker unpacker)
{
this.unpacker = unpacker;
}
@Override
public void sizeFrame()
{
pack();
setSize(installdata.guiPrefs.width, installdata.guiPrefs.height);
setPreferredSize(new Dimension(installdata.guiPrefs.width, installdata.guiPrefs.height));
setResizable(installdata.guiPrefs.resizable);
centerFrame(this);
}
public Debugger getDebugger()
{
return this.debugger;
}
/**
* Builds the GUI.
*/
public void buildGUI()
{
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
ImageIcon jframeIcon = getIcons().get("JFrameIcon");
setIconImage(jframeIcon.getImage());
// Prepares the glass pane to block the gui interaction when needed
JPanel glassPane = (JPanel) getGlassPane();
glassPane.addMouseListener(new MouseAdapter()
{
});
glassPane.addMouseMotionListener(new MouseMotionAdapter()
{
});
glassPane.addKeyListener(new KeyAdapter()
{
});
glassPane.addFocusListener(new FocusAdapter()
{
});
// We set the layout & prepare the constraint object
contentPane = (JPanel) getContentPane();
contentPane.setLayout(new BorderLayout()); // layout);
// We add the panels container
panelsContainer = new JPanel();
panelsContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
panelsContainer.setLayout(new GridLayout(1, 1));
contentPane.add(panelsContainer, BorderLayout.CENTER);
logger.fine("Building GUI. The panel list to display is " + installdata.getPanels());
Messages messages = locales.getMessages();
navigator.updateButtonText(messages);
JPanel navPanel = new JPanel();
navPanel.setLayout(new BoxLayout(navPanel, BoxLayout.X_AXIS));
TitledBorder border = BorderFactory.createTitledBorder(
new EtchedLineBorder(), messages.get("installer.madewith") + " ",
TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.PLAIN, 10));
navPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8), border));
// Add help Button to the navigation panel
this.helpButton = ButtonFactory.createButton(messages.get("installer.help"), getIcons()
.get("help"), installdata.buttonsHColor);
navPanel.add(this.helpButton);
this.helpButton.setName(BUTTON_HELP.id);
this.helpButton.addActionListener(new HelpHandler());
// update navigation panel and help button mnemonic shortcuts for selected language.
ButtonFactory.clearAllMnemonics();
ButtonFactory.reserveButtonMnemonics(new JButton[] {helpButton});
navigator.reserveNavigatorButtonMnemonics();
navPanel.add(Box.createHorizontalGlue());
navPanel.add(navigator.getPrevious());
navPanel.add(Box.createRigidArea(new Dimension(5, 0)));
navPanel.add(navigator.getNext());
navPanel.add(Box.createRigidArea(new Dimension(5, 0)));
navPanel.add(navigator.getQuit());
contentPane.add(navPanel, BorderLayout.SOUTH);
// create a debug panel if TRACE is enabled
if (Debug.isTRACE())
{
debugger = new Debugger(installdata, getIcons(), rules);
// this needed to fully initialize the debugger
JPanel debugpanel = debugger.getDebugPanel();
if (installdata.guiPrefs.modifier.containsKey("showDebugWindow")
&& Boolean.valueOf(installdata.guiPrefs.modifier.get("showDebugWindow")))
{
JFrame debugframe = new JFrame("Debug information");
debugframe.setContentPane(debugpanel);
debugframe.setSize(new Dimension(400, 400));
debugframe.setVisible(true);
}
else
{
debugpanel.setPreferredSize(new Dimension(200, 400));
contentPane.add(debugpanel, BorderLayout.EAST);
}
}
ImageIcon icon = loadIcon(ICON_RESOURCE, 0 + "");
if (icon != null)
{
JPanel imgPanel = new JPanel();
imgPanel.setLayout(new BorderLayout());
imgPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
iconLabel = new JLabel(icon);
iconLabel.setBorder(BorderFactory.createLoweredBevelBorder());
imgPanel.add(iconLabel, BorderLayout.NORTH);
contentPane.add(imgPanel, BorderLayout.WEST);
loadAndShowImageForPanelNum(iconLabel, 0);
}
getRootPane().setDefaultButton(navigator.setDefaultButton());
callGUIListener(GUIListener.GUI_BUILDED, navPanel);
createHeading(navPanel);
// need to initialise the panels after construction, as many of the panels require InstallerFrame
panels.initialise();
panels.setListener(new IzPanelsListener()
{
@Override
public void switchPanel(IzPanelView newPanel, IzPanelView oldPanel)
{
InstallerFrame.this.switchPanel(newPanel, oldPanel);
}
});
}
/**
* Returns the panel navigator.
*
* @return the panel navigator
*/
public Navigator getNavigator()
{
return navigator;
}
private void callGUIListener(int what)
{
callGUIListener(what, null);
}
private void callGUIListener(int what, JPanel param)
{
for (GUIListener aGuiListener : guiListener)
{
aGuiListener.guiActionPerformed(what, param);
}
}
/**
* Loads icon for given panel id.
*
* @param resPrefix resource prefix
* @param panelid panel id
* @return image icon, or {@code null} if no icon exists
* @throws ResourceException if the resource exists but cannot be retrieved
*/
private ImageIcon loadIcon(String resPrefix, String panelid)
{
ImageIcon icon = null;
String ext = getIconResourceNameExtension();
try
{
icon = resourceManager.getImageIcon(resPrefix, resPrefix + "." + panelid + ext);
}
catch (ResourceNotFoundException exception)
{
logger.fine("No icon for panel=" + panelid + ": " + exception.getMessage());
}
return icon;
}
/**
* Returns the current set extension to icon resource names. Can be used to change the static
* installer image based on user input
*
* @return a resource extension or an empty string if the variable was not set.
*/
private String getIconResourceNameExtension()
{
try
{
String iconext = installdata.getVariable(ICON_RESOURCE_EXT_VARIABLE_NAME);
if (iconext == null)
{
iconext = "";
}
else
{
if ((iconext.length() > 0) && (iconext.charAt(0) != '.'))
{
iconext = "." + iconext;
}
}
iconext = iconext.trim();
return iconext;
}
catch (Exception e)
{
// in case of error, return an empty string
return "";
}
}
private void loadAndShowImageForPanelNum(JLabel jLabel, int panelNo)
{
loadAndShowImage(jLabel, ICON_RESOURCE, panelNo);
}
private void loadAndShowImageForPanelOrId(JLabel jLabel, int panelNo, String panelId)
{
loadAndShowImage(jLabel, ICON_RESOURCE, panelNo, panelId);
}
private void loadAndShowImage(JLabel jLabel, String resPrefix, int panelNo, String panelId)
{
ImageIcon icon = loadIcon(resPrefix, panelId);
if (icon == null)
{
icon = loadIcon(resPrefix, panelNo + "");
}
jLabel.setVisible(false);
jLabel.setIcon(icon);
jLabel.setVisible(true);
}
private void loadAndShowImage(JLabel jLabel, String resPrefix, int panelNo)
{
ImageIcon icon = loadIcon(resPrefix, panelNo + "");
if (icon == null)
{
icon = loadIcon(resPrefix, panelNo + "");
}
if (icon != null)
{
jLabel.setVisible(false);
jLabel.setIcon(icon);
jLabel.setVisible(true);
}
}
/**
* Switches the current panel.
*
* @param newPanel the new panel
* @param oldPanel the old panel. May be {@code null}
*/
protected void switchPanel(IzPanelView newPanel, IzPanelView oldPanel)
{
int oldIndex = (oldPanel != null) ? oldPanel.getIndex() : -1;
logger.fine("Switching panel, old index is " + oldIndex);
try
{
panelsContainer.setVisible(false);
IzPanel newView = newPanel.getView();
showHelpButton(newView.canShowHelp());
if (Debug.isTRACE())
{
Panel panel = (oldPanel != null) ? oldPanel.getPanel() : null;
debugger.switchPanel(newPanel.getPanel(), panel);
}
String oldPanelClass = (oldPanel != null) ? oldPanel.getClass().getName() : null;
log.addDebugMessage(
"InstallerFrame.switchPanel: try switching newPanel from {0} to {1} ({2} to {3})",
new String[]{oldPanelClass, newPanel.getClass().getName(),
Integer.toString(oldIndex), Integer.toString(newPanel.getIndex())},
Log.PANEL_TRACE, null);
// instead of writing data here which leads to duplicated entries in
// auto-installation script (bug # 4551), let's make data only immediately before
// writing out that script.
// oldPanel.makeXMLData(installdata.xmlData.getChildAtIndex(oldIndex));
// No previous button in the first visible newPanel
// Change panels container to the current one.
if (oldPanel != null)
{
IzPanel oldView = oldPanel.getView();
panelsContainer.remove(oldView);
oldView.panelDeactivate();
}
panelsContainer.add(newView);
if (newView.getInitialFocus() != null)
{
// Initial focus hint should be performed after current newPanel
// was added to the panels container, else the focus hint will
// be ignored.
// Give a hint for the initial focus to the system.
final Component inFoc = newView.getInitialFocus();
// On java VM version >= 1.5 it works only if
// invoke later will be used.
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
inFoc.requestFocusInWindow();
}
});
/*
* On editable text components position the caret to the end of the cust existent
* text.
*/
if (inFoc instanceof JTextComponent)
{
JTextComponent inText = (JTextComponent) inFoc;
if (inText.isEditable() && inText.getDocument() != null)
{
inText.setCaretPosition(inText.getDocument().getLength());
}
}
}
performHeading(newPanel);
performHeadingCounter(newPanel);
newPanel.executePreActivationActions();
Panel panel = newPanel.getPanel();
String readonlyCondition = panel.getReadonlyCondition();
String displayHiddenCondition = panel.getDisplayHiddenCondition();
newView.panelActivate();
panelsContainer.setVisible(true);
if (iconLabel != null)
{
if (!"UNKNOWN".equals(newPanel.getPanelId()))
{
loadAndShowImageForPanelOrId(iconLabel, panels.getVisibleIndex(newPanel), newPanel.getPanelId());
}
else
{
loadAndShowImageForPanelNum(iconLabel, panels.getVisibleIndex(newPanel));
}
}
callGUIListener(GUIListener.PANEL_SWITCHED);
log.addDebugMessage("InstallerFrame.switchPanel: switched", null, Log.PANEL_TRACE, null);
}
catch (Exception e)
{
e.printStackTrace();
logger.log(Level.SEVERE, "Error when switching panel", e);
}
}
/**
* Centers a window on screen.
*
* @param frame The window tp center.
*/
public void centerFrame(Window frame)
{
Point center = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
Dimension frameSize = frame.getSize();
frame.setLocation(center.x - frameSize.width / 2, center.y - frameSize.height / 2 - 10);
}
/**
* Returns the panels container size.
*
* @return The panels container size.
*/
public Dimension getPanelsContainerSize()
{
return panelsContainer.getSize();
}
/**
* Exits the installer, if quit is enabled.
*
* If installation is complete, this writes any uninstallation data, and shuts down.
* If installation is incomplete, a confirmation dialog will be displayed.
*/
public void exit()
{
navigator.quit();
}
/**
* Quits the installer.
*
* If installation is complete, this writes any uninstallation data, and shuts down.
* If installation is incomplete, a confirmation dialog will be displayed.
*/
void quit()
{
// FIXME !!! Reboot handling
boolean confirmQuit;
Panel panel = panels.getPanel();
if (panel.getConfirmQuitType() == Panel.ConfirmQuitType.DYNAMIC)
confirmQuit = !(installdata.isCanClose() || (!navigator.isNextEnabled() && !navigator.isPreviousEnabled()));
else
confirmQuit = (panel.getConfirmQuitType() == Panel.ConfirmQuitType.CONFIRM);
if (!confirmQuit)
{
if (!writeUninstallData())
{
// TODO - for now just shut down. Alternative approaches include:
// . retry
// . revert installation - which is what wipeAborted attempts to do, but fails to handle shortcuts and
// registry changes
}
shutdown();
}
else
{
// The installation is not over
confirmExit();
}
}
/**
* Wipes the written files when you abort the installation.
*/
protected void wipeAborted()
{
// We set interrupt to all running Unpacker and wait 40 sec for maximum.
// If interrupt is discarded (return value false), return immediately:
if (!unpacker.interrupt(40000))
{
return;
}
// Wipe the files that had been installed
for (String installedFile : uninstallData.getInstalledFilesList())
{
File file = new File(installedFile);
file.delete();
}
}
/**
* Launches the installation.
*
* @param listener The installation listener.
*/
public void install(ProgressListener listener)
{
unpacker.setProgressListener(listener);
Thread unpackerthread = new Thread(unpacker, "IzPack - Unpacker thread");
unpackerthread.start();
}
/**
* Writes the installation record to a file.
*
* @param file The file to write to.
* @param uninstallData The uninstall data.
* @throws Exception Description of the Exception
*/
@Override
public void writeInstallationRecord(File file, UninstallData uninstallData) throws Exception
{
panels.writeInstallationRecord(file, uninstallData);
}
/**
* Changes the quit button text. If text is null, the default quit text is used.
*
* @param text text to be used for changes
*/
public void setQuitButtonText(String text)
{
if (text == null)
{
Messages messages = locales.getMessages();
text = messages.get("installer.quit");
}
navigator.setQuitText(text);
}
/**
* Sets a new icon into the quit button if icons should be used, else nothing will be done.
*
* @param iconName name of the icon to be used
*/
public void setQuitButtonIcon(String iconName)
{
String useButtonIcons = installdata.guiPrefs.modifier.get("useButtonIcons");
if (useButtonIcons == null || "yes".equalsIgnoreCase(useButtonIcons))
{
navigator.getQuit().setIcon(getIcons().get(iconName));
}
}
/**
* FocusTraversalPolicy objects to handle keybord blocking; the declaration os Object allows to
* use a pre version 1.4 VM.
*/
private Object usualFTP = null;
private Object blockFTP = null;
/**
* Blocks GUI interaction.
*/
public void blockGUI()
{
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
getGlassPane().setVisible(true);
getGlassPane().setEnabled(true);
if (usualFTP == null)
{
usualFTP = getFocusTraversalPolicy();
}
if (blockFTP == null)
{
blockFTP = new BlockFocusTraversalPolicy();
}
setFocusTraversalPolicy((java.awt.FocusTraversalPolicy) blockFTP);
getGlassPane().requestFocus();
callGUIListener(GUIListener.GUI_BLOCKED);
}
/**
* Releases GUI interaction.
*/
public void releaseGUI()
{
getGlassPane().setEnabled(false);
getGlassPane().setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
setFocusTraversalPolicy((java.awt.FocusTraversalPolicy) usualFTP);
callGUIListener(GUIListener.GUI_RELEASED);
}
/**
* Locks the 'previous' button.
*/
@Override
public void lockPrevButton()
{
navigator.setPreviousEnabled(false);
}
/**
* Locks the 'next' button.
*/
@Override
public void lockNextButton()
{
navigator.setNextEnabled(false);
}
/**
* Locks the 'Quit' button.
*/
@Override
public void lockQuitButton()
{
navigator.setQuitEnabled(false);
}
/**
* Unlocks the 'previous' button.
*/
@Override
public void unlockPrevButton()
{
navigator.setPreviousEnabled(true);
}
/**
* Unlocks the 'next' button.
*/
@Override
public void unlockNextButton()
{
unlockNextButton(true);
}
/**
* Unlocks the 'Quit' button.
*/
@Override
public void unlockQuitButton()
{
navigator.setQuitEnabled(true);
}
/**
* Unlocks the 'next' button.
*
* @param requestFocus if true focus goes to nextButton
*/
@Override
public void unlockNextButton(boolean requestFocus)
{
navigator.setNextEnabled(true);
if (requestFocus)
{
getRootPane().setDefaultButton(navigator.setDefaultButton());
navigator.getNext().requestFocusInWindow();
if (this.getFocusOwner() != null)
{
logger.fine("Current focus owner: " + this.getFocusOwner().getName());
}
}
}
/**
* Allows a panel to ask to be skipped.
*/
public void skipPanel()
{
if (panels.isBack())
{
navigatePrevious();
}
else
{
navigator.next(false);
}
}
/**
* This function moves to the next panel
*/
@Override
public void navigateNext()
{
navigator.next();
}
/**
* This function moves to the previous panel
*/
@Override
public void navigatePrevious()
{
navigator.previous();
}
/**
* Show help Window
*/
@Override
public void showHelp()
{
IzPanel izPanel = panels.getView();
izPanel.showHelp();
}
/**
* Returns the locale-specific messages.
*
* @return the messages
*/
public Messages getMessages()
{
return locales.getMessages();
}
public IconsDatabase getIcons()
{
return icons;
}
public void setIcons(IconsDatabase icons)
{
this.icons = icons;
}
class HelpHandler implements ActionListener
{
/**Button
* Actions handler.
*
* @param e The event.
*/
@Override
public void actionPerformed(ActionEvent e)
{
showHelp();
}
}
/**
* A FocusTraversalPolicy that only allows the block panel to have the focus
*/
private class BlockFocusTraversalPolicy extends java.awt.DefaultFocusTraversalPolicy
{
private static final long serialVersionUID = 3258413928261169209L;
/**
* Only accepts the block panel
*
* @param aComp the component to check
* @return true if aComp is the block panel
*/
@Override
protected boolean accept(Component aComp)
{
return aComp == getGlassPane();
}
}
/**
* Returns the gui creation listener list.
*
* @return the gui creation listener list
*/
public List getGuiListener()
{
return guiListener;
}
/**
* Add a listener to the listener list.
*
* @param listener to be added as gui creation listener
*/
public void addGuiListener(GUIListener listener)
{
guiListener.add(listener);
}
/**
* Creates heading labels.
*
* @param headingLines the number of lines of heading labels
* @param back background color (currently not used)
*/
private void createHeadingLabels(int headingLines, Color back)
{
// headingLabels are an array which contains the labels for header (0),
// description lines and the icon (last).
headingLabels = new JLabel[headingLines + 1];
headingLabels[0] = new JLabel("");
// First line ist the "main heading" which should be bold.
headingLabels[0].setFont(headingLabels[0].getFont().deriveFont(Font.BOLD));
// Updated by Daniel Azarov, Exadel Inc.
// start
Color foreground;
if (installdata.guiPrefs.modifier.containsKey("headingForegroundColor"))
{
foreground = Color.decode(installdata.guiPrefs.modifier.get("headingForegroundColor"));
headingLabels[0].setForeground(foreground);
}
// end
if (installdata.guiPrefs.modifier.containsKey("headingFontSize"))
{
float fontSize = Float.parseFloat(installdata.guiPrefs.modifier.get("headingFontSize"));
if (fontSize > 0.0 && fontSize <= 5.0)
{
float currentSize = headingLabels[0].getFont().getSize2D();
headingLabels[0].setFont(headingLabels[0].getFont().deriveFont(
currentSize * fontSize));
}
}
if (imageLeft)
{
headingLabels[0].setAlignmentX(Component.RIGHT_ALIGNMENT);
}
for (int i = 1; i < headingLines; ++i)
{
headingLabels[i] = new JLabel();
// Minor headings should be a little bit more to the right.
if (imageLeft)
{
headingLabels[i].setAlignmentX(Component.RIGHT_ALIGNMENT);
}
else
{
headingLabels[i].setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 8));
}
}
}
/**
* Creates heading panel counter.
*
* @param navPanel navi JPanel
* @param leftHeadingPanel left heading JPanel
*/
private void createHeadingCounter(JPanel navPanel, JPanel leftHeadingPanel)
{
int i;
String counterPos = "inHeading";
if (installdata.guiPrefs.modifier.containsKey("headingPanelCounterPos"))
{
counterPos = installdata.guiPrefs.modifier.get("headingPanelCounterPos");
}
// Do not create counter if it should be in the heading, but no heading should be used.
if (leftHeadingPanel == null && "inHeading".equalsIgnoreCase(counterPos))
{
return;
}
if (installdata.guiPrefs.modifier.containsKey("headingPanelCounter"))
{
headingCounterComponent = null;
if ("progressbar".equalsIgnoreCase(installdata.guiPrefs.modifier
.get("headingPanelCounter")))
{
JProgressBar headingProgressBar = new JProgressBar();
headingProgressBar.setStringPainted(true);
headingProgressBar.setString("");
headingProgressBar.setValue(0);
headingCounterComponent = headingProgressBar;
if (imageLeft)
{
headingCounterComponent.setAlignmentX(Component.RIGHT_ALIGNMENT);
}
}
else
{
if ("text".equalsIgnoreCase(installdata.guiPrefs.modifier
.get("headingPanelCounter")))
{
JLabel headingCountPanels = new JLabel(" ");
headingCounterComponent = headingCountPanels;
if (imageLeft)
{
headingCounterComponent.setAlignmentX(Component.RIGHT_ALIGNMENT);
}
else
{
headingCounterComponent.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0));
}
// Updated by Daniel Azarov, Exadel Inc.
// start
Color foreground;
if (installdata.guiPrefs.modifier.containsKey("headingForegroundColor"))
{
foreground = Color.decode(installdata.guiPrefs.modifier
.get("headingForegroundColor"));
headingCountPanels.setForeground(foreground);
}
// end
}
}
if ("inHeading".equals(counterPos))
{
assert leftHeadingPanel != null;
leftHeadingPanel.add(headingCounterComponent);
}
else if ("inNavigationPanel".equals(counterPos))
{
Component[] comps = navPanel.getComponents();
for (i = 0; i < comps.length; ++i)
{
if (comps[i].equals(navigator.getPrevious()))
{
break;
}
}
if (i <= comps.length)
{
navPanel.add(Box.createHorizontalGlue(), i);
navPanel.add(headingCounterComponent, i);
}
}
}
}
/**
* Creates heading icon.
*
* @param back the color of background around image.
* @return a panel with heading image.
*/
private JPanel createHeadingIcon(Color back)
{
JPanel imgPanel = new JPanel();
imgPanel.setLayout(new BoxLayout(imgPanel, BoxLayout.Y_AXIS));
// Updated by Daniel Azarov, Exadel Inc.
// start
int borderSize = 8;
if (installdata.guiPrefs.modifier.containsKey("headingImageBorderSize"))
{
borderSize = Integer.parseInt(installdata.guiPrefs.modifier
.get("headingImageBorderSize"));
}
imgPanel.setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize,
borderSize));
// end
if (back != null)
{
imgPanel.setBackground(back);
}
ImageIcon icon = loadIcon(HEADING_ICON_RESOURCE, 0 + "");
if (icon != null)
{
JLabel iconLab = new JLabel(icon);
if (imageLeft)
{
imgPanel.add(iconLab, BorderLayout.WEST);
}
else
{
imgPanel.add(iconLab, BorderLayout.EAST);
}
headingLabels[headingLabels.length - 1] = iconLab;
}
return (imgPanel);
}
/**
* Creates a Heading in given Panel.
*
* @param navPanel a panel
*/
private void createHeading(JPanel navPanel)
{
headingPanel = null;
int headingLines = 1;
// The number of lines can be determined in the config xml file.
// The first is the header, additonals are descriptions for the header.
if (installdata.guiPrefs.modifier.containsKey("headingLineCount"))
{
headingLines = Integer.parseInt(installdata.guiPrefs.modifier.get("headingLineCount"));
}
Color back = null;
// It is possible to determine the used background color of the heading panel.
if (installdata.guiPrefs.modifier.containsKey("headingBackgroundColor"))
{
back = Color.decode(installdata.guiPrefs.modifier.get("headingBackgroundColor"));
}
// Try to create counter if no heading should be used.
if (!isHeading(null))
{
createHeadingCounter(navPanel, null);
return;
}
// See if we should switch the header image to the left side
if (installdata.guiPrefs.modifier.containsKey("headingImageOnLeft")
&& (installdata.guiPrefs.modifier.get("headingImageOnLeft").equalsIgnoreCase(
"yes") || installdata.guiPrefs.modifier
.get("headingImageOnLeft").equalsIgnoreCase("true")))
{
imageLeft = true;
}
// We create the text labels and the needed panels. From inner to outer.
// Labels
createHeadingLabels(headingLines, back);
// Panel which contains the labels
JPanel leftHeadingPanel = new JPanel();
if (back != null)
{
leftHeadingPanel.setBackground(back);
}
leftHeadingPanel.setLayout(new BoxLayout(leftHeadingPanel, BoxLayout.Y_AXIS));
if (imageLeft)
{
leftHeadingPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8));
}
for (int i = 0; i < headingLines; ++i)
{
leftHeadingPanel.add(headingLabels[i]);
}
// HeadingPanel counter: this is a label or a progress bar which can be placed
// in the leftHeadingPanel or in the navigation bar. It is facultative. If
// exist, it shows the current panel number and the amount of panels.
createHeadingCounter(navPanel, leftHeadingPanel);
// It is possible to place an icon on the right side of the heading panel.
JPanel imgPanel = createHeadingIcon(back);
// The panel for text and icon.
JPanel northPanel = new JPanel();
if (back != null)
{
northPanel.setBackground(back);
}
northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.X_AXIS));
if (imageLeft)
{
northPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
northPanel.add(imgPanel);
northPanel.add(Box.createHorizontalGlue());
northPanel.add(leftHeadingPanel);
}
else
{
northPanel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
northPanel.add(leftHeadingPanel);
northPanel.add(Box.createHorizontalGlue());
northPanel.add(imgPanel);
}
headingPanel = new JPanel(new BorderLayout());
headingPanel.add(northPanel);
headingPanel.add(new JSeparator(), BorderLayout.SOUTH);
// contentPane.add(northPanel, BorderLayout.NORTH);
contentPane.add(headingPanel, BorderLayout.NORTH);
}
/**
* Returns whether this installer frame uses with the given panel a separated heading panel or
* not. Be aware, this is an other heading as given by the IzPanel which will be placed in the
* IzPanel. This heading will be placed if the gui preferences contains an modifier with the key
* "useHeadingPanel" and the value "yes" and there is a message with the key "<class
* name>.headline".
*
* @param caller the IzPanel for which heading should be resolved
* @return whether an heading panel will be used or not
*/
public boolean isHeading(IzPanel caller)
{
return !(!installdata.guiPrefs.modifier.containsKey("useHeadingPanel")
|| !(installdata.guiPrefs.modifier.get("useHeadingPanel")).equalsIgnoreCase("yes")) && (caller == null || (caller.getI18nStringForClass("headline") != null));
}
private void performHeading(IzPanelView panel)
{
int i;
int headingLines = 1;
if (installdata.guiPrefs.modifier.containsKey("headingLineCount"))
{
headingLines = Integer.parseInt(installdata.guiPrefs.modifier.get("headingLineCount"));
}
if (headingLabels == null)
{
return;
}
IzPanel view = panel.getView();
String headline = view.getI18nStringForClass("headline");
if (headline == null)
{
headingPanel.setVisible(false);
return;
}
for (i = 0; i <= headingLines; ++i)
{
if (headingLabels[i] != null)
{
headingLabels[i].setVisible(false);
}
}
String info;
for (i = 0; i < headingLines - 1; ++i)
{
info = view.getI18nStringForClass("headinfo" + Integer.toString(i));
if (info == null)
{
info = " ";
}
if (info.endsWith(":"))
{
info = info.substring(0, info.length() - 1) + ".";
}
headingLabels[i + 1].setText(info);
headingLabels[i + 1].setVisible(true);
}
// Do not forgett the first headline.
headingLabels[0].setText(headline);
headingLabels[0].setVisible(true);
int curPanelNo = panels.getVisibleIndex(panel);
if (headingLabels[headingLines] != null)
{
loadAndShowImage(headingLabels[headingLines], HEADING_ICON_RESOURCE, curPanelNo);
headingLabels[headingLines].setVisible(true);
}
headingPanel.setVisible(true);
}
private void performHeadingCounter(IzPanelView panel)
{
if (headingCounterComponent != null)
{
int curPanelNo = panels.getVisibleIndex(panel);
int visPanelsCount = panels.getVisible();
Messages messages = locales.getMessages();
String message = String.format(
"%s %d %s %d",
messages.get("installer.step"), curPanelNo + 1,
messages.get("installer.of"), visPanelsCount
);
if (headingCounterComponent instanceof JProgressBar)
{
updateProgressBar(visPanelsCount, curPanelNo + 1, message);
}
else
{
updateProgressCounter(message);
}
}
}
public void updateProgressCounter(String message)
{
((JLabel) headingCounterComponent).setText(message);
}
public void updateProgressBar(int maximum, int value, String message)
{
JProgressBar counterComponent = (JProgressBar) headingCounterComponent;
counterComponent.setMaximum(maximum);
counterComponent.setValue(value);
counterComponent.setString(message);
}
/**
* Shows or hides Help button depending on show parameter
*
* @param show - flag to show or hide Help button
*/
private void showHelpButton(boolean show)
{
if (this.helpButton == null)
{
return;
}
this.helpButton.setVisible(show);
}
/**
* Writes uninstall data if it is required.
*
* An error message will be displayed if the write fails.
*
* @return true if uninstall data was written successfully or is not required, otherwise false
*/
private boolean writeUninstallData()
{
boolean result = true;
if (uninstallDataWriter.isUninstallRequired())
{
result = uninstallDataWriter.write();
if (!result)
{
Messages messages = locales.getMessages();
String title = messages.get("installer.error");
String message = messages.get("installer.uninstall.writefailed");
JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE);
}
}
return result;
}
/**
* Shuts down the installer after successful installation.
*
* This may trigger a reboot.
*/
private void shutdown()
{
boolean reboot = false;
if (installdata.isRebootNecessary())
{
Messages messages = locales.getMessages();
String message;
String title;
System.out.println("[ There are file operations pending after reboot ]");
switch (installdata.getInfo().getRebootAction())
{
case Info.REBOOT_ACTION_ALWAYS:
reboot = true;
break;
case Info.REBOOT_ACTION_ASK:
message = variables.replace(messages.get("installer.reboot.ask.message"));
title = variables.replace(messages.get("installer.reboot.ask.title"));
int res = JOptionPane
.showConfirmDialog(this, message, title, JOptionPane.YES_NO_OPTION);
if (res == JOptionPane.YES_OPTION)
{
reboot = true;
}
break;
case Info.REBOOT_ACTION_NOTICE:
message = variables.replace(messages.get("installer.reboot.notice.message"));
title = variables.replace(messages.get("installer.reboot.notice.title"));
JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_OPTION);
break;
}
if (reboot)
{
System.out.println("[ Rebooting now automatically ]");
}
}
housekeeper.shutDown(0, reboot);
}
/**
* Confirms exit when installation is not complete.
*/
private void confirmExit()
{
if (unpacker.isInterruptDisabled() && interruptCount < MAX_INTERRUPT)
{ // But we should not interrupt.
interruptCount++;
return;
}
Messages messages = locales.getMessages();
// Use a alternate message and title if defined.
final String mkey = "installer.quit.reversemessage";
final String tkey = "installer.quit.reversetitle";
String message = messages.get(mkey);
String title = messages.get(tkey);
// message equal to key -> no alternate message defined.
if (message.contains(mkey))
{
message = messages.get("installer.quit.message");
}
// title equal to key -> no alternate title defined.
if (title.contains(tkey))
{
title = messages.get("installer.quit.title");
}
// Now replace variables in message or title.
message = variables.replace(message);
title = variables.replace(title);
int res = JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_OPTION);
if (res == JOptionPane.YES_OPTION)
{
wipeAborted();
housekeeper.shutDown(0);
}
}
@Override
public String getTitle()
{
// Use a alternate message if defined.
final String key = "installer.reversetitle";
Messages messages = installdata.getMessages();
String message = messages.get(key);
// message equal to key -> no message defined.
if (message.equals(key))
{
message = messages.get("installer.title") + " " + installdata.getInfo().getAppName();
}
else
{
// Attention! The alternate message has to contain the whole message including
// $APP_NAME and may be $APP_VER.
message = installdata.getVariables().replace(message);
}
return message;
}
}