/****************************************************************************
* Copyright (C) 2013 ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
* This file is part of the Open eCard App.
*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public
* License version 3.0 as published by the Free Software Foundation
* and appearing in the file LICENSE.GPL included in the packaging of
* this file. Please review the following information to ensure the
* GNU General Public License version 3.0 requirements will be met:
* http://www.gnu.org/copyleft/gpl.html.
*
* Other Usage
* Alternatively, this file may be used in accordance with the terms
* and conditions contained in a signed written agreement between
* you and ecsec GmbH.
*
***************************************************************************/
package org.openecard.richclient.gui.manage;
import java.awt.AlphaComposite;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.swing.Box;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import org.openecard.common.I18n;
import org.openecard.gui.graphics.GraphicsUtil;
import org.openecard.gui.graphics.OecLogoBgWhite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Base implementation of an add-on panel.
* {@code AddonPanel}s are used to represent add-ons on the {@link ManagementDialog}. This implementation is complete,
* however it should be subclassed to reflect the needs of the add-on or builtin item.<br/>
* {@code AddonPanel}s are either arranged as tabs, or as a single content panel, depending on the use case.
*
* @author Tobias Wich <tobias.wich@ecsec.de>
*/
public class AddonPanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(AddonPanel.class);
private final I18n lang = I18n.getTranslation("addon");
private static final int LOGO_WIDTH = 45;
private static final int LOGO_HEIGHT = 45;
private Image logo;
private SettingsPanel settingsPanel;
/**
* Creates an AddonPanel with the given panels.
* Each of the panel types may be left out, but at least one must be present in order for the dialog to make any
* sense. The panels are arranged in a tab pane.
*
* @param actionPanel Optional action panel of the add-on.
* @param settingsPanel Optional settings panel of the add-on.
* @param aboutPanel Optional about page panel of the add-on.
* @param name Name of the add-on as displayed in the head of the panel.
* @param description Optional description of the add-on as displayed in the head of the panel.
* @param logo Optional logo of the add-on as displayed on the {@link ManagementDialog}.
* If not present a default will be used.
*/
public AddonPanel(@Nullable ActionPanel actionPanel, @Nullable SettingsPanel settingsPanel,
@Nullable JPanel aboutPanel, @Nonnull String name, @Nullable String description, @Nullable Image logo) {
setLayout(new BorderLayout(0, 0));
this.logo = logo;
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
add(tabbedPane);
if (actionPanel != null) {
tabbedPane.addTab(lang.translationForKey("addon.panel.tab.function"), null, actionPanel, null);
}
if (settingsPanel != null) {
if (settingsPanel instanceof SettingsPanel) {
this.settingsPanel = settingsPanel;
}
tabbedPane.addTab(lang.translationForKey("addon.panel.tab.settings"), null, settingsPanel, null);
}
if (aboutPanel != null) {
tabbedPane.addTab(lang.translationForKey("addon.panel.tab.about"), null, aboutPanel, null);
}
createHeader(name, description);
}
/**
* Creates an AddonPanel with the given panel.
* The panels is placed directly on this panel.
*
* @param singlePanel Panel to display. This panel may be of any type.
* @param name Name of the add-on as displayed in the head of the panel.
* @param description Optional description of the add-on as displayed in the head of the panel.
* @param logo Optional logo of the add-on as displayed on the {@link ManagementDialog}.
* If not present a default will be used.
*/
public AddonPanel(@Nonnull JPanel singlePanel, @Nonnull String name, @Nullable String description,
@Nullable Image logo) {
setLayout(new BorderLayout(0, 0));
this.logo = logo;
add(singlePanel);
createHeader(name, description);
if (singlePanel instanceof SettingsPanel) {
this.settingsPanel = (SettingsPanel) singlePanel;
}
}
/**
* Saves the properties of the settings panel if one is present.
*/
public void saveProperties() {
try {
if (settingsPanel != null) {
settingsPanel.saveProperties();
}
} catch (IOException ex) {
logger.error("Failed to save settings.", ex);
} catch (SecurityException ex) {
logger.error("Missing permissions to save settings.", ex);
}
}
/**
* Gets the logo of the add-on.
* If no logo has been defined, a default logo is returned.
*
* @return The logo of the add-on.
*/
@Nonnull
public Image getLogo() {
Image result;
if (logo == null) {
result = getDefaultLogo();
} else {
result = logo.getScaledInstance(LOGO_WIDTH, LOGO_HEIGHT, Image.SCALE_SMOOTH);
}
return result;
}
private void createHeader(@Nonnull String name, @Nullable String description) {
Box panel = Box.createVerticalBox();
add(panel, BorderLayout.NORTH);
Box content = Box.createVerticalBox();
content.setAlignmentX(Component.LEFT_ALIGNMENT);
content.setBorder(new EmptyBorder(5, 20, 0, 0));
content.setMinimumSize(new Dimension(50, 50));
content.setPreferredSize(new Dimension(50, 50));
panel.add(content);
JLabel nameLabel = new JLabel(name);
nameLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
nameLabel.setFont(nameLabel.getFont().deriveFont(Font.BOLD, 19));
nameLabel.setForeground(Color.getHSBColor(0, 0, 0.25f));
content.add(nameLabel);
if (description != null && ! description.isEmpty()) {
content.add(Box.createVerticalStrut(5));
JLabel descLabel = new JLabel(description);
descLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
descLabel.setFont(descLabel.getFont().deriveFont(Font.PLAIN));
descLabel.setForeground(Color.getHSBColor(0, 0, 0.25f));
content.add(descLabel);
}
panel.add(Box.createVerticalStrut(4));
JSeparator rule = new JSeparator(SwingConstants.HORIZONTAL);
rule.setBorder(new EmptyBorder(10, 20, 10, 20));
rule.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.add(rule);
panel.add(Box.createVerticalStrut(5));
}
private Image getDefaultLogo() {
Image original = GraphicsUtil.createImage(OecLogoBgWhite.class, LOGO_WIDTH, LOGO_HEIGHT);
BufferedImage result = new BufferedImage(LOGO_WIDTH, LOGO_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
// draw original image with grey shade
g.setComposite(AlphaComposite.SrcOver.derive(0.3f));
g.drawImage(original, 0, 0, null);
g.dispose();
return result;
}
}