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 java.io.Serializable;
041    
042    /**
043     * A set of tab stops.  Instances of this class are immutable.
044     */
045    public class TabSet implements Serializable
046    {
047      /** The serialization UID (compatible with JDK1.5). */
048      private static final long serialVersionUID = 2367703481999080593L;
049    
050      /** Storage for the tab stops. */
051      TabStop[] tabs;
052    
053      /**
054       * Creates a new <code>TabSet</code> containing the specified tab stops.
055       * 
056       * @param t  the tab stops (<code>null</code> permitted).
057       */
058      public TabSet(TabStop[] t) 
059      {
060        if (t != null)
061          tabs = (TabStop[]) t.clone();
062        else 
063          tabs = new TabStop[0];
064      }
065     
066      /**
067       * Returns the tab stop with the specified index.
068       * 
069       * @param i  the index.
070       * 
071       * @return The tab stop.
072       * 
073       * @throws IllegalArgumentException if <code>i</code> is not in the range 
074       *     <code>0</code> to <code>getTabCount() - 1</code>.
075       */
076      public TabStop getTab(int i) 
077      {
078        if (i < 0 || i >= tabs.length)
079          throw new IllegalArgumentException("Index out of bounds.");
080        return tabs[i];
081      }
082    
083      /**
084       * Returns the tab following the specified location.
085       * 
086       * @param location  the location.
087       * 
088       * @return The tab following the specified location (or <code>null</code>).
089       */
090      public TabStop getTabAfter(float location) 
091      {
092        int idx = getTabIndexAfter(location);
093        if (idx == -1)
094          return null;
095        else
096          return tabs[idx];        
097      }
098    
099      /**
100       * Returns the number of tab stops in this tab set.
101       * 
102       * @return The number of tab stops in this tab set.
103       */
104      public int getTabCount() 
105      {
106        return tabs.length;
107      }
108    
109      /**
110       * Returns the index of the specified tab, or -1 if the tab is not found.
111       * 
112       * @param tab  the tab (<code>null</code> permitted).
113       * 
114       * @return The index of the specified tab, or -1.
115       */
116      public int getTabIndex(TabStop tab) 
117      {
118        for (int i = 0; i < tabs.length; ++i)
119          if (tabs[i] == tab)
120            return i;
121        return -1;
122      }
123    
124      /**
125       * Returns the index of the tab at or after the specified location.
126       * 
127       * @param location  the tab location.
128       * 
129       * @return The index of the tab stop, or -1.
130       */
131      public int getTabIndexAfter(float location) 
132      {
133        for (int i = 0; i < tabs.length; i++)
134          {
135            if (location <= tabs[i].getPosition())
136              return i;
137          }
138        return -1;
139      }
140      
141      /**
142       * Tests this <code>TabSet</code> for equality with an arbitrary object.
143       * 
144       * @param obj  the object (<code>null</code> permitted).
145       * 
146       * @return <code>true</code> if this <code>TabSet</code> is equal to
147       *     <code>obj</code>, and <code>false</code> otherwise.
148       *     
149       * @since 1.5
150       */
151      public boolean equals(Object obj)
152      {
153        if (obj == this)
154          return true;
155        if (!(obj instanceof TabSet))
156          return false;
157        TabSet that = (TabSet) obj;
158        int tabCount = getTabCount();
159        if (tabCount != that.getTabCount())
160          return false;
161        for (int i = 0; i < tabCount; i++)
162          {
163            if (!this.getTab(i).equals(that.getTab(i)))
164              return false;
165          }
166        return true;
167      }
168      
169      /**
170       * Returns a hash code for this <code>TabSet</code>.
171       * 
172       * @return A hash code.
173       * 
174       * @since 1.5
175       */
176      public int hashCode() 
177      {
178        // this hash code won't match Sun's, but that shouldn't matter...
179        int result = 193;
180        int tabs = getTabCount();
181        for (int i = 0; i < tabs; i++)
182          {
183            TabStop t = getTab(i);
184            if (t != null)
185              result = 37 * result + t.hashCode();
186          }
187        return result;
188      }
189    
190      /**
191       * Returns a string representation of this <code>TabSet</code>.
192       * 
193       * @return A string representation of this <code>TabSet</code>.
194       */
195      public String toString()
196      {
197        StringBuffer sb = new StringBuffer();
198        sb.append("[ ");
199        for (int i = 0; i < tabs.length; ++i)
200          {
201            if (i != 0)
202              sb.append(" - ");
203            sb.append(tabs[i].toString());
204          }
205        sb.append(" ]");
206        return sb.toString();
207      }
208    }