Mega Code Archive

 
Categories / Java Tutorial / Swing
 

Compents are laid out in a circle

/*   * JCommon : a free general purpose class library for the Java(tm) platform  *   *  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.  *   * Project Info:  http://www.jfree.org/jcommon/index.html  *  * This library is free software; you can redistribute it and/or modify it   * under the terms of the GNU Lesser General Public License as published by   * the Free Software Foundation; either version 2.1 of the License, or   * (at your option) any later version.  *  * This library is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public   * License for more details.  *  * You should have received a copy of the GNU Lesser General Public  * License along with this library; if not, write to the Free Software  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,   * USA.    *  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.   * in the United States and other countries.]  *   * -----------------  * RadialLayout.java  * -----------------  * (C) Copyright 2003, 2004, by Bryan Scott (for Australian Antarctic Division).  *  * Original Author:  Bryan Scott (for Australian Antarctic Division);  * Contributor(s):   David Gilbert (for Object Refinery Limited);  *  * Changes:  * --------  * 30-Jun-2003 : Version 1 (BS);  * 24-Jul-2003 : Completed missing Javadocs (DG);  *  */ import java.awt.Checkbox; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Frame; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Panel; import java.io.Serializable; /**  * RadialLayout is a component layout manager.  Compents are laid out in a  * circle. If only one component is contained in the layout it is positioned  * centrally, otherwise components are evenly spaced around the centre with  * the first component placed to the North.  *<P>  * This code was developed to display CTD rosette firing control  *  * WARNING: Not thoughly tested, use at own risk.  *   * @author Bryan Scott (for Australian Antarctic Division)  */ public class RadialLayout implements LayoutManager, Serializable {          /** For serialization. */     private static final long serialVersionUID = -7582156799248315534L;          /** The minimum width. */     private int minWidth = 0;          /** The minimum height. */     private int minHeight = 0;          /** The maximum component width. */     private int maxCompWidth = 0;          /** The maximum component height. */     private int maxCompHeight = 0;          /** The preferred width. */     private int preferredWidth = 0;          /** The preferred height. */     private int preferredHeight = 0;          /** Size unknown flag. */     private boolean sizeUnknown = true;     /**       * Constructs this layout manager with default properties.       */     public RadialLayout() {         super();     }     /**      * Not used.      *      * @param comp  the component.      */     public void addLayoutComponent(final Component comp) {         // not used     }     /**      * Not used.      *      * @param comp  the component.      */     public void removeLayoutComponent(final Component comp) {         // not used     }     /**      * Not used.      *      * @param name  the component name.      * @param comp  the component.      */     public void addLayoutComponent(final String name, final Component comp) {         // not used     }     /**      * Not used.      *      * @param name  the component name.      * @param comp  the component.      */     public void removeLayoutComponent(final String name, final Component comp) {         // not used     }     /**      * Sets the sizes attribute of the RadialLayout object.      *      * @param  parent  the parent.      *       * @see LayoutManager      */     private void setSizes(final Container parent) {         final int nComps = parent.getComponentCount();         //Reset preferred/minimum width and height.         this.preferredWidth = 0;         this.preferredHeight = 0;         this.minWidth = 0;         this.minHeight = 0;         for (int i = 0; i < nComps; i++) {             final Component c = parent.getComponent(i);             if (c.isVisible()) {                 final Dimension d = c.getPreferredSize();                 if (this.maxCompWidth < d.width) {                     this.maxCompWidth = d.width;                 }                 if (this.maxCompHeight < d.height) {                     this.maxCompHeight = d.height;                 }                 this.preferredWidth += d.width;                 this.preferredHeight += d.height;             }         }         this.preferredWidth  = this.preferredWidth / 2;         this.preferredHeight = this.preferredHeight / 2;         this.minWidth = this.preferredWidth;         this.minHeight = this.preferredHeight;     }     /**      * Returns the preferred size.      *      * @param parent  the parent.      *      * @return The preferred size.      * @see LayoutManager      */     public Dimension preferredLayoutSize(final Container parent) {         final Dimension dim = new Dimension(0, 0);         setSizes(parent);         //Always add the container's insets!         final Insets insets = parent.getInsets();         dim.width = this.preferredWidth + insets.left + insets.right;         dim.height = this.preferredHeight + insets.top + insets.bottom;         this.sizeUnknown = false;         return dim;     }     /**      * Returns the minimum size.      *      * @param parent  the parent.      *      * @return The minimum size.      * @see LayoutManager      */     public Dimension minimumLayoutSize(final Container parent) {         final Dimension dim = new Dimension(0, 0);         //Always add the container's insets!         final Insets insets = parent.getInsets();         dim.width = this.minWidth + insets.left + insets.right;         dim.height = this.minHeight + insets.top + insets.bottom;         this.sizeUnknown = false;         return dim;     }    /**     * This is called when the panel is first displayed, and every time its size     * changes.     * Note: You CAN'T assume preferredLayoutSize or minimumLayoutSize will be     * called -- in the case of applets, at least, they probably won't be.     *     * @param  parent  the parent.     * @see LayoutManager     */     public void layoutContainer(final Container parent) {         final Insets insets = parent.getInsets();         final int maxWidth = parent.getSize().width              - (insets.left + insets.right);         final int maxHeight = parent.getSize().height              - (insets.top + insets.bottom);         final int nComps = parent.getComponentCount();         int x = 0;         int y = 0;         // Go through the components' sizes, if neither preferredLayoutSize nor         // minimumLayoutSize has been called.         if (this.sizeUnknown) {             setSizes(parent);         }         if (nComps < 2) {             final Component c = parent.getComponent(0);             if (c.isVisible()) {                 final Dimension d = c.getPreferredSize();                 c.setBounds(x, y, d.width, d.height);             }         }          else {             double radialCurrent = Math.toRadians(90);             final double radialIncrement = 2 * Math.PI / nComps;             final int midX = maxWidth / 2;             final int midY = maxHeight / 2;             final int a = midX - this.maxCompWidth;             final int b = midY - this.maxCompHeight;             for (int i = 0; i < nComps; i++) {                 final Component c = parent.getComponent(i);                 if (c.isVisible()) {                     final Dimension d = c.getPreferredSize();                     x = (int) (midX                                - (a * Math.cos(radialCurrent))                                - (d.getWidth() / 2)                                + insets.left);                     y = (int) (midY                                - (b * Math.sin(radialCurrent))                                - (d.getHeight() / 2)                                + insets.top);                     // Set the component's size and position.                     c.setBounds(x, y, d.width, d.height);                 }                 radialCurrent += radialIncrement;             }         }     }     /**      * Returns the class name.      *       * @return The class name.      */     public String toString() {         return getClass().getName();     }     /**      * Run a demonstration.      *      * @param args  ignored.      *       * @throws Exception when an error occurs.      */     public static void main(final String[] args) throws Exception {         final Frame frame = new Frame();         final Panel panel = new Panel();         panel.setLayout(new RadialLayout());         panel.add(new Checkbox("One"));         panel.add(new Checkbox("Two"));         panel.add(new Checkbox("Three"));         panel.add(new Checkbox("Four"));         panel.add(new Checkbox("Five"));         panel.add(new Checkbox("One"));         panel.add(new Checkbox("Two"));         panel.add(new Checkbox("Three"));         panel.add(new Checkbox("Four"));         panel.add(new Checkbox("Five"));         frame.add(panel);         frame.setSize(300, 500);         frame.setVisible(true);     } }