001    /* TabSet.java --
002       Copyright (C) 2004, 2006, Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.swing.text;
039    
040    import gnu.java.lang.CPStringBuilder;
041    
042    import java.io.Serializable;
043    
044    /**
045     * A set of tab stops.  Instances of this class are immutable.
046     */
047    public class TabSet implements Serializable
048    {
049      /** The serialization UID (compatible with JDK1.5). */
050      private static final long serialVersionUID = 2367703481999080593L;
051    
052      /** Storage for the tab stops. */
053      TabStop[] tabs;
054    
055      /**
056       * Creates a new <code>TabSet</code> containing the specified tab stops.
057       *
058       * @param t  the tab stops (<code>null</code> permitted).
059       */
060      public TabSet(TabStop[] t)
061      {
062        if (t != null)
063          tabs = (TabStop[]) t.clone();
064        else
065          tabs = new TabStop[0];
066      }
067    
068      /**
069       * Returns the tab stop with the specified index.
070       *
071       * @param i  the index.
072       *
073       * @return The tab stop.
074       *
075       * @throws IllegalArgumentException if <code>i</code> is not in the range
076       *     <code>0</code> to <code>getTabCount() - 1</code>.
077       */
078      public TabStop getTab(int i)
079      {
080        if (i < 0 || i >= tabs.length)
081          throw new IllegalArgumentException("Index out of bounds.");
082        return tabs[i];
083      }
084    
085      /**
086       * Returns the tab following the specified location.
087       *
088       * @param location  the location.
089       *
090       * @return The tab following the specified location (or <code>null</code>).
091       */
092      public TabStop getTabAfter(float location)
093      {
094        int idx = getTabIndexAfter(location);
095        if (idx == -1)
096          return null;
097        else
098          return tabs[idx];
099      }
100    
101      /**
102       * Returns the number of tab stops in this tab set.
103       *
104       * @return The number of tab stops in this tab set.
105       */
106      public int getTabCount()
107      {
108        return tabs.length;
109      }
110    
111      /**
112       * Returns the index of the specified tab, or -1 if the tab is not found.
113       *
114       * @param tab  the tab (<code>null</code> permitted).
115       *
116       * @return The index of the specified tab, or -1.
117       */
118      public int getTabIndex(TabStop tab)
119      {
120        for (int i = 0; i < tabs.length; ++i)
121          if (tabs[i] == tab)
122            return i;
123        return -1;
124      }
125    
126      /**
127       * Returns the index of the tab at or after the specified location.
128       *
129       * @param location  the tab location.
130       *
131       * @return The index of the tab stop, or -1.
132       */
133      public int getTabIndexAfter(float location)
134      {
135        for (int i = 0; i < tabs.length; i++)
136          {
137            if (location <= tabs[i].getPosition())
138              return i;
139          }
140        return -1;
141      }
142    
143      /**
144       * Tests this <code>TabSet</code> for equality with an arbitrary object.
145       *
146       * @param obj  the object (<code>null</code> permitted).
147       *
148       * @return <code>true</code> if this <code>TabSet</code> is equal to
149       *     <code>obj</code>, and <code>false</code> otherwise.
150       *
151       * @since 1.5
152       */
153      public boolean equals(Object obj)
154      {
155        if (obj == this)
156          return true;
157        if (!(obj instanceof TabSet))
158          return false;
159        TabSet that = (TabSet) obj;
160        int tabCount = getTabCount();
161        if (tabCount != that.getTabCount())
162          return false;
163        for (int i = 0; i < tabCount; i++)
164          {
165            if (!this.getTab(i).equals(that.getTab(i)))
166              return false;
167          }
168        return true;
169      }
170    
171      /**
172       * Returns a hash code for this <code>TabSet</code>.
173       *
174       * @return A hash code.
175       *
176       * @since 1.5
177       */
178      public int hashCode()
179      {
180        // this hash code won't match Sun's, but that shouldn't matter...
181        int result = 193;
182        int tabs = getTabCount();
183        for (int i = 0; i < tabs; i++)
184          {
185            TabStop t = getTab(i);
186            if (t != null)
187              result = 37 * result + t.hashCode();
188          }
189        return result;
190      }
191    
192      /**
193       * Returns a string representation of this <code>TabSet</code>.
194       *
195       * @return A string representation of this <code>TabSet</code>.
196       */
197      public String toString()
198      {
199        CPStringBuilder sb = new CPStringBuilder();
200        sb.append("[ ");
201        for (int i = 0; i < tabs.length; ++i)
202          {
203            if (i != 0)
204              sb.append(" - ");
205            sb.append(tabs[i].toString());
206          }
207        sb.append(" ]");
208        return sb.toString();
209      }
210    }