1 /*
   2  * Copyright (c) 1997, 2015, 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 package javax.swing.text;
  26 
  27 import java.io.Serializable;
  28 
  29 /**
  30  * This class encapsulates a single tab stop (basically as tab stops
  31  * are thought of by RTF). A tab stop is at a specified distance from the
  32  * left margin, aligns text in a specified way, and has a specified leader.
  33  * TabStops are immutable, and usually contained in TabSets.
  34  * <p>
  35  * <strong>Warning:</strong>
  36  * Serialized objects of this class will not be compatible with
  37  * future Swing releases. The current serialization support is
  38  * appropriate for short term storage or RMI between applications running
  39  * the same version of Swing.  As of 1.4, support for long term storage
  40  * of all JavaBeans&trade;
  41  * has been added to the <code>java.beans</code> package.
  42  * Please see {@link java.beans.XMLEncoder}.
  43  *
  44  */
  45 @SuppressWarnings("serial") // Same-version serialization only
  46 public class TabStop implements Serializable {
  47 
  48     /** Character following tab is positioned at location. */
  49     public static final int ALIGN_LEFT    = 0;
  50     /** Characters following tab are positioned such that all following
  51      * characters up to next tab/newline end at location. */
  52     public static final int ALIGN_RIGHT   = 1;
  53     /** Characters following tab are positioned such that all following
  54      * characters up to next tab/newline are centered around the tabs
  55      * location. */
  56     public static final int ALIGN_CENTER  = 2;
  57     /** Characters following tab are aligned such that next
  58      * decimal/tab/newline is at the tab location, very similar to
  59      * RIGHT_TAB, just includes decimal as additional character to look for.
  60      */
  61     public static final int ALIGN_DECIMAL = 4;
  62     /** Align bar */
  63     public static final int ALIGN_BAR     = 5;
  64 
  65     /* Bar tabs (whatever they are) are actually a separate kind of tab
  66        in the RTF spec. However, being a bar tab and having alignment
  67        properties are mutually exclusive, so the reader treats barness
  68        as being a kind of alignment. */
  69 
  70     /** Lead none */
  71     public static final int LEAD_NONE      = 0;
  72     /** Lead dots */
  73     public static final int LEAD_DOTS      = 1;
  74     /** Lead hyphens */
  75     public static final int LEAD_HYPHENS   = 2;
  76     /** Lead underline */
  77     public static final int LEAD_UNDERLINE = 3;
  78     /** Lead thickline */
  79     public static final int LEAD_THICKLINE = 4;
  80     /** Lead equals */
  81     public static final int LEAD_EQUALS    = 5;
  82 
  83     /** Tab type. */
  84     private int alignment;
  85     /** Location, from the left margin, that tab is at. */
  86     private float position;
  87     private int leader;
  88 
  89     /**
  90      * Creates a tab at position <code>pos</code> with a default alignment
  91      * and default leader.
  92      * @param pos position of the tab
  93      */
  94     public TabStop(float pos) {
  95         this(pos, ALIGN_LEFT, LEAD_NONE);
  96     }
  97 
  98     /**
  99      * Creates a tab with the specified position <code>pos</code>,
 100      * alignment <code>align</code> and leader <code>leader</code>.
 101      * @param pos position of the tab
 102      * @param align alignment of the tab
 103      * @param leader leader of the tab
 104      */
 105     public TabStop(float pos, int align, int leader) {
 106         alignment = align;
 107         this.leader = leader;
 108         position = pos;
 109     }
 110 
 111     /**
 112      * Returns the position, as a float, of the tab.
 113      * @return the position of the tab
 114      */
 115     public float getPosition() {
 116         return position;
 117     }
 118 
 119     /**
 120      * Returns the alignment, as an integer, of the tab.
 121      * @return the alignment of the tab
 122      */
 123     public int getAlignment() {
 124         return alignment;
 125     }
 126 
 127     /**
 128      * Returns the leader of the tab.
 129      * @return the leader of the tab
 130      */
 131     public int getLeader() {
 132         return leader;
 133     }
 134 
 135     /**
 136      * Returns true if the tabs are equal.
 137      * @return true if the tabs are equal, otherwise false
 138      */
 139     public boolean equals(Object other)
 140     {
 141         if (other == this) {
 142             return true;
 143         }
 144         if (other instanceof TabStop) {
 145             TabStop o = (TabStop)other;
 146             return ( (alignment == o.alignment) &&
 147                      (leader == o.leader) &&
 148                      (position == o.position) );  /* TODO: epsilon */
 149         }
 150         return false;
 151     }
 152 
 153     /**
 154      * Returns the hashCode for the object.  This must be defined
 155      * here to ensure 100% pure.
 156      *
 157      * @return the hashCode for the object
 158      */
 159     public int hashCode() {
 160         return alignment ^ leader ^ Math.round(position);
 161     }
 162 
 163     /* This is for debugging; perhaps it should be removed before release */
 164     public String toString() {
 165         String buf;
 166         switch(alignment) {
 167           default:
 168           case ALIGN_LEFT:
 169             buf = "";
 170             break;
 171           case ALIGN_RIGHT:
 172             buf = "right ";
 173             break;
 174           case ALIGN_CENTER:
 175             buf = "center ";
 176             break;
 177           case ALIGN_DECIMAL:
 178             buf = "decimal ";
 179             break;
 180           case ALIGN_BAR:
 181             buf = "bar ";
 182             break;
 183         }
 184         buf = buf + "tab @" + String.valueOf(position);
 185         if (leader != LEAD_NONE)
 186             buf = buf + " (w/leaders)";
 187         return buf;
 188     }
 189 }