com.izforge.izpack.installer.gui.IzPanel Maven / Gradle / Ivy
The newest version!
/*
* $Id$
* IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
*
* http://izpack.org/
* http://izpack.codehaus.org/
*
* 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.GuiId;
import com.izforge.izpack.api.adaptator.IXMLElement;
import com.izforge.izpack.api.data.Panel;
import com.izforge.izpack.api.handler.AbstractUIHandler;
import com.izforge.izpack.api.installer.ISummarisable;
import com.izforge.izpack.api.resource.Resources;
import com.izforge.izpack.core.handler.PromptUIHandler;
import com.izforge.izpack.gui.*;
import com.izforge.izpack.installer.data.GUIInstallData;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Defines the base class for the IzPack panels. Any panel should be a subclass of it and should
* belong to the com.izforge.izpack.panels
package. Since IzPack version 3.9 the
* layout handling will be delegated to the class LayoutHelper which can be accessed by
* getLayoutHelper
. There are some layout helper methods in this class which will be
* exist some time longer, but they are deprecated. At a redesign or new panel use the layout
* helper. There is a special layout manager for IzPanels. This layout manager will be supported by
* the layout helper. There are some points which should be observed at layouting. One point e.g. is
* the anchor. All IzPanels have to be able to use different anchors, as minimum CENTER and
* NORTHWEST. To use a consistent appearance use this special layout manger and not others.
*
* @author Julien Ponge
* @author Klaus Bartz
*/
public abstract class IzPanel extends JPanel implements AbstractUIHandler, LayoutConstants, ISummarisable
{
private static final long serialVersionUID = 3256442495255786038L;
/**
* The helper object which handles layout
*/
protected transient LayoutHelper layoutHelper;
/**
* The component which should get the focus at activation
*/
protected Component initialFocus = null;
/**
* The installer internal data (actually a melting-pot class with all-public fields.
*/
protected final GUIInstallData installData;
/**
* The parent IzPack installer frame.
*/
protected final InstallerFrame parent;
/**
* internal headline Label
*/
protected JLabel headLineLabel;
/**
* HEADLINE = "headline"
*/
public final static String HEADLINE = "headline";
/**
* DELIMITER = "." ( dot )
*/
public final static String DELIMITER = ".";
/**
* The resources.
*/
private transient final Resources resources;
/**
* The panel meta-data.
*/
private final Panel metadata;
private String helpUrl = null;
/**
* Constructs an IzPanel.
*
* @param panel the panel meta-data
* @param parent the parent IzPack installer frame
* @param installData the installation data
* @param resources the resources
*/
public IzPanel(Panel panel, InstallerFrame parent, GUIInstallData installData, Resources resources)
{
this(panel, parent, installData, (LayoutManager2) null, resources);
}
/**
* Constructs an IzPanel with the given layout manager.
*
* Valid layout manager are the {@link IzPanelLayout} and GridBagLayout.
* New panels should be use IzPanelLayout. If layoutManager is
* null, no layout manager will be created or initialized.
*
* @param panel the panel meta-data
* @param parent the parent IzPack installer frame
* @param installData the installation data
* @param layoutManager layout manager to be used with this IzPanel
* @param resources the resources
*/
public IzPanel(Panel panel, InstallerFrame parent, GUIInstallData installData, LayoutManager2 layoutManager,
Resources resources)
{
super();
this.metadata = panel;
this.parent = parent;
this.installData = installData;
this.resources = resources;
initLayoutHelper();
if (layoutManager != null)
{
getLayoutHelper().startLayout(layoutManager);
}
}
/**
* Constructs an IzPanel.
*
* @param panel the panel meta-data
* @param parent the parent IzPack installer frame
* @param installData the installation data
* @param iconName the Headline icon name
* @param resources the resources
*/
@Deprecated
// FIXME: This constructor is used just in ShortcutPanel, move it there
public IzPanel(Panel panel, InstallerFrame parent, GUIInstallData installData, String iconName,
Resources resources)
{
this(panel, parent, installData, resources);
buildHeadline(iconName);
}
/**
* Build the IzPanel internal Headline. If an external headline# is used, this method returns
* immediately with false. Allows also to display a leading Icon for the PanelHeadline. This
* Icon can also be different if the panel has more than one Instances. The UserInputPanel is
* one of these Candidates. by marc.eppelmann@gmx.de
*
* @param imageIconName an Iconname
*/
@Deprecated
private void buildHeadline(String imageIconName)
{
if (parent.isHeading(this))
{
return;
}
String headline = null;
String searchkey = getMetadata().getPanelId() + DELIMITER + "headline";
if (getMetadata().hasPanelId() && installData.getMessages().getMessages().containsKey(searchkey))
{
headline = getString(getMetadata().getPanelId() + DELIMITER + "headline");
}
else {
searchkey = getClass().getSimpleName() + DELIMITER + "headline";
if (installData.getMessages().getMessages().containsKey(searchkey))
{
headline = getString(searchkey);
}
}
if (headline != null)
{
if ((imageIconName != null) && !"".equals(imageIconName))
{
headLineLabel = new JLabel(headline, getImageIcon(imageIconName), SwingConstants.LEADING);
}
else
{
headLineLabel = new JLabel(headline);
}
Font font = headLineLabel.getFont();
float size = font.getSize();
font = font.deriveFont(Font.PLAIN, (size * 1.5f));
headLineLabel.setFont(font);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(0, 0, 0, 0);
headLineLabel.setName(HEADLINE);
((GridBagLayout) getLayout()).addLayoutComponent(headLineLabel, gbc);
add(headLineLabel);
}
}
/**
* Helper to return a language resource string.
*
* @param key the search key
* @return the corresponding string, or {@code key} if the string is not found
*/
public String getString(String key)
{
return installData.getMessages().get(key);
}
/**
* Gets a named image icon
*
* @param iconName a valid image icon
* @return the icon
*/
public ImageIcon getImageIcon(String iconName)
{
return parent.getIcons().get(iconName);
}
/**
* Inits and sets the internal layout helper object.
*/
protected void initLayoutHelper()
{
layoutHelper = new LayoutHelper(this, installData);
}
/**
* Indicates wether the panel has been validated or not. The installer won't let the user go
* further through the installation process until the panel is validated. Default behaviour is
* to return true
.
*
* @return A boolean stating whether the panel has been validated or not.
*/
protected boolean isValidated()
{
return true;
}
protected void saveData()
{
//Save Data
}
public boolean panelValidated()
{
return isValidated();
}
/**
* This method is called when the panel becomes active. Default is to do nothing : feel free to
* implement what you need in your subclasses. A panel becomes active when the user reaches it
* during the installation process.
*/
public void panelActivate()
{
}
/**
* This method is called when the panel gets desactivated, when the user switches to the next
* panel. By default it doesn't do anything.
*/
public void panelDeactivate()
{
}
public void createInstallationRecord(IXMLElement rootElement)
{
// Default method, override to record panel contents
}
/**
* Ask the user a question.
*
* @param title Message title.
* @param question The question.
* @param choices The set of choices to present.
* @return The user's choice.
* @see AbstractUIHandler#askQuestion(String, String, int)
*/
@Override
public int askQuestion(String title, String question, int choices)
{
return askQuestion(title, question, choices, -1);
}
/**
* Ask the user a question.
*
* @param title Message title.
* @param question The question.
* @param choices The set of choices to present.
* @param defaultChoice The default choice. (-1 = no default choice)
* @return The user's choice.
* @see AbstractUIHandler#askQuestion(String, String, int, int)
*/
@Override
public int askQuestion(final String title, final String question, int choices, int defaultChoice)
{
return new PromptUIHandler(new GUIPrompt(this)).askQuestion(title, question, choices, defaultChoice);
}
@Override
public int askWarningQuestion(final String title, final String question, int choices, int defaultChoice)
{
return new PromptUIHandler(new GUIPrompt(this)).askWarningQuestion(title, question, choices, defaultChoice);
}
public boolean emitNotificationFeedback(final String message)
{
return emitWarning(getString("installer.Message"), message);
}
/**
* Notify the user about something.
*
* @param message The notification.
*/
@Override
public void emitNotification(final String message)
{
new PromptUIHandler(new GUIPrompt(this)).emitNotification(message);
}
/**
* Warn the user about something.
*
* @param message The warning message.
*/
@Override
public boolean emitWarning(final String title, final String message)
{
return new PromptUIHandler(new GUIPrompt(this)).emitWarning(title, message);
}
/**
* Notify the user of some error.
*
* @param message The error message.
*/
@Override
public void emitError(final String title, final String message)
{
new PromptUIHandler(new GUIPrompt(this)).emitError(title, message);
}
/**
* Returns the component which should be get the focus at activation of this panel.
*
* @return the component which should be get the focus at activation of this panel
*/
public Component getInitialFocus()
{
return initialFocus;
}
/**
* Sets the component which should be get the focus at activation of this panel.
*
* @param component which should be get the focus at activation of this panel
*/
public void setInitialFocus(Component component)
{
initialFocus = component;
}
/**
* Calls the langpack of parent InstallerFrame for the String RuntimeClassName.subkey.
* Do not add a point infront of subkey, it is always added in this method. If
* RuntimeClassName.subkey is not found, the super class name will be used until it
* is IzPanel. If no key will be found, null returns.
*
* @param subkey the subkey for the string which should be returned
* @return the founded string
*/
public String getI18nStringForClass(String subkey)
{
return getI18nStringForClass(subkey, null);
}
/**
* Calls the langpack of parent InstallerFrame for the String RuntimeClassName.subkey.
* Do not add a point infront of subkey, it is always added in this method. If no key will be
* found the key or - if alternate class is null - null returns.
*
* @param subkey the subkey for the string which should be returned
* @param alternateClass the short name of the class which should be used if no string is
* present with the runtime class name
* @return the founded string
*/
public String getI18nStringForClass(String subkey, String alternateClass)
{
String retval = null;
List prefixes = new ArrayList<>();
String panelId = getMetadata().getPanelId();
Class> clazz = this.getClass();
String fullClassname = alternateClass==null?clazz.getName():alternateClass;
String simpleClassname = alternateClass==null?clazz.getSimpleName():alternateClass;
do
{
prefixes.add(fullClassname + "." + panelId);
prefixes.add(simpleClassname + "." + panelId);
prefixes.add(fullClassname);
prefixes.add(simpleClassname);
clazz = clazz.getSuperclass();
fullClassname = clazz.getName();
simpleClassname = clazz.getSimpleName();
} while (alternateClass == null && !clazz.equals(IzPanel.class));
prefixes.add(2, panelId);
for (String prefix : prefixes)
{
String searchkey = prefix + "." + subkey;
if (installData.getMessages().getMessages().containsKey(searchkey))
{
retval = getString(searchkey);
}
if (retval != null)
{
break;
}
}
if (retval != null && retval.indexOf('$') > -1)
{
retval = installData.getVariables().replace(retval);
}
return (retval);
}
/**
* Returns the parent of this IzPanel (which is a InstallerFrame).
*
* @return the parent of this IzPanel
*/
public InstallerFrame getInstallerFrame()
{
return (parent);
}
// ------------- Helper for common used components ----- START ---
/**
* Creates a label via LabelFactory using iconId, pos and method getI18nStringForClass for
* resolving the text to be used. If the icon id is null, the label will be created also. If
* isFullLine true a LabelFactory.FullLineLabel will be created instead of a JLabel. The
* difference between both classes are a different layout handling.
*
* @param subkey the subkey which should be used for resolving the text
* @param alternateClass the short name of the class which should be used if no string is
* present with the runtime class name
* @param iconId id string for the icon
* @param pos horizontal alignment
* @param isFullLine determines whether a FullLineLabel or a JLabel should be created
* @return the newly created label
*/
public JLabel createLabel(String subkey, String alternateClass, String iconId, int pos,
boolean isFullLine)
{
ImageIcon imageIcon = (iconId != null) ? parent.getIcons().get(iconId) : null;
String msg = getI18nStringForClass(subkey, alternateClass);
JLabel label = LabelFactory.create(msg, imageIcon, pos, isFullLine);
label.setFont(getControlTextFont());
return (label);
}
/**
* The Font of Labels in many cases
*/
public Font getControlTextFont()
{
Font fontObj = (getLAF() != null) ?
MetalLookAndFeel.getControlTextFont() : getFont();
//if guiprefs 'labelFontSize' multiplier value
// has been setup then apply it to the font:
final float val;
if ((val = LabelFactory.getLabelFontSize()) != 1.0f)
{
fontObj = fontObj.deriveFont(fontObj.getSize2D() * val);
}
return fontObj;
}
protected static MetalLookAndFeel getLAF()
{
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
if (lookAndFeel instanceof MetalLookAndFeel)
{
return ((MetalLookAndFeel) lookAndFeel);
}
return (null);
}
// ------------------- Summary stuff -------------------- START ---
@Override
public String getSummaryBody()
{
return null;
}
@Override
public String getSummaryCaption()
{
String caption;
if (parent.isHeading(this) && this.installData.guiPrefs.modifier.containsKey("useHeadingForSummary")
&& (this.installData.guiPrefs.modifier.get("useHeadingForSummary")).equalsIgnoreCase("yes"))
{
caption = getI18nStringForClass("headline", null);
}
else
{
caption = getI18nStringForClass("summaryCaption", null);
}
return (caption);
}
@Override
public boolean isVisited()
{
return getMetadata().isVisited();
}
// ------------------- Summary stuff -------------------- END ---
// ------------------- Inner classes ------------------- START ---
public static class Filler extends JComponent
{
private static final long serialVersionUID = 3258416144414095153L;
}
// ------------------- Inner classes ------------------- END ---
/**
* Returns the used layout helper. Can be used in a derived class to create custom layout.
*
* @return the used layout helper
*/
public LayoutHelper getLayoutHelper()
{
return layoutHelper;
}
/**
* Returns the panel metadata.
*
* @return the panel metadata
*/
public Panel getMetadata()
{
return metadata;
}
/**
* Parses the text for special variables.
*/
protected String parseText(String string_to_parse)
{
string_to_parse = installData.getVariables().replace(string_to_parse);
return string_to_parse;
}
/**
* Indicates wether the panel can display help. The installer will hide Help button if current
* panel does not support help functions. Default behaviour is to return false
.
*
* @return A boolean stating wether the panel supports Help function.
*/
public boolean canShowHelp()
{
return helpUrl != null;
}
/**
* This method is called when Help button has been clicked. By default it doesn't do anything.
*/
public void showHelp()
{
// System.out.println("Help function called, helpName: " + helpName);
if (helpUrl != null)
{
URL resourceUrl = resources.getURL(helpUrl);
getHelpWindow().showHelp(getString("installer.help"), resourceUrl);
}
}
private HelpWindow helpWindow = null;
private HelpWindow getHelpWindow()
{
if (this.helpWindow != null)
{
return this.helpWindow;
}
this.helpWindow = new HelpWindow(parent, getString("installer.help.close"));
helpWindow.setName(GuiId.HELP_WINDOWS.id);
return this.helpWindow;
}
public void setHelpUrl(String helpUrl)
{
this.helpUrl = helpUrl;
}
@Override
public String toString()
{
return "IzPanel{" +
"class=" + getClass().getSimpleName() +
'}';
}
/**
* Returns the resources.
*
* @return the resources
*/
protected Resources getResources()
{
return resources;
}
}