LayoutStyle.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:15k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit.layouts;
  26. import com.sun.lwuit.Component;
  27. import com.sun.lwuit.Container;
  28. /**
  29.  * LayoutStyle is used to determine how much space to place between components
  30.  * during layout.  LayoutStyle can be obtained for two components, or for
  31.  * a component relative to an edge of a parent container.  The amount of
  32.  * space can vary depending upon whether or not the components are
  33.  * logically grouped together (<code>RELATED</code>).
  34.  * <p>
  35.  * This class is primarily useful for JREs prior to 1.6.  In 1.6 API for this
  36.  * was added to Swing.  When run on a JRE of 1.6 or greater this will call into
  37.  * the appropriate methods in Swing.
  38.  *
  39.  * @version $Revision: 1.10 $
  40.  */
  41. public class LayoutStyle {
  42.     /**
  43.      * Possible argument to getPreferredGap.  Used to indicate the two components
  44.      * are grouped together.
  45.      */
  46.     public static final int RELATED = 0;
  47.     /**
  48.      * Possible argument to getPreferredGap.  Used to indicate the two components
  49.      * are not grouped together.
  50.      */
  51.     public static final int UNRELATED = 1;
  52.     
  53.     /**
  54.      * Possible argument to getPreferredGap.  Used to indicate the distance
  55.      * to indent a component is being requested.  To visually indicate
  56.      * a set of related components they will often times be horizontally
  57.      * indented, the <code>INDENT</code> constant for this.
  58.      * For example, to indent a check box relative to a label use this
  59.      * constant to <code>getPreferredGap</code>.
  60.      */
  61.     public static final int INDENT = 3;
  62.     private static LayoutStyle layoutStyle = new LayoutStyle();
  63.     //private static LookAndFeel laf;
  64.     /**
  65.      * Sets the LayoutStyle instance to use for this look and feel.
  66.      * You generally don't need to invoke this, instead use the getter which
  67.      * will return the LayoutStyle appropriate for the current look and feel.
  68.      * 
  69.      * @param layout the LayoutStyle to use; a value of null indicates 
  70.      *        the default should be used
  71.      */
  72.     public static void setSharedInstance(LayoutStyle layout) {
  73.         layoutStyle = layout;
  74.     }
  75.     
  76.     /**
  77.      * Factory methods for obtaining the current <code>LayoutStyle</code>
  78.      * object appropriate for the current look and feel.
  79.      * 
  80.      * @return the current LayoutStyle instance
  81.      */
  82.     public static LayoutStyle getSharedInstance() {
  83.         return layoutStyle;
  84.     }
  85.     /**
  86.      * Returns the amount of space to use between two components.
  87.      * The return value indicates the distance to place
  88.      * <code>component2</code> relative to <code>component1</code>.
  89.      * For example, the following returns the amount of space to place
  90.      * between <code>component2</code> and <code>component1</code>
  91.      * when <code>component2</code> is placed vertically above
  92.      * <code>component1</code>:
  93.      * <pre>
  94.      *   int gap = getPreferredGap(component1, component2,
  95.      *                             LayoutStyle.RELATED,
  96.      *                             SwingConstants.NORTH, parent);
  97.      * </pre>
  98.      * The <code>type</code> parameter indicates the type 
  99.      * of gap being requested.  It can be one of the following values:
  100.      * <table>
  101.      * <tr><td><code>RELATED</code>
  102.      *     <td>If the two components will be contained in
  103.      *         the same parent and are showing similar logically related
  104.      *         items, use <code>RELATED</code>.
  105.      * <tr><td><code>UNRELATED</code>
  106.      *     <td>If the two components will be
  107.      *          contained in the same parent but show logically unrelated items
  108.      *          use <code>UNRELATED</code>.
  109.      * <tr><td><code>INDENT</code>
  110.      *     <td>Used to obtain the preferred distance to indent a component
  111.      *         relative to another.  For example, if you want to horizontally
  112.      *         indent a JCheckBox relative to a JLabel use <code>INDENT</code>.
  113.      *         This is only useful for the horizontal axis.
  114.      * </table>
  115.      * <p>
  116.      * It's important to note that some look and feels may not distinguish
  117.      * between <code>RELATED</code> and <code>UNRELATED</code>.
  118.      * <p>
  119.      * The return value is not intended to take into account the
  120.      * current size and position of <code>component2</code> or
  121.      * <code>component1</code>.  The return value may take into
  122.      * consideration various properties of the components.  For
  123.      * example, the space may vary based on font size, or the preferred
  124.      * size of the component.
  125.      * 
  126.      * @param component1 the <code>JComponent</code>
  127.      *               <code>component2</code> is being placed relative to
  128.      * @param component2 the <code>JComponent</code> being placed
  129.      * @param type how the two components are being placed
  130.      * @param position the position <code>component2</code> is being placed 
  131.      *        relative to <code>component1</code>; one of
  132.      *        <code>SwingConstants.NORTH</code>,
  133.      *        <code>SwingConstants.SOUTH</code>,
  134.      *        <code>SwingConstants.EAST</code> or
  135.      *        <code>SwingConstants.WEST</code>
  136.      * @param parent the parent of <code>component2</code>; this may differ
  137.      *        from the actual parent and may be null
  138.      * @return the amount of space to place between the two components
  139.      * @throws IllegalArgumentException if <code>position</code> is not
  140.      *         one of <code>SwingConstants.NORTH</code>,
  141.      *         <code>SwingConstants.SOUTH</code>,
  142.      *         <code>SwingConstants.EAST</code> or 
  143.      *         <code>SwingConstants.WEST</code>; <code>type</code> not one
  144.      *         of <code>INDENT</code>, <code>RELATED</code>
  145.      *         or <code>UNRELATED</code>; or <code>component1</code> or
  146.      *         <code>component2</code> is null
  147.      */
  148.     public int getPreferredGap(Component component1, Component component2,
  149.                           int type, int position, Container parent) {
  150.         if (position != GroupLayout.NORTH &&
  151.               position != GroupLayout.SOUTH &&
  152.               position != GroupLayout.WEST &&
  153.               position != GroupLayout.EAST) {
  154.             throw new IllegalArgumentException("Invalid position");
  155.         }
  156.         if (component1 == null || component2== null) {
  157.             throw new IllegalArgumentException("Components must be non-null");
  158.         }
  159.         if (type == RELATED) {
  160.             return 6;
  161.         } else if (type == UNRELATED) {
  162.             return 12;
  163.         } else if (type == INDENT) {
  164.             if (position == GroupLayout.EAST || position == GroupLayout.WEST) {
  165.                 int gap = getButtonChildIndent(component1, position);
  166.                 if (gap != 0) {
  167.                     return gap;
  168.                 }
  169.                 return 6;
  170.             }
  171.             return 6;
  172.         }
  173.         throw new IllegalArgumentException("Invalid type");
  174.     }
  175.     /**
  176.      * Returns the amount of space to position a component inside its
  177.      * parent.
  178.      *
  179.      * @param component the <code>Component</code> being positioned
  180.      * @param position the position <code>component</code> is being placed 
  181.      *        relative to its parent; one of
  182.      *        <code>SwingConstants.NORTH</code>,
  183.      *        <code>SwingConstants.SOUTH</code>,
  184.      *        <code>SwingConstants.EAST</code> or
  185.      *        <code>SwingConstants.WEST</code>
  186.      * @param parent the parent of <code>component</code>; this may differ
  187.      *        from the actual parent and may be null
  188.      * @return the amount of space to place between the component and specified
  189.      *         edge
  190.      * @throws IllegalArgumentException if <code>position</code> is not
  191.      *         one of <code>SwingConstants.NORTH</code>,
  192.      *         <code>SwingConstants.SOUTH</code>,
  193.      *         <code>SwingConstants.EAST</code> or 
  194.      *         <code>SwingConstants.WEST</code>;
  195.      *         or <code>component</code> is null
  196.      */
  197.     public int getContainerGap(Component component, int position,
  198.             Container parent) {
  199.         if (position != GroupLayout.NORTH &&
  200.               position != GroupLayout.SOUTH &&
  201.               position != GroupLayout.WEST &&
  202.               position != GroupLayout.EAST) {
  203.             throw new IllegalArgumentException("Invalid position");
  204.         }
  205.         if (component == null) {
  206.             throw new IllegalArgumentException("Component must be non-null");
  207.         }
  208.         return 12;
  209.     }
  210.     /**
  211.      * For some look and feels check boxs and radio buttons have an empty
  212.      * border around them.  Look and feel guidelines generally don't include
  213.      * this space.  Use this method to subtract this space from the specified
  214.      * components.
  215.      *
  216.      * @param source First component
  217.      * @param target Second component
  218.      * @param position Position doing layout along.
  219.      * @param offset Ideal offset, not including border/margin
  220.      * @return offset - border/margin around the component.
  221.      */
  222.     int getCBRBPadding(Component source, Component target, int position,
  223.                        int offset) {
  224.         offset -= getCBRBPadding(source, position);
  225.         if (offset > 0) {
  226.             offset -= getCBRBPadding(target, flipDirection(position));
  227.         }
  228.         if (offset < 0) {
  229.             return 0;
  230.         }
  231.         return offset;
  232.     }
  233.     /**
  234.      * For some look and feels check boxs and radio buttons have an empty
  235.      * border around them.  Look and feel guidelines generally don't include
  236.      * this space.  Use this method to subtract this space from the specified
  237.      * components.
  238.      *
  239.      * @param source Component
  240.      * @param position Position doing layout along.
  241.      * @param offset Ideal offset, not including border/margin
  242.      * @return offset - border/margin around the component.
  243.      */
  244.     int getCBRBPadding(Component source, int position, int offset) {
  245.         offset -= getCBRBPadding(source, position);
  246.         return Math.max(offset, 0);
  247.     }
  248.     int flipDirection(int position) {
  249.         switch(position) {
  250.         case GroupLayout.NORTH:
  251.             return GroupLayout.SOUTH;
  252.         case GroupLayout.SOUTH:
  253.             return GroupLayout.NORTH;
  254.         case GroupLayout.EAST:
  255.             return GroupLayout.WEST;
  256.         case GroupLayout.WEST:
  257.             return GroupLayout.EAST;
  258.         default:
  259.             throw new IllegalArgumentException("Illegal position: " + position);
  260.         }
  261.     }
  262.     private int getCBRBPadding(Component c, int position) {
  263.         /*if (c.getUIClassID() == "CheckBoxUI" ||
  264.               c.getUIClassID() == "RadioButtonUI") {
  265.             Border border = c.getBorder();
  266.             if (border instanceof UIResource) {
  267.                 return getInset(c, position);
  268.             }
  269.         }*/
  270.         return 0;
  271.     }
  272.     private int getInset(Component c, int position) {
  273.         int insetLeft = c.getStyle().getMargin(false, Component.LEFT);
  274.         int insetTop = c.getStyle().getMargin(false, Component.TOP);
  275.         int insetRight = c.getStyle().getMargin(false, Component.RIGHT);
  276.         int insetBottom = c.getStyle().getMargin(false, Component.BOTTOM);
  277.         switch(position) {
  278.         case GroupLayout.NORTH:
  279.             return insetTop;
  280.         case GroupLayout.SOUTH:
  281.             return insetBottom;
  282.         case GroupLayout.EAST:
  283.             return insetRight;
  284.         case GroupLayout.WEST:
  285.             return insetLeft;
  286.         default:
  287.             throw new IllegalArgumentException("Illegal argument position: " + position);
  288.         }
  289.     }
  290.     // Fix component alignment to work with labels etc when doing bidi
  291.     /*private boolean isLeftAligned(Label button, int position) {
  292.         if (position == GroupLayout.WEST) {
  293.             boolean ltr = button.getComponentOrientation().isLeftToRight();
  294.             int hAlign = button.getHorizontalAlignment();
  295.             return ((ltr && (hAlign == SwingConstants.LEFT ||
  296.                              hAlign == SwingConstants.LEADING)) ||
  297.                     (!ltr && (hAlign == SwingConstants.TRAILING)));
  298.         }
  299.         return false;
  300.     }
  301.     private boolean isRightAligned(AbstractButton button, int position) {
  302.         if (position == SwingConstants.EAST) {
  303.             boolean ltr = button.getComponentOrientation().isLeftToRight();
  304.             int hAlign = button.getHorizontalAlignment();
  305.             return ((ltr && (hAlign == SwingConstants.RIGHT ||
  306.                              hAlign == SwingConstants.TRAILING)) ||
  307.                     (!ltr && (hAlign == SwingConstants.LEADING)));
  308.         }
  309.         return false;
  310.     }*/
  311.     /*private Image getIcon(Label button) {
  312.         Icon icon = button.getIcon();
  313.         if (icon != null) {
  314.             return icon;
  315.         }
  316.         String key = null;
  317.         if (button instanceof JCheckBox) {
  318.             key = "CheckBox.icon";
  319.         } else if (button instanceof JRadioButton) {
  320.             key = "RadioButton.icon";
  321.         }
  322.         if (key != null) {
  323.             Object oIcon = UIManager.get(key);
  324.             if (oIcon instanceof Icon) {
  325.                 return (Icon)oIcon;
  326.             }
  327.         }
  328.         return null;
  329.     }*/
  330.     /**
  331.      * Returns the amount to indent the specified component if it's
  332.      * a JCheckBox or JRadioButton.  If the component is not a JCheckBox or
  333.      * JRadioButton, 0 will be returned.
  334.      */
  335.     int getButtonChildIndent(Component c, int position) {
  336.         /*if ((c instanceof JRadioButton) || (c instanceof JCheckBox)) {
  337.             AbstractButton button = (AbstractButton)c;
  338.             Insets insets = c.getInsets();
  339.             Icon icon = getIcon(button);
  340.             int gap = button.getIconTextGap();
  341.             if (isLeftAligned(button, position)) {
  342.                 return insets.left + icon.getIconWidth() + gap;
  343.             } else if (isRightAligned(button, position)) {
  344.                 return insets.right + icon.getIconWidth() + gap;
  345.             }
  346.         }*/
  347.         return 0;
  348.     }
  349. }