Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   /**
   18    * @author Alexander T. Simbirtsev
   19    */
   20   package javax.swing;
   21   
   22   import java.awt.Component;
   23   import java.awt.Container;
   24   import java.awt.Dimension;
   25   import java.awt.Insets;
   26   import java.awt.Rectangle;
   27   
   28   import org.apache.harmony.x.swing.Utilities;
   29   
   30   
   31   /**
   32    * This class helps BoxLayout and OverlayLayout to layout their components
   33    * and calculate all target's necessary parameters. It encapsulates all necessary
   34    * for calculations data.
   35    *
   36    */
   37   final class LayoutParameters {
   38   
   39       public float alignmentX = 0.0f;
   40       public float alignmentY = 0.0f;
   41       public final Dimension minimumSize = new Dimension();
   42       public final Dimension preferredSize = new Dimension();
   43       public final Dimension maximumSize = new Dimension();
   44   
   45       public final static int MIXED_ALIGNMENT = 0;
   46       public final static int HORIZONTAL_ALIGNMENT = 1;
   47       public final static int VERTICAL_ALIGNMENT = 2;
   48   
   49       private SizeRequirements[] horRequirements = null;
   50       private SizeRequirements[] vertRequirements = null;
   51       private final SizeRequirements totalRequirements = new SizeRequirements();
   52       private int[] offsetsX = null;
   53       private int[] spansX = null;
   54       private int[] offsetsY = null;
   55       private int[] spansY = null;
   56   
   57       private boolean isValid = false;
   58       private final Container target;
   59       private int alignment;
   60   
   61       /**
   62        *
   63        * @param target - container being laid out with this parameters
   64        * @param alignment - alignment of the target. It can be one of the following values:
   65        *      <code>MIXED_ALIGNMENT</code> - value for OverlayLayout
   66        *      <code>HORIZONTAL_ALIGNMENT</code> - value for BoxLayout with horizontal alignment
   67        *      <code>VERTICAL_ALIGNMENT</code> - value for BoxLayout with vertical alignment
   68        */
   69       public LayoutParameters(final Container target, final int alignment) {
   70           this.target = target;
   71           this.alignment = alignment;
   72       }
   73       /**
   74        *  This method layouts target:
   75        *  calculates sizes an positions for all subcomponents
   76        *
   77        */
   78       public void layoutTarget() {
   79           calculateLayoutParameters();
   80   
   81           int numChildren = target.getComponentCount();
   82           if (offsetsX == null || offsetsX.length != numChildren) {
   83               offsetsX = new int[numChildren];
   84               spansX = new int[numChildren];
   85               offsetsY = new int[numChildren];
   86               spansY = new int[numChildren];
   87           }
   88           final Insets insets = target.getInsets();
   89           Rectangle innerSize = Utilities.subtractInsets(target.getBounds(), insets);
   90           totalRequirements.alignment = alignmentX;
   91           if (alignment == HORIZONTAL_ALIGNMENT) {
   92               SizeRequirements.calculateTiledPositions(innerSize.width,
   93                                                        totalRequirements, horRequirements,
   94                                                        offsetsX, spansX);
   95           } else {
   96               SizeRequirements.calculateAlignedPositions(innerSize.width,
   97                                                          totalRequirements, horRequirements,
   98                                                          offsetsX, spansX);
   99           }
  100           totalRequirements.alignment = alignmentY;
  101           if (alignment == VERTICAL_ALIGNMENT) {
  102               SizeRequirements.calculateTiledPositions(innerSize.height,
  103                                                        totalRequirements, vertRequirements,
  104                                                        offsetsY, spansY);
  105           } else {
  106               SizeRequirements.calculateAlignedPositions(innerSize.height,
  107                                                          totalRequirements, vertRequirements,
  108                                                          offsetsY, spansY);
  109           }
  110   
  111           final boolean isLTR = target.getComponentOrientation().isLeftToRight();
  112           final int offsetX = isLTR ? insets.left : target.getWidth() - insets.right;
  113           final int offsetY = insets.top;
  114           for (int iChild = 0; iChild < numChildren; iChild++) {
  115               final Component component = target.getComponent(iChild);
  116               final int spanX = spansX[iChild] > 0 ? spansX[iChild] : 0;
  117               final int spanY = spansY[iChild] > 0 ? spansY[iChild] : 0;
  118               final int x = isLTR ? offsetsX[iChild] : -offsetsX[iChild] - spanX;
  119               component.setBounds(offsetX + x, offsetY + offsetsY[iChild], spanX, spanY);
  120           }
  121       }
  122   
  123       /**
  124        *  fills arrays with target's subcomponents data
  125        *  required in futher calculations
  126        */
  127       private synchronized void fillRequirementArrays() {
  128           int numChildren = target.getComponentCount();
  129           if (horRequirements == null || horRequirements.length != numChildren) {
  130               horRequirements = new SizeRequirements[numChildren];
  131               vertRequirements = new SizeRequirements[numChildren];
  132               for (int iChild = 0; iChild < numChildren; iChild++) {
  133                   horRequirements[iChild] = new SizeRequirements();
  134                   vertRequirements[iChild] = new SizeRequirements();
  135               }
  136           }
  137   
  138           for (int iChild = 0; iChild < numChildren; iChild++) {
  139               Component component = target.getComponent(iChild);
  140               if (component.isVisible()) {
  141                   Dimension minSize = component.getMinimumSize();
  142                   Dimension prefSize = component.getPreferredSize();
  143                   Dimension maxSize = component.getMaximumSize();
  144                   horRequirements[iChild].set(minSize.width, prefSize.width,
  145                           maxSize.width, component.getAlignmentX());
  146                   vertRequirements[iChild].set(minSize.height, prefSize.height,
  147                           maxSize.height, component.getAlignmentY());
  148               } else {
  149                   horRequirements[iChild].reset();
  150                   vertRequirements[iChild].reset();
  151               }
  152           }
  153       }
  154   
  155       /**
  156        *  Calculates layout parameters:
  157        *  maximum, preferred and minimum sizes for container
  158        */
  159       public synchronized void calculateLayoutParameters() {
  160           if (isValid) {
  161               return;
  162           }
  163           fillRequirementArrays();
  164   
  165           Insets insets = target.getInsets();
  166           int horzInsets = insets.left + insets.right;
  167           int vertInsets = insets.top + insets.bottom;
  168   
  169           SizeRequirements resultedRequirements = null;
  170           if (alignment == HORIZONTAL_ALIGNMENT) {
  171               resultedRequirements = SizeRequirements.getTiledSizeRequirements(horRequirements);
  172           } else {
  173               resultedRequirements = SizeRequirements.getAlignedSizeRequirements(horRequirements);
  174           }
  175           alignmentX = resultedRequirements.alignment;
  176           minimumSize.width = Utilities.safeIntSum(resultedRequirements.minimum, horzInsets);
  177           preferredSize.width = Utilities.safeIntSum(resultedRequirements.preferred, horzInsets);
  178           maximumSize.width = Utilities.safeIntSum(resultedRequirements.maximum, horzInsets);
  179   
  180           if (alignment == VERTICAL_ALIGNMENT) {
  181               resultedRequirements = SizeRequirements.getTiledSizeRequirements(vertRequirements);
  182           } else {
  183               resultedRequirements = SizeRequirements.getAlignedSizeRequirements(vertRequirements);
  184           }
  185           alignmentY = resultedRequirements.alignment;
  186           minimumSize.height = Utilities.safeIntSum(resultedRequirements.minimum, vertInsets);
  187           preferredSize.height = Utilities.safeIntSum(resultedRequirements.preferred, vertInsets);
  188           maximumSize.height = Utilities.safeIntSum(resultedRequirements.maximum, vertInsets);
  189   
  190           isValid = true;
  191       }
  192   
  193       /**
  194        *  This method is to be invoked to notify LayoutParameters object, that target was changed somehow
  195        *  and all cached data became unreliable
  196        */
  197       public void invalidate() {
  198           isValid = false;
  199       }
  200   
  201       public int getAlignment() {
  202           return alignment;
  203       }
  204   
  205       public void setAlignment(final int alignment) {
  206           if (this.alignment == alignment) {
  207               return;
  208           }
  209           this.alignment = alignment;
  210           invalidate();
  211       }
  212   }
  213   

Home » openjdk-7 » javax » swing » [javadoc | source]