/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * 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 net.java.sip.communicator.plugin.pluginmanager; import java.awt.*; import java.util.*; import javax.swing.*; import javax.swing.table.*; import net.java.sip.communicator.plugin.desktoputil.*; import org.osgi.framework.*; /** * The <tt>ContactListCellRenderer</tt> is the custom cell renderer used in the * SIP-Communicator's <tt>ContactList</tt>. It extends JPanel instead of JLabel, * which allows adding different buttons and icons to the contact cell. * The cell border and background are repainted. * * @author Yana Stamcheva */ public class PluginListCellRenderer extends JPanel implements TableCellRenderer { /** * Serial version UID. */ private static final long serialVersionUID = 0L; /** * The end color used to paint a gradient selected background. */ private static final Color SELECTED_START_COLOR = new Color(Resources.getColor("service.gui.LIST_SELECTION_COLOR")); /** * The start color used to paint a gradient selected background. */ private static final Color SELECTED_END_COLOR = new Color(Resources.getColor("service.gui.GRADIENT_LIGHT_COLOR")); /** * The name and version label. */ private JLabel nameVersionLabel = new JLabel(); /** * The description label. */ private JLabel descriptionLabel = new JLabel(); /** * The state label. */ private JLabel stateLabel = new JLabel(); /** * Indicates if a skin is selected. */ private boolean isSelected = false; /** * The cache of the <code>ImageIcon</code> values returned by * {@link #getStateIcon(int)} because the method in question is called * whenever a table cell is painted and reading the image data out of a file * and loading it into a new <code>ImageIcon</code> at such a time * noticeably affects execution the speed. */ private final ImageIcon[] stateIconCache = new ImageIcon[5]; /** * Initialize the panel containing the node. */ public PluginListCellRenderer() { super(new BorderLayout(8, 0)); this.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); this.setBackground(Color.WHITE); JPanel mainPanel = new TransparentPanel(new GridLayout(2, 1)); mainPanel.add(nameVersionLabel); mainPanel.add(descriptionLabel); this.add(mainPanel, BorderLayout.CENTER); this.add(stateLabel, BorderLayout.WEST); } /** * Implements the <tt>ListCellRenderer</tt> method. * Returns this panel that has been configured to display bundle name, * version and description. * @param table the parent table * @param value the value of the rendered cell * @param isSelected indicates if the rendered cell is selected * @param hasFocus indicates if the rendered cell has the focus * @param rowIndex the row index of the rendered cell * @param vColIndex the column index of the rendered cell * @return the rendering component */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) { Bundle bundle = (Bundle) value; Dictionary<?, ?> headers = bundle.getHeaders(); Object bundleName = headers.get(Constants.BUNDLE_NAME); Object bundleVersion = headers.get(Constants.BUNDLE_VERSION); Object bundleDescription = headers.get(Constants.BUNDLE_DESCRIPTION); Icon stateIcon = getStateIcon(bundle.getState()); StringBuilder sb = new StringBuilder(); sb.append("<html><nobr><b>"); sb.append(bundleName != null ? bundleName.toString() : "unknown"); sb.append("</b> "); sb.append(bundleVersion != null ? bundleVersion.toString() : ""); if (PluginManagerActivator.isSystemBundle(bundle)) { sb.append(" <b>("); sb.append(Resources.getString("plugin.pluginmanager.SYSTEM")); sb.append(")</b>"); } sb.append("</nobr></html>"); this.nameVersionLabel.setText(sb.toString()); if(bundleDescription != null) this.descriptionLabel.setText(bundleDescription.toString()); else this.descriptionLabel.setText(""); if(stateIcon != null) this.stateLabel.setIcon(stateIcon); this.isSelected = isSelected; return this; } /** * Returns an icon corresponding to the given <tt>state</tt>. * @param state the state, for which we're looking for an icon * @return the icon corresponding to the given state */ private ImageIcon getStateIcon(int state) { int cacheIndex; String imageID; switch (state) { case Bundle.INSTALLED: cacheIndex = 0; imageID = "plugin.pluginmanager.INSTALLED_STATE"; break; case Bundle.RESOLVED: cacheIndex = 1; imageID = "plugin.pluginmanager.DEACTIVATED_STATE"; break; case Bundle.STARTING: cacheIndex = 2; imageID = "plugin.pluginmanager.STARTING_STATE"; break; case Bundle.STOPPING: cacheIndex = 3; imageID = "plugin.pluginmanager.STOPPING_STATE"; break; case Bundle.ACTIVE: cacheIndex = 4; imageID = "plugin.pluginmanager.ACTIVATE_STATE"; break; default: return null; } ImageIcon stateIcon = stateIconCache[cacheIndex]; if (stateIcon == null) stateIconCache[cacheIndex] = stateIcon = Resources.getResources().getImage(imageID); return stateIcon; } /** * Paint a background for all groups and a round blue border and background * when a cell is selected. * @param g the <tt>Graphics</tt> object used for painting */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); g = g.create(); try { internalPaintComponent(g); } finally { g.dispose(); } } /** * Paints a custom gradient background for selected cells. * @param g the <tt>Graphics</tt> object used for painting */ private void internalPaintComponent(Graphics g) { AntialiasingManager.activateAntialiasing(g); Graphics2D g2 = (Graphics2D) g; int width = getWidth(); int height = getHeight(); if (this.isSelected) { GradientPaint p = new GradientPaint(width / 2, 0, SELECTED_START_COLOR, width / 2, height, SELECTED_END_COLOR); g2.setPaint(p); g2.fillRoundRect(1, 1, width, height - 1, 7, 7); } g2.setColor(SELECTED_START_COLOR); g2.drawLine(0, height - 1, width, height - 1); } }