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
37package java.awt;
38
39import java.util.Locale;
40import 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()} and
76  * {@code isHorizontal()} 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  */
91public 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     *
130     * @return {@code true} if this orientation has horizontal lines
131     */
132    public boolean isHorizontal() {
133        return (orientation & HORIZ_BIT) != 0;
134    }
135
136    /**
137     * HorizontalLines: Do items run left-to-right?<br>
138     * Vertical Lines:  Do lines run left-to-right?<br>
139     * This will return true for horizontal, left-to-right writing
140     * systems such as Roman.
141     *
142     * @return {@code true} if this orientation is left-to-right
143     */
144    public boolean isLeftToRight() {
145        return (orientation & LTR_BIT) != 0;
146    }
147
148    /**
149     * Returns the orientation that is appropriate for the given locale.
150     *
151     * @param locale the specified locale
152     * @return the orientation for the locale
153     */
154    public static ComponentOrientation getOrientation(Locale locale) {
155        // A more flexible implementation would consult a ResourceBundle
156        // to find the appropriate orientation.  Until pluggable locales
157        // are introduced however, the flexibility isn't really needed.
158        // So we choose efficiency instead.
159        String lang = locale.getLanguage();
160        if( "iw".equals(lang) || "ar".equals(lang)
161            || "fa".equals(lang) || "ur".equals(lang) )
162        {
163            return RIGHT_TO_LEFT;
164        } else {
165            return LEFT_TO_RIGHT;
166        }
167    }
168
169    /**
170     * Returns the orientation appropriate for the given ResourceBundle's
171     * localization.  Three approaches are tried, in the following order:
172     * <ol>
173     * <li>Retrieve a ComponentOrientation object from the ResourceBundle
174     *      using the string "Orientation" as the key.
175     * <li>Use the ResourceBundle.getLocale to determine the bundle's
176     *      locale, then return the orientation for that locale.
177     * <li>Return the default locale's orientation.
178     * </ol>
179     *
180     * @param  bdl the bundle to use
181     * @return the orientation
182     * @deprecated As of J2SE 1.4, use {@link #getOrientation(java.util.Locale)}.
183     */
184    @Deprecated
185    public static ComponentOrientation getOrientation(ResourceBundle bdl)
186    {
187        ComponentOrientation result = null;
188
189        try {
190            result = (ComponentOrientation)bdl.getObject("Orientation");
191        }
192        catch (Exception e) {
193        }
194
195        if (result == null) {
196            result = getOrientation(bdl.getLocale());
197        }
198        if (result == null) {
199            result = getOrientation(Locale.getDefault());
200        }
201        return result;
202    }
203
204    private int orientation;
205
206    private ComponentOrientation(int value)
207    {
208        orientation = value;
209    }
210 }
211