1 /*
   2  * Copyright (c) 1998, 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * (C) Copyright IBM Corp. 1998 - All Rights Reserved
  28  *
  29  * The original version of this source code and documentation is copyrighted
  30  * and owned by IBM, Inc. These materials are provided under terms of a
  31  * License Agreement between IBM and Sun. This technology is protected by
  32  * multiple US and International patents. This notice and attribution to IBM
  33  * may not be removed.
  34  *
  35  */
  36 
  37 package java.awt;
  38 
  39 import java.util.Locale;
  40 import java.util.ResourceBundle;
  41 
  42 /**
  43   * The ComponentOrientation class encapsulates the language-sensitive
  44   * orientation that is to be used to order the elements of a component
  45   * or of text. It is used to reflect the differences in this ordering
  46   * between Western alphabets, Middle Eastern (such as Hebrew), and Far
  47   * Eastern (such as Japanese).
  48   * <p>
  49   * Fundamentally, this governs items (such as characters) which are laid out
  50   * in lines, with the lines then laid out in a block. This also applies
  51   * to items in a widget: for example, in a check box where the box is
  52   * positioned relative to the text.
  53   * <p>
  54   * There are four different orientations used in modern languages
  55   * as in the following table.<br>
  56   * <pre>
  57   * LT          RT          TL          TR
  58   * A B C       C B A       A D G       G D A
  59   * D E F       F E D       B E H       H E B
  60   * G H I       I H G       C F I       I F C
  61   * </pre><br>
  62   * (In the header, the two-letter abbreviation represents the item direction
  63   * in the first letter, and the line direction in the second. For example,
  64   * LT means "items left-to-right, lines top-to-bottom",
  65   * TL means "items top-to-bottom, lines left-to-right", and so on.)
  66   * <p>
  67   * The orientations are:
  68   * <ul>
  69   * <li>LT - Western Europe (optional for Japanese, Chinese, Korean)
  70   * <li>RT - Middle East (Arabic, Hebrew)
  71   * <li>TR - Japanese, Chinese, Korean
  72   * <li>TL - Mongolian
  73   * </ul>
  74   * Components whose view and controller code depends on orientation
  75   * should use the <code>isLeftToRight()</code> and
  76   * <code>isHorizontal()</code> methods to
  77   * determine their behavior. They should not include switch-like
  78   * code that keys off of the constants, such as:
  79   * <pre>
  80   * if (orientation == LEFT_TO_RIGHT) {
  81   *   ...
  82   * } else if (orientation == RIGHT_TO_LEFT) {
  83   *   ...
  84   * } else {
  85   *   // Oops
  86   * }
  87   * </pre>
  88   * This is unsafe, since more constants may be added in the future and
  89   * since it is not guaranteed that orientation objects will be unique.
  90   */
  91 public final class ComponentOrientation implements java.io.Serializable
  92 {
  93     /*
  94      * serialVersionUID
  95      */
  96     private static final long serialVersionUID = -4113291392143563828L;
  97 
  98     // Internal constants used in the implementation
  99     private static final int UNK_BIT      = 1;
 100     private static final int HORIZ_BIT    = 2;
 101     private static final int LTR_BIT      = 4;
 102 
 103     /**
 104      * Items run left to right and lines flow top to bottom
 105      * Examples: English, French.
 106      */
 107     public static final ComponentOrientation LEFT_TO_RIGHT =
 108                     new ComponentOrientation(HORIZ_BIT|LTR_BIT);
 109 
 110     /**
 111      * Items run right to left and lines flow top to bottom
 112      * Examples: Arabic, Hebrew.
 113      */
 114     public static final ComponentOrientation RIGHT_TO_LEFT =
 115                     new ComponentOrientation(HORIZ_BIT);
 116 
 117     /**
 118      * Indicates that a component's orientation has not been set.
 119      * To preserve the behavior of existing applications,
 120      * isLeftToRight will return true for this value.
 121      */
 122     public static final ComponentOrientation UNKNOWN =
 123                     new ComponentOrientation(HORIZ_BIT|LTR_BIT|UNK_BIT);
 124 
 125     /**
 126      * Are lines horizontal?
 127      * This will return true for horizontal, left-to-right writing
 128      * systems such as Roman.
 129      * @return  {@code true} if this orientation has horizontal lines
 130      */
 131     public boolean isHorizontal() {
 132         return (orientation & HORIZ_BIT) != 0;
 133     }
 134 
 135     /**
 136      * HorizontalLines: Do items run left-to-right?<br>
 137      * Vertical Lines:  Do lines run left-to-right?<br>
 138      * This will return true for horizontal, left-to-right writing
 139      *         systems such as Roman.
 140      * @return {@code true} if this orientation is left-to-right
 141      */
 142     public boolean isLeftToRight() {
 143         return (orientation & LTR_BIT) != 0;
 144     }
 145 
 146     /**
 147      * Returns the orientation that is appropriate for the given locale.
 148      * @param locale the specified locale
 149      * @return  the orientation for the locale
 150      */
 151     public static ComponentOrientation getOrientation(Locale locale) {
 152         // A more flexible implementation would consult a ResourceBundle
 153         // to find the appropriate orientation.  Until pluggable locales
 154         // are introduced however, the flexiblity isn't really needed.
 155         // So we choose efficiency instead.
 156         String lang = locale.getLanguage();
 157         if( "iw".equals(lang) || "ar".equals(lang)
 158             || "fa".equals(lang) || "ur".equals(lang) )
 159         {
 160             return RIGHT_TO_LEFT;
 161         } else {
 162             return LEFT_TO_RIGHT;
 163         }
 164     }
 165 
 166     /**
 167      * Returns the orientation appropriate for the given ResourceBundle's
 168      * localization.  Three approaches are tried, in the following order:
 169      * <ol>
 170      * <li>Retrieve a ComponentOrientation object from the ResourceBundle
 171      *      using the string "Orientation" as the key.
 172      * <li>Use the ResourceBundle.getLocale to determine the bundle's
 173      *      locale, then return the orientation for that locale.
 174      * <li>Return the default locale's orientation.
 175      * </ol>
 176      *
 177      * @param bdl  the bundle to use
 178      * @return  the orientation
 179      * @deprecated As of J2SE 1.4, use {@link #getOrientation(java.util.Locale)}.
 180      */
 181     @Deprecated
 182     public static ComponentOrientation getOrientation(ResourceBundle bdl)
 183     {
 184         ComponentOrientation result = null;
 185 
 186         try {
 187             result = (ComponentOrientation)bdl.getObject("Orientation");
 188         }
 189         catch (Exception e) {
 190         }
 191 
 192         if (result == null) {
 193             result = getOrientation(bdl.getLocale());
 194         }
 195         if (result == null) {
 196             result = getOrientation(Locale.getDefault());
 197         }
 198         return result;
 199     }
 200 
 201     private int orientation;
 202 
 203     private ComponentOrientation(int value)
 204     {
 205         orientation = value;
 206     }
 207  }