001    /*
002     * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003     *
004     * This file is part of
005     * CleanSheets - a spreadsheet application for the Java platform.
006     *
007     * CleanSheets is free software; you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published by
009     * the Free Software Foundation; either version 2 of the License, or
010     * (at your option) any later version.
011     *
012     * CleanSheets is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with CleanSheets; if not, write to the Free Software
019     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020     */
021    package csheets.core;
022    
023    import java.io.Serializable;
024    
025    /**
026     * An address in a spreadsheet that denotes to the location of a cell.
027     * @author Einar Pehrson
028     */
029    public class Address implements Comparable<Address>, Serializable {
030    
031            /** The unique version identifier used for serialization */
032            private static final long serialVersionUID = -1096697824364544991L;
033    
034            /** The lowest character to be used in a column name */
035            public static final char LOWEST_CHAR = 'A';
036    
037            /** The highest character to be used in a column name */
038            public static final char HIGHEST_CHAR = 'Z';
039    
040            /** The column of the spreadsheet that the address refers to */
041            private int column;
042    
043            /** The row of the spreadsheet that the address refers to */
044            private int row;
045    
046            /** A string representation of the address */
047            private transient String string;
048    
049            /**
050             * Creates a new address from the given column and row indices.
051             * @param column the column of the address
052             * @param row the row of the address
053             */
054            public Address(int column, int row) {
055                    this.column = column;
056                    this.row = row;
057            }
058    
059            /**
060             * Returns the column of the address.
061             * @return the column of the address
062             */
063            public int getColumn() {
064                    return column;
065            }
066    
067            /**
068             * Returns the row of the address.
069             * @return the row of the address
070             */
071            public int getRow() {
072                    return row;
073            }
074    
075            /**
076             * Returns whether the other object is an address with
077             * the same column and row coordinates as this address.
078             * @param other the object to check for equality
079             * @return true if the objects are equal
080             */
081            public boolean equals(Object other) {
082                    if (!(other instanceof Address) || other == null)
083                            return false;
084                    Address otherAddress = (Address)other;
085                    return row == otherAddress.getRow()
086                            && column == otherAddress.getColumn();
087            }
088    
089            /**
090             * Returns the hash code of the address.
091             * @return an int with the column in the 16 high bits, row in the low 16.
092             */
093            public int hashCode() {
094                    return (column << 16) + row;
095            }
096    
097            /**
098             * Compares this address with the given address for order.
099             * Ordering is first done on the addresses' columns, then on their rows.
100             * @param address the address to compared to
101             * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
102             */
103            public int compareTo(Address address) {
104                    int columnDiff = column - address.getColumn();
105                    if (columnDiff != 0)
106                            return columnDiff;
107                    else 
108                            return row - address.getRow();
109            }
110    
111            /**
112             * Returns a string representation of the address on the form "B22",
113             * composed of the letter of the column and number of the row that
114             * intersect to form the address.        
115             * @return a string representation of the address
116             */
117            public String toString() {
118                    if (string == null) {
119                            String columnStr;
120                            int tempColumn = column;
121                            for (columnStr = ""; tempColumn >= 0; tempColumn = tempColumn
122                                            / (HIGHEST_CHAR - LOWEST_CHAR + 1) - 1)
123                                    columnStr = (char)((char)(tempColumn % (HIGHEST_CHAR
124                                            - LOWEST_CHAR + 1)) + LOWEST_CHAR) + columnStr;
125                            string = columnStr + (row + 1);
126                    }
127                    return new String(string);
128            }
129    }