import java.awt.*; import java.awt.image.*; import javax.swing.*; /* * Support custom painting on a panel in the form of * * a) images - that can be scaled, tiled or painted at original size * b) non solid painting - that can be done by using a Paint object * * Also, any component added directly to this panel will be made * non-opaque so that the custom painting can show through. */ public class BackgroundPanel extends JPanel { public static final int SCALED = 0; public static final int TILED = 1; public static final int ACTUAL = 2; private Paint painter; private Image image; private int style = SCALED; private float alignmentX = 0.5f; private float alignmentY = 0.5f; private boolean isTransparentAdd = true; /* * Set image as the background with the SCALED style */ public BackgroundPanel(Image image) { this(image, SCALED); } /* * Set image as the background with the specified style */ public BackgroundPanel(Image image, int style) { setImage( image ); setStyle( style ); setLayout( new BorderLayout() ); } /* * Set image as the backround with the specified style and alignment */ public BackgroundPanel(Image image, int style, float alignmentX, float alignmentY) { setImage( image ); setStyle( style ); setImageAlignmentX( alignmentX ); setImageAlignmentY( alignmentY ); setLayout( new BorderLayout() ); } /* * Use the Paint interface to paint a background */ public BackgroundPanel(Paint painter) { setPaint( painter ); setLayout( new BorderLayout() ); } /* * Set the image used as the background */ public void setImage(Image image) { this.image = image; repaint(); } /* * Set the style used to paint the background image */ public void setStyle(int style) { this.style = style; repaint(); } /* * Set the Paint object used to paint the background */ public void setPaint(Paint painter) { this.painter = painter; repaint(); } /* * Specify the horizontal alignment of the image when using ACTUAL style */ public void setImageAlignmentX(float alignmentX) { this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX; repaint(); } /* * Specify the horizontal alignment of the image when using ACTUAL style */ public void setImageAlignmentY(float alignmentY) { this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY; repaint(); } /* * Override method so we can make the component transparent */ public void add(JComponent component) { add(component, null); } /* * Override to provide a preferred size equal to the image size */ @Override public Dimension getPreferredSize() { if (image == null) return super.getPreferredSize(); else return new Dimension(image.getWidth(null), image.getHeight(null)); } /* * Override method so we can make the component transparent */ public void add(JComponent component, Object constraints) { if (isTransparentAdd) { makeComponentTransparent(component); } super.add(component, constraints); } /* * Controls whether components added to this panel should automatically * be made transparent. That is, setOpaque(false) will be invoked. * The default is set to true. */ public void setTransparentAdd(boolean isTransparentAdd) { this.isTransparentAdd = isTransparentAdd; } /* * Try to make the component transparent. * For components that use renderers, like JTable, you will also need to * change the renderer to be transparent. An easy way to do this it to * set the background of the table to a Color using an alpha value of 0. */ private void makeComponentTransparent(JComponent component) { component.setOpaque( false ); if (component instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)component; JViewport viewport = scrollPane.getViewport(); viewport.setOpaque( false ); Component c = viewport.getView(); if (c instanceof JComponent) { ((JComponent)c).setOpaque( false ); } } } /* * Add custom painting */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // Invoke the painter for the background if (painter != null) { Dimension d = getSize(); Graphics2D g2 = (Graphics2D) g; g2.setPaint(painter); g2.fill( new Rectangle(0, 0, d.width, d.height) ); } // Draw the image if (image == null ) return; switch (style) { case SCALED : drawScaled(g); break; case TILED : drawTiled(g); break; case ACTUAL : drawActual(g); break; default: drawScaled(g); } } /* * Custom painting code for drawing a SCALED image as the background */ private void drawScaled(Graphics g) { Dimension d = getSize(); g.drawImage(image, 0, 0, d.width, d.height, null); } /* * Custom painting code for drawing TILED images as the background */ private void drawTiled(Graphics g) { Dimension d = getSize(); int width = image.getWidth( null ); int height = image.getHeight( null ); for (int x = 0; x < d.width; x += width) { for (int y = 0; y < d.height; y += height) { g.drawImage( image, x, y, null, null ); } } } /* * Custom painting code for drawing the ACTUAL image as the background. * The image is positioned in the panel based on the horizontal and * vertical alignments specified. */ private void drawActual(Graphics g) { Dimension d = getSize(); Insets insets = getInsets(); int width = d.width - insets.left - insets.right; int height = d.height - insets.top - insets.left; float x = (width - image.getWidth(null)) * alignmentX; float y = (height - image.getHeight(null)) * alignmentY; g.drawImage(image, (int)x + insets.left, (int)y + insets.top, this); } }