1 /*
   2  * Copyright (c) 2006, 2016, Oracle and/or its affiliates. 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25    @test
  26   @key headful
  27    @bug 4370316
  28    @summary GridLayout does not centre its component properly
  29     (summary was GridLayout does not fill its Container)
  30    @author Andrei Dmitriev : area=awt.layout
  31    @run main LayoutExtraGaps
  32 */
  33 
  34 
  35 import java.awt.Frame;
  36 import java.awt.Panel;
  37 import java.awt.GridLayout;
  38 import java.awt.Color;
  39 import java.awt.Label;
  40 import java.awt.Component;
  41 import java.awt.ComponentOrientation;
  42 import java.awt.Rectangle;
  43 
  44 public class LayoutExtraGaps extends Frame {
  45     final static int compCount = 30;
  46 
  47     public LayoutExtraGaps() {
  48         super("GridLayoutTest");
  49         Panel yellowPanel = new Panel(new GridLayout(compCount, 1, 3, 3));
  50         yellowPanel.setBackground(Color.yellow);
  51 
  52         for(int i = 0; i < compCount ; i++) {
  53             Label redLabel = new Label(""+i);
  54             redLabel.setBackground(Color.red);
  55             yellowPanel.add(redLabel);
  56         }
  57 
  58         Panel bluePanel = new Panel(new GridLayout(1, compCount, 3, 3));
  59         bluePanel.setBackground(Color.blue);
  60 
  61         for(int i = 0; i < compCount; i++) {
  62             Label greenLabel = new Label(""+i);
  63             greenLabel.setBackground(Color.green);
  64             bluePanel.add(greenLabel);
  65         }
  66 
  67         //RTL orientation
  68         Panel blackPanel = new Panel(new GridLayout(compCount, 1, 3, 3));
  69         blackPanel.setBackground(Color.black);
  70         blackPanel.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
  71 
  72         for(int i = 0; i < compCount ; i++) {
  73             Label redLabel = new Label(""+i);
  74             redLabel.setBackground(Color.red);
  75             blackPanel.add(redLabel);
  76         }
  77 
  78         Panel redPanel = new Panel(new GridLayout(1, compCount, 3, 3));
  79         redPanel.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
  80         redPanel.setBackground(Color.red);
  81 
  82         for(int i = 0; i < compCount; i++) {
  83             Label greenLabel = new Label(""+i);
  84             greenLabel.setBackground(Color.green);
  85             redPanel.add(greenLabel);
  86         }
  87 
  88         setLayout(new GridLayout(2, 2, 20, 20));
  89 
  90         add(yellowPanel);
  91         add(bluePanel);
  92         add(redPanel);
  93         add(blackPanel);
  94         pack();
  95         setSize((int)getPreferredSize().getWidth() + 50, (int)getPreferredSize().getHeight() + 50);
  96         setVisible(true);
  97 
  98         blockTillDisplayed();
  99 
 100         if (isComponentCentredLTR(yellowPanel) && isComponentCentredLTR(bluePanel)
 101                 && isComponentCentredLTR(blackPanel) && isComponentCentredRTL(redPanel))
 102         {
 103             System.out.println("Test passed.");
 104         } else {
 105             throw new RuntimeException("Test failed. GridLayout doesn't center component.");
 106         }
 107         
 108         setVisible(false);
 109         dispose();
 110     }
 111 
 112      void blockTillDisplayed() {
 113         while (isVisible() == false) {
 114             try {
 115                 Thread.sleep(100);
 116             } catch (InterruptedException e) {
 117                 e.printStackTrace();
 118                 setVisible(false);
 119                 dispose();
 120                 throw new RuntimeException("Test failed.");
 121             }
 122         }
 123      }
 124     /**
 125      * Checks if the components under Panel p are properly centred (i.e.
 126      * opposite borders between the Panel and component are equal). Panel p
 127      * must not be affect by RTL orientation (RTL only affects horizontal
 128      * positioning and components lay out from top right corner).
 129      *
 130      * @param      p the panel where the components exist and is not affected
 131      *             by right to left orientation
 132      * @return     true if components of panel p are properly centre, false
 133      *             otherwise
 134      */
 135     public static boolean isComponentCentredLTR(Panel p) {
 136         double borderLeft;
 137         double borderRight;
 138         double borderTop;
 139         double borderBottom;
 140 
 141         //The first component(rectangle) in panel p.
 142         Rectangle firstRec = p.getComponent(0).getBounds();
 143 
 144         //The last component(rectangle) in panel p.
 145         Rectangle lastRec = p.getComponent(compCount - 1).getBounds();
 146 
 147         System.out.println("bounds of the first rectangle in "+ p.getName() + " = " + firstRec);
 148         System.out.println("bounds of the last rectangle in "+ p.getName() + " = " + lastRec);
 149 
 150         borderLeft = firstRec.getX();
 151         borderRight = p.getWidth() - lastRec.getWidth() - lastRec.getX();
 152         borderTop = firstRec.getY();
 153         borderBottom = p.getHeight() - lastRec.getHeight() - lastRec.getY();
 154 
 155         return areBordersEqual(borderLeft, borderRight) &&
 156                 areBordersEqual(borderTop, borderBottom);
 157     }
 158 
 159     /**
 160      * Checks if the components under Panel p are properly centred (i.e.
 161      * opposite borders between the Panel and component are equal). Panel p
 162      * must be affect by RTL orientation (RTL only affects horizontal positioning
 163      * and components lay out from top right corner).
 164      *
 165      * @param      p the panel where the components exist and is affected by
 166      *             right to left orientation
 167      * @return     true if components of panel p are properly centre, false
 168      *             otherwise
 169      */
 170     public static boolean isComponentCentredRTL(Panel p) {
 171         double borderLeft;
 172         double borderRight;
 173         double borderTop;
 174         double borderBottom;
 175 
 176         //The first component(rectangle) in panel p.
 177         Rectangle firstRec = p.getComponent(0).getBounds();
 178 
 179         //The last component(rectangle) in panel p.
 180         Rectangle lastRec = p.getComponent(compCount - 1).getBounds();
 181 
 182         System.out.println("bounds of the first rectangle in "+ p.getName() + " = " + firstRec);
 183         System.out.println("bounds of the last rectangle in "+ p.getName() + " = " + lastRec);
 184 
 185         borderLeft = lastRec.getX();
 186         borderRight = p.getWidth() - firstRec.getWidth() - firstRec.getX();
 187         borderTop = lastRec.getY();
 188         borderBottom = p.getHeight() - firstRec.getHeight() - firstRec.getY();
 189 
 190         return areBordersEqual(borderLeft, borderRight) &&
 191                 areBordersEqual(borderTop, borderBottom);
 192     }
 193 
 194     /**
 195      * Given two borders border1 and border2 check if they are equal.
 196      *
 197      * @param      border1 one of the borders being compared
 198      * @param      border2 the other border being compared
 199      * @return     true if border1 and border2 are equal to each other (i.e.
 200      *             their width/height difference is at most 1, assuming the
 201      *             smallest pixel is of size 1), false otherwise
 202      */
 203     public static boolean areBordersEqual(double border1, double border2) {
 204         return Math.abs(border1 - border2) <= 1;
 205     }
 206 
 207     public static void main(String[] args) {
 208         new LayoutExtraGaps();
 209     }
 210 }