/** * This software is released as part of the Pumpernickel project. * * All com.pump resources in the Pumpernickel project are distributed under the * MIT License: * https://raw.githubusercontent.com/mickleness/pumpernickel/master/License.txt * * More information about the Pumpernickel project is available here: * https://mickleness.github.io/pumpernickel/ */ package com.pump.swing; import java.awt.AlphaComposite; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javax.swing.AbstractButton; import javax.swing.JComponent; /** * This component stores an image of another component, and displays only that * image. * <P> * This is useful as a proxy/substitute for existing components that already * have a permanent home in the UI. */ public class MockComponent extends JComponent { private static final long serialVersionUID = 1L; BufferedImage image; /** * This creates a MockComponent that displays the image provided. A shallow * reference to this image is used, so you should not modify the argument * image. * * @param bi */ public MockComponent(BufferedImage bi) { this.image = bi; Dimension d = new Dimension(bi.getWidth(), bi.getHeight()); setSize(d); setPreferredSize(d); } /** * Creates a MockComponent that resembles the argument component. * <P> * Note this method will traverse c and its subcomponents and may * temporarily change properties of inner components: such as the focused * state, the visibility, etc. * <P> * The goal is of this component is not to mirror the exact state of a * component, but rather to provide a sample image of this component in its * plain, unmodified, unused state. * * @param c */ public MockComponent(JComponent c) { Dimension preferredSize = c.getPreferredSize(); Dimension currentSize = c.getSize(); Dimension d = new Dimension(Math.max(preferredSize.width, currentSize.width), Math.max(preferredSize.height, currentSize.height)); if (currentSize.width == 0 || currentSize.height == 0) { // if the component isn't visible yet c.setSize(d); c.doLayout(); } storeState(c); image = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setComposite(AlphaComposite.Clear); g.fillRect(0, 0, d.width, d.height); g.setComposite(AlphaComposite.SrcOver); c.paint(g); g.dispose(); setPreferredSize(d); setMinimumSize(d); setMaximumSize(d); setOpaque(c.isOpaque()); setName(c.getName()); setToolTipText(c.getToolTipText()); restoreState(c); } public BufferedImage getBufferedImage() { return image; } private static String WAS_SELECTED = "MockComponent.wasSelected"; private static String WAS_FOCUS_PAINTED = "MockComponent.wasFocusPainted"; private static String WAS_ENABLED = "MockComponent.wasEnabled"; private static String WAS_VISIBLE = "MockComponent.wasVisible"; /** * Temporarily massage this component so it is visible, enabled, unselected, * unfocused, etc. */ private void storeState(JComponent c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; b.putClientProperty(WAS_SELECTED, new Boolean(b.isSelected())); b.putClientProperty(WAS_FOCUS_PAINTED, new Boolean(b.isSelected())); b.setSelected(false); b.setFocusPainted(false); } if (c.isEnabled() == false) { c.putClientProperty(WAS_ENABLED, new Boolean(c.isEnabled())); c.setEnabled(true); } if (c.isVisible() == false) { c.putClientProperty(WAS_VISIBLE, new Boolean(c.isVisible())); c.setVisible(true); } for (int a = 0; a < c.getComponentCount(); a++) { if (c.getComponent(a) instanceof JComponent) { storeState((JComponent) c.getComponent(a)); } } } /** Restore this component back to its original goodness. */ private void restoreState(JComponent c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton) c; if (b.getClientProperty(WAS_SELECTED) != null) { b.setSelected(((Boolean) b.getClientProperty(WAS_SELECTED)) .booleanValue()); b.putClientProperty(WAS_SELECTED, null); } if (b.getClientProperty(WAS_FOCUS_PAINTED) != null) { b.setFocusPainted(((Boolean) b .getClientProperty(WAS_FOCUS_PAINTED)).booleanValue()); b.putClientProperty(WAS_FOCUS_PAINTED, null); } } if (c.getClientProperty(WAS_ENABLED) != null) { c.setEnabled(((Boolean) c.getClientProperty(WAS_ENABLED)) .booleanValue()); c.putClientProperty(WAS_ENABLED, null); } if (c.getClientProperty(WAS_VISIBLE) != null) { c.setVisible(((Boolean) c.getClientProperty(WAS_VISIBLE)) .booleanValue()); c.putClientProperty(WAS_VISIBLE, null); } for (int a = 0; a < c.getComponentCount(); a++) { if (c.getComponent(a) instanceof JComponent) { restoreState((JComponent) c.getComponent(a)); } } } @Override protected void paintComponent(Graphics g) { g.drawImage(image, getWidth() / 2 - image.getWidth() / 2, getHeight() / 2 - image.getHeight() / 2, null); } }