/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.plugin.desktoputil; import java.awt.*; import java.awt.image.*; import java.beans.*; import java.lang.reflect.*; import javax.swing.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; import org.jitsi.util.*; /** * The SCScrollPane is a JScrollPane with a custom viewport that allows to * set an image as a background. Depending on the * "impl.gui.IS_CONTACT_LIST_TEXTURE_BG_ENABLED" property we'll be setting a * single image or a texture of images. * * @author Yana Stamcheva * @author Adam Netocny */ public class SIPCommScrollPane extends JScrollPane implements Skinnable { private static final long serialVersionUID = 0L; /** * Creates an SCSCrollPane. */ public SIPCommScrollPane() { this.setBorder(BorderFactory.createMatteBorder( 1, 0, 1, 0, Color.GRAY)); this.setViewport(new SCViewport()); this.getVerticalScrollBar().setUnitIncrement(100); } /** * Sets the view of this JViewport. * * @param view the view to set. */ @Override public void setViewportView(Component view) { if (view instanceof JComponent) { JComponent viewAsJComponent = (JComponent) view; viewAsJComponent.setBorder( BorderFactory.createEmptyBorder(3, 3, 3, 3)); viewAsJComponent.setOpaque(false); } super.setViewportView(view); } /** * Reloads skin information in viewport. */ public void loadSkin() { ((SCViewport) getViewport()).loadSkin(); } /** * The SCViewport used as viewport in this scrollpane. */ private static class SCViewport extends JViewport implements Skinnable { private static final long serialVersionUID = 1L; private BufferedImage bgImage; private Color color; private TexturePaint texture; /** * Creates the SCViewport. */ public SCViewport() { this.setBackground(Color.WHITE); loadSkin(); } /** * Returns the boolean value of the property given by key. * @param key the key of the property we look for * @return the boolean value of the searched property */ private boolean getSettingsBoolean(String key) { return Boolean.parseBoolean( DesktopUtilActivator.getResources().getSettingsString(key)); } /** * Paints this viewport. * @param g the Graphics object used for painting */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); g = g.create(); try { AntialiasingManager.activateAntialiasing(g); Graphics2D g2 = (Graphics2D) g; int width = getWidth(); int height = getHeight(); // paint the image if (bgImage != null) { if (texture != null) { g2.setPaint(texture); g2.fillRect(0, 0, width, height); } else { g.setColor(color); // paint the background with the chosen color g.fillRect(0, 0, width, height); g2.drawImage(bgImage, width - bgImage.getWidth(), height - bgImage.getHeight(), this); } } } finally { g.dispose(); } } /** * Reloads background. */ public void loadSkin() { if(getSettingsBoolean("impl.gui.IS_CONTACT_LIST_IMG_BG_ENABLED")) { bgImage = DesktopUtilActivator.getImage("service.gui.MAIN_WINDOW_BACKGROUND"); if (getSettingsBoolean( "impl.gui.IS_CONTACT_LIST_TEXTURE_BG_ENABLED") && (bgImage != null)) { texture = new TexturePaint(bgImage, new Rectangle(0, 0, bgImage .getWidth(null), bgImage.getHeight(null))); color = null; } else { texture = null; color = new Color(DesktopUtilActivator.getResources().getColor( "service.gui.CONTACT_LIST_BACKGROUND")); } } else { bgImage = null; texture = null; color = null; } } } /** * Releases the resources allocated by this instance throughout its lifetime * and prepares it for garbage collection. */ public void dispose() { if(OSUtils.IS_MAC) { // Apple introduced a memory leak in JViewport class - // they add a PropertyChangeListeners to the CToolkit try { Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); PropertyChangeListener[] pcl = defaultToolkit.getPropertyChangeListeners( "apple.awt.contentScaleFactor"); for(PropertyChangeListener pc : pcl) { // find the reference to the object created the listener Field f = pc.getClass().getDeclaredField("this$0"); f.setAccessible(true); // If we are the parent, clean up. if(f.get(pc).equals(this.getViewport())) { defaultToolkit.removePropertyChangeListener( "apple.awt.contentScaleFactor", pc); break; } } } catch(Throwable t) { if (t instanceof ThreadDeath) throw (ThreadDeath) t; } } } }