Mega Code Archive

 
Categories / Java / Advanced Graphics
 

Shedding Light Demo

/*  * Copyright (c) 2007, Romain Guy  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  *   * Redistributions of source code must retain the above copyright  *     notice, this list of conditions and the following disclaimer.  *   * Redistributions in binary form must reproduce the above  *     copyright notice, this list of conditions and the following  *     disclaimer in the documentation and/or other materials provided  *     with the distribution.  *   * Neither the name of the TimingFramework project nor the names of its  *     contributors may be used to endorse or promote products derived  *     from this software without specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.ButtonModel; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.plaf.basic.BasicButtonUI; import java.awt.Color; import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; /**  *  * @author Romain Guy <romain.guy@mac.com>  */ public class SheddingLightDemo extends JFrame {     public SheddingLightDemo() {         super("Shedding Light");                  JPanel panel = new JPanel(new FlowLayout());         panel.setBackground(new Color(0x8B93A3));                  panel.add(new LightButton("Shed"));         panel.add(new LightButton("The"));         panel.add(new LightButton("Light"));                  add(panel);                  pack();         setLocationRelativeTo(null);         setDefaultCloseOperation(EXIT_ON_CLOSE);     }     public static void main(String[] args) {         try {             UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());         } catch (ClassNotFoundException ex) {             ex.printStackTrace();         } catch (IllegalAccessException ex) {             ex.printStackTrace();         } catch (InstantiationException ex) {             ex.printStackTrace();         } catch (UnsupportedLookAndFeelException ex) {             ex.printStackTrace();         }                  SwingUtilities.invokeLater(new Runnable() {             public void run() {                 new SheddingLightDemo().setVisible(true);             }         });     } } /*  * Copyright (c) 2007, Romain Guy  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  *   * Redistributions of source code must retain the above copyright  *     notice, this list of conditions and the following disclaimer.  *   * Redistributions in binary form must reproduce the above  *     copyright notice, this list of conditions and the following  *     disclaimer in the documentation and/or other materials provided  *     with the distribution.  *   * Neither the name of the TimingFramework project nor the names of its  *     contributors may be used to endorse or promote products derived  *     from this software without specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */ class LightButton extends JButton {     private float shadowOffsetX;     private float shadowOffsetY;          private Color shadowColor = Color.BLACK;     private int shadowDirection = 60;          private Image normalButton, normalButtonPressed, buttonHighlight;     private int shadowDistance = 1;     private Insets sourceInsets = new Insets(6, 7, 6, 8);     private Dimension buttonDimension = new Dimension(116, 35);     private Color buttonForeground = Color.WHITE;     private Font buttonFont = new Font("Arial", Font.BOLD, 22);          private float ghostValue;          private boolean main = false;     public LightButton(String text) {         this();         setText(text);     }          public LightButton(Action a) {         this();         setAction(a);     }          public LightButton() {         computeShadow();         setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));         setForeground(buttonForeground);         setFont(buttonFont);         setContentAreaFilled(false);         setBorderPainted(false);         setFocusable(false);                  normalButton = loadImage("button-normal.png");         normalButtonPressed = loadImage("button-normal-pressed.png");         buttonHighlight = loadImage("header-halo.png");                  // Hacky? Hacky!         setUI(new BasicButtonUI() {             @Override             public Dimension getMinimumSize(JComponent c) {                 return getPreferredSize(c);             }                          @Override             public Dimension getMaximumSize(JComponent c) {                 return getPreferredSize(c);             }                          @Override             public Dimension getPreferredSize(JComponent c) {                 Insets insets = c.getInsets();                 Dimension d = new Dimension(buttonDimension);                 d.width += insets.left + insets.right;                 d.height += insets.top + insets.bottom;                 return d;             }         });     }          private static Image loadImage(String fileName) {         try {             return ImageIO.read(LightButton.class.getResource(fileName));         } catch (IOException ex) {             return null;         }     }          private void computeShadow() {         double rads = Math.toRadians(shadowDirection);         shadowOffsetX = (float) Math.cos(rads) * shadowDistance;         shadowOffsetY = (float) Math.sin(rads) * shadowDistance;     }          private Image getImage(boolean armed) {         return armed ? normalButtonPressed : normalButton;     }          @Override     protected void paintComponent(Graphics g) {         Graphics2D g2 = (Graphics2D) g;         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,                 RenderingHints.VALUE_ANTIALIAS_ON);                  ButtonModel m = getModel();         Insets insets = getInsets();                  int width = getWidth() - insets.left - insets.right;         int height = getHeight() - insets.top - insets.bottom;                  tileStretchPaint(g2,this,(BufferedImage) getImage(m.isArmed()), sourceInsets);                  if (getModel().isRollover()) {             g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,                     RenderingHints.VALUE_INTERPOLATION_BILINEAR);             g2.drawImage(buttonHighlight,                     insets.left + 2, insets.top + 2,                     width - 4, height - 4, null);         }                  FontMetrics fm = getFontMetrics(getFont());         TextLayout layout = new TextLayout(getText(),                 getFont(),                 g2.getFontRenderContext());         Rectangle2D bounds = layout.getBounds();                  int x = (int) (getWidth() - insets.left - insets.right -                 bounds.getWidth()) / 2;         //x -= 2;         int y = (getHeight() - insets.top - insets.bottom -                  fm.getMaxAscent() - fm.getMaxDescent()) / 2;         y += fm.getAscent() - 1;                  if (m.isArmed()) {             x += 1;             y += 1;         }                  g2.setColor(shadowColor);         layout.draw(g2,                 x + (int) Math.ceil(shadowOffsetX),                 y + (int) Math.ceil(shadowOffsetY));         g2.setColor(getForeground());         layout.draw(g2, x, y);     }          /**      * Draws an image on top of a component by doing a 3x3 grid stretch of the image      * using the specified insets.      *      * From SwingLabs, licensed under LGPL      */     public static void tileStretchPaint(Graphics g,                  JComponent comp,                 BufferedImage img,                 Insets ins) {                  int left = ins.left;         int right = ins.right;         int top = ins.top;         int bottom = ins.bottom;                  // top         g.drawImage(img,                     0,0,left,top,                     0,0,left,top,                     null);         g.drawImage(img,                     left,                 0,                      comp.getWidth() - right, top,                      left,                 0,                      img.getWidth()  - right, top,                      null);         g.drawImage(img,                     comp.getWidth() - right, 0,                      comp.getWidth(),         top,                      img.getWidth()  - right, 0,                      img.getWidth(),          top,                      null);         // middle         g.drawImage(img,                     0,    top,                      left, comp.getHeight()-bottom,                     0,    top,                        left, img.getHeight()-bottom,                     null);                  g.drawImage(img,                     left,                  top,                      comp.getWidth()-right,      comp.getHeight()-bottom,                     left,                  top,                        img.getWidth()-right,  img.getHeight()-bottom,                     null);                   g.drawImage(img,                     comp.getWidth()-right,     top,                      comp.getWidth(),           comp.getHeight()-bottom,                     img.getWidth()-right, top,                        img.getWidth(),       img.getHeight()-bottom,                     null);                  // bottom         g.drawImage(img,                     0,comp.getHeight()-bottom,                      left, comp.getHeight(),                     0,img.getHeight()-bottom,                        left,img.getHeight(),                     null);         g.drawImage(img,                     left,                    comp.getHeight()-bottom,                      comp.getWidth()-right,        comp.getHeight(),                     left,                    img.getHeight()-bottom,                        img.getWidth()-right,    img.getHeight(),                     null);         g.drawImage(img,                     comp.getWidth()-right,     comp.getHeight()-bottom,                      comp.getWidth(),           comp.getHeight(),                     img.getWidth()-right, img.getHeight()-bottom,                        img.getWidth(),       img.getHeight(),                     null);     } }