Mega Code Archive

 
Categories / Java / Advanced Graphics
 

LayeredPane Layout

/*  * 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.AlphaComposite; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Transparency; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JComponent; import javax.swing.JLayeredPane; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.net.URL; import javax.swing.Box; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /**  *  * @author Romain Guy <romain.guy@mac.com>  */ public class LayeredPaneLayout extends JFrame {     private JLayeredPane layeredPane;     private Loupe loupe;          public LayeredPaneLayout() {         super("Layered Pane Layout");                  layeredPane = new JLayeredPane();         addLayersControl();         loadImagesInLayers();         createLoupe();                  setSize(540, 350);         setLocationRelativeTo(null);         setResizable(false);     }          public static void main(String[] args) {         SwingUtilities.invokeLater(new Runnable() {             public void run() {                 new LayeredPaneLayout().setVisible(true);             }         });     }     private void loadImagesInLayers() {         layeredPane.setLayout(new FlowLayout());                  for (int i = 2; i <= 5; i++) {             String name = "photo" + i + ".jpg";             URL url = getClass().getResource(name);             Icon icon = new ImageIcon(url);             JLabel label = new JLabel(icon);                          layeredPane.add(label,                     (Integer) (JLayeredPane.DEFAULT_LAYER + (i - 1) * 2));         }                  add(layeredPane);     }     private void addLayersControl() {         JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));                  JComboBox layerSelection = new JComboBox(new String[] {             "Layer 0", "Layer 1", "Layer 2", "Layer 3", "Layer 4"          });         layerSelection.addActionListener(new ActionListener() {             public void actionPerformed(ActionEvent actionEvent) {                 JComboBox layerSelection = (JComboBox) actionEvent.getSource();                 int layerId = layerSelection.getSelectedIndex();                 layeredPane.setLayer(loupe,                         (Integer) (JLayeredPane.DEFAULT_LAYER + layerId * 2 + 1));             }         });         panel.add(new JLabel("Loupe Layer: "));         panel.add(layerSelection);                  JSlider zoomSelection = new JSlider(1, 16, 2);         zoomSelection.setPaintTicks(true);         zoomSelection.setSnapToTicks(true);         zoomSelection.setPaintLabels(true);         zoomSelection.addChangeListener(new ChangeListener() {             public void stateChanged(ChangeEvent changeEvent) {                 JSlider zoomSelection = (JSlider) changeEvent.getSource();                 loupe.setZoomLevel(zoomSelection.getValue());             }         });                  panel.add(Box.createHorizontalStrut(24));         panel.add(new JLabel("Zoom: "));         panel.add(new JLabel("1"));         panel.add(zoomSelection);         panel.add(new JLabel("16"));                  add(panel, BorderLayout.NORTH);     }     private void createLoupe() {         loupe = new Loupe(layeredPane);         Dimension size = loupe.getPreferredSize();         layeredPane.add(loupe,                 (Integer) (JLayeredPane.DEFAULT_LAYER + 1));     } } /*  * 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.  */ /**  *  * @author Romain Guy <romain.guy@mac.com>  */ class Loupe extends JComponent {     private BufferedImage loupeImage;     private Point loupeLocation = new Point(0, 0);     private JLayeredPane layeredPane;     private BufferedImage buffer;     private int zoomLevel = 2;     public Loupe(JLayeredPane layeredPane) {         this.layeredPane = layeredPane;         loadImages();                  layeredPane.addMouseMotionListener(new MouseMotionAdapter() {             public void mouseMoved(MouseEvent mouseEvent) {                 Point location = mouseEvent.getPoint();                 location.translate(-getWidth() / 2, -getHeight() / 2);                 setLocation(location);             }         });         addComponentListener(new ComponentListener() {             public void componentHidden(ComponentEvent componentEvent) {                 resetBuffer();             }                          public void componentMoved(ComponentEvent componentEvent) {             }                          public void componentResized(ComponentEvent componentEvent) {                 resetBuffer();             }                         public void componentShown(ComponentEvent componentEvent) {             }         });     }     public int getZoomLevel() {         return this.zoomLevel;     }          public void setZoomLevel(int zoom) {         if (zoom < 1) {             zoom = 1;         }                  int oldZoom = this.zoomLevel;         this.zoomLevel = zoom;         firePropertyChange("zoomLevel", oldZoom, this.zoomLevel);                  repaint();     }          @Override     public Dimension getPreferredSize() {         return new Dimension(loupeImage.getWidth(),                 loupeImage.getHeight());     }          public void resetBuffer() {         buffer = null;     }          private void loadImages() {         try {             loupeImage = ImageIO.read(getClass().getResource("loupe.png"));         } catch (IOException ex) {             ex.printStackTrace();         }     }          @Override     protected void paintComponent(Graphics g) {         if (buffer == null) {             buffer = createBuffer();         }                  Graphics2D g2 = buffer.createGraphics();         g2.setComposite(AlphaComposite.Clear);         g2.fillRect(0, 0, buffer.getWidth(), buffer.getHeight());         g2.setComposite(AlphaComposite.Src);         Point location = getLocation();         location.translate(getWidth() / 2, getHeight() / 2);                  int myLayer = layeredPane.getLayer(this);         for (int i = myLayer - 1; i >= 2; i -= 2) {             Component[] components = layeredPane.getComponentsInLayer(i);             for (Component c : components) {                 if (c.getBounds().contains(location)) {                     g2.translate(c.getX(), c.getY());                     c.paint(g2);                     g2.translate(-c.getX(), -c.getY());                 }             }         }                  g2.dispose();                  if (zoomLevel > 1) {             ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION,                     RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);             Shape clip = g.getClip();             Area newClip = new Area(clip);             newClip.intersect(new Area(new Ellipse2D.Double(6.0, 6.0, 138.0, 138.0)));                  g.setClip(newClip);             g.drawImage(buffer,                     (int) (-getX() * zoomLevel - getWidth() * 0.5 * (zoomLevel - 1)),                     (int) (-getY() * zoomLevel - getHeight() * 0.5 * (zoomLevel - 1)),                     buffer.getWidth() * zoomLevel,                     buffer.getHeight() * zoomLevel, null);             g.setClip(clip);         }                  g.drawImage(loupeImage, 0, 0, null);     }     private BufferedImage createBuffer() {         GraphicsEnvironment local = GraphicsEnvironment.getLocalGraphicsEnvironment();         GraphicsDevice device = local.getDefaultScreenDevice();         GraphicsConfiguration config = device.getDefaultConfiguration();                  Container parent = getParent();         return config.createCompatibleImage(parent.getWidth(), parent.getHeight(),                 Transparency.TRANSLUCENT);     } }