Source Code Cross Referenced for CyclicNumberAxis.java in  » Chart » jfreechart » org » jfree » chart » axis » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Chart » jfreechart » org.jfree.chart.axis 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ===========================================================
0002:         * JFreeChart : a free chart library for the Java(tm) platform
0003:         * ===========================================================
0004:         *
0005:         * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
0006:         *
0007:         * Project Info:  http://www.jfree.org/jfreechart/index.html
0008:         *
0009:         * This library is free software; you can redistribute it and/or modify it 
0010:         * under the terms of the GNU Lesser General Public License as published by 
0011:         * the Free Software Foundation; either version 2.1 of the License, or 
0012:         * (at your option) any later version.
0013:         *
0014:         * This library is distributed in the hope that it will be useful, but 
0015:         * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
0016:         * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
0017:         * License for more details.
0018:         *
0019:         * You should have received a copy of the GNU Lesser General Public
0020:         * License along with this library; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
0022:         * USA.  
0023:         *
0024:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
0025:         * in the United States and other countries.]
0026:         *
0027:         * ---------------------
0028:         * CyclicNumberAxis.java
0029:         * ---------------------
0030:         * (C) Copyright 2003, 2004, by Nicolas Brodu and Contributors.
0031:         *
0032:         * Original Author:  Nicolas Brodu;
0033:         * Contributor(s):   David Gilbert (for Object Refinery Limited);
0034:         *
0035:         * $Id: CyclicNumberAxis.java,v 1.10.2.2 2005/10/25 20:37:34 mungady Exp $
0036:         *
0037:         * Changes
0038:         * -------
0039:         * 19-Nov-2003 : Initial import to JFreeChart from the JSynoptic project (NB);
0040:         * 16-Mar-2004 : Added plotState to draw() method (DG);
0041:         * 07-Apr-2004 : Modifed text bounds calculation (DG);
0042:         * 21-Apr-2005 : Replaced Insets with RectangleInsets, removed redundant
0043:         *               argument in selectAutoTickUnit() (DG);
0044:         * 22-Apr-2005 : Renamed refreshHorizontalTicks() --> refreshTicksHorizontal
0045:         *               (for consistency with other classes) and removed unused
0046:         *               parameters (DG);
0047:         * 08-Jun-2005 : Fixed equals() method to handle GradientPaint (DG);
0048:         *
0049:         */
0050:
0051:        package org.jfree.chart.axis;
0052:
0053:        import java.awt.BasicStroke;
0054:        import java.awt.Color;
0055:        import java.awt.Font;
0056:        import java.awt.FontMetrics;
0057:        import java.awt.Graphics2D;
0058:        import java.awt.Paint;
0059:        import java.awt.Stroke;
0060:        import java.awt.geom.Line2D;
0061:        import java.awt.geom.Rectangle2D;
0062:        import java.io.IOException;
0063:        import java.io.ObjectInputStream;
0064:        import java.io.ObjectOutputStream;
0065:        import java.text.NumberFormat;
0066:        import java.util.List;
0067:
0068:        import org.jfree.chart.plot.Plot;
0069:        import org.jfree.chart.plot.PlotRenderingInfo;
0070:        import org.jfree.data.Range;
0071:        import org.jfree.io.SerialUtilities;
0072:        import org.jfree.text.TextUtilities;
0073:        import org.jfree.ui.RectangleEdge;
0074:        import org.jfree.ui.TextAnchor;
0075:        import org.jfree.util.ObjectUtilities;
0076:        import org.jfree.util.PaintUtilities;
0077:
0078:        /**
0079:         This class extends NumberAxis and handles cycling.
0080:        
0081:         Traditional representation of data in the range x0..x1
0082:         <pre>
0083:         |-------------------------|
0084:         x0                       x1
0085:         </pre> 
0086:
0087:         Here, the range bounds are at the axis extremities.
0088:         With cyclic axis, however, the time is split in 
0089:         "cycles", or "time frames", or the same duration : the period.
0090:
0091:         A cycle axis cannot by definition handle a larger interval 
0092:         than the period : <pre>x1 - x0 >= period</pre>. Thus, at most a full 
0093:         period can be represented with such an axis.
0094:
0095:         The cycle bound is the number between x0 and x1 which marks 
0096:         the beginning of new time frame:
0097:         <pre>
0098:         |---------------------|----------------------------|
0099:         x0                   cb                           x1
0100:         <---previous cycle---><-------current cycle-------->
0101:         </pre>
0102:
0103:         It is actually a multiple of the period, plus optionally 
0104:         a start offset: <pre>cb = n * period + offset</pre>
0105:
0106:         Thus, by definition, two consecutive cycle bounds 
0107:         period apart, which is precisely why it is called a 
0108:         period.
0109:
0110:         The visual representation of a cyclic axis is like that:
0111:         <pre>
0112:         |----------------------------|---------------------|
0113:         cb                         x1|x0                  cb
0114:         <-------current cycle--------><---previous cycle--->
0115:         </pre>
0116:
0117:         The cycle bound is at the axis ends, then current 
0118:         cycle is shown, then the last cycle. When using 
0119:         dynamic data, the visual effect is the current cycle 
0120:         erases the last cycle as x grows. Then, the next cycle 
0121:         bound is reached, and the process starts over, erasing 
0122:         the previous cycle.
0123:
0124:         A Cyclic item renderer is provided to do exactly this.
0125:
0126:         */
0127:        public class CyclicNumberAxis extends NumberAxis {
0128:
0129:            /** The default axis line stroke. */
0130:            public static Stroke DEFAULT_ADVANCE_LINE_STROKE = new BasicStroke(
0131:                    1.0f);
0132:
0133:            /** The default axis line paint. */
0134:            public static final Paint DEFAULT_ADVANCE_LINE_PAINT = Color.gray;
0135:
0136:            /** The offset. */
0137:            protected double offset;
0138:
0139:            /** The period.*/
0140:            protected double period;
0141:
0142:            /** ??. */
0143:            protected boolean boundMappedToLastCycle;
0144:
0145:            /** A flag that controls whether or not the advance line is visible. */
0146:            protected boolean advanceLineVisible;
0147:
0148:            /** The advance line stroke. */
0149:            protected transient Stroke advanceLineStroke = DEFAULT_ADVANCE_LINE_STROKE;
0150:
0151:            /** The advance line paint. */
0152:            protected transient Paint advanceLinePaint;
0153:
0154:            private transient boolean internalMarkerWhenTicksOverlap;
0155:            private transient Tick internalMarkerCycleBoundTick;
0156:
0157:            /** 
0158:             * Creates a CycleNumberAxis with the given period.
0159:             * 
0160:             * @param period  the period.
0161:             */
0162:            public CyclicNumberAxis(double period) {
0163:                this (period, 0.0);
0164:            }
0165:
0166:            /** 
0167:             * Creates a CycleNumberAxis with the given period and offset.
0168:             * 
0169:             * @param period  the period.
0170:             * @param offset  the offset.
0171:             */
0172:            public CyclicNumberAxis(double period, double offset) {
0173:                this (period, offset, null);
0174:            }
0175:
0176:            /** 
0177:             * Creates a named CycleNumberAxis with the given period.
0178:             * 
0179:             * @param period  the period.
0180:             * @param label  the label.
0181:             */
0182:            public CyclicNumberAxis(double period, String label) {
0183:                this (0, period, label);
0184:            }
0185:
0186:            /** 
0187:             * Creates a named CycleNumberAxis with the given period and offset.
0188:             * 
0189:             * @param period  the period.
0190:             * @param offset  the offset.
0191:             * @param label  the label.
0192:             */
0193:            public CyclicNumberAxis(double period, double offset, String label) {
0194:                super (label);
0195:                this .period = period;
0196:                this .offset = offset;
0197:                setFixedAutoRange(period);
0198:                this .advanceLineVisible = true;
0199:                this .advanceLinePaint = DEFAULT_ADVANCE_LINE_PAINT;
0200:            }
0201:
0202:            /**
0203:             * The advance line is the line drawn at the limit of the current cycle, 
0204:             * when erasing the previous cycle. 
0205:             * 
0206:             * @return A boolean.
0207:             */
0208:            public boolean isAdvanceLineVisible() {
0209:                return this .advanceLineVisible;
0210:            }
0211:
0212:            /**
0213:             * The advance line is the line drawn at the limit of the current cycle, 
0214:             * when erasing the previous cycle. 
0215:             * 
0216:             * @param visible  the flag.
0217:             */
0218:            public void setAdvanceLineVisible(boolean visible) {
0219:                this .advanceLineVisible = visible;
0220:            }
0221:
0222:            /**
0223:             * The advance line is the line drawn at the limit of the current cycle, 
0224:             * when erasing the previous cycle. 
0225:             * 
0226:             * @return The paint (never <code>null</code>).
0227:             */
0228:            public Paint getAdvanceLinePaint() {
0229:                return this .advanceLinePaint;
0230:            }
0231:
0232:            /**
0233:             * The advance line is the line drawn at the limit of the current cycle, 
0234:             * when erasing the previous cycle. 
0235:             * 
0236:             * @param paint  the paint (<code>null</code> not permitted).
0237:             */
0238:            public void setAdvanceLinePaint(Paint paint) {
0239:                if (paint == null) {
0240:                    throw new IllegalArgumentException("Null 'paint' argument.");
0241:                }
0242:                this .advanceLinePaint = paint;
0243:            }
0244:
0245:            /**
0246:             * The advance line is the line drawn at the limit of the current cycle, 
0247:             * when erasing the previous cycle. 
0248:             * 
0249:             * @return The stroke (never <code>null</code>).
0250:             */
0251:            public Stroke getAdvanceLineStroke() {
0252:                return this .advanceLineStroke;
0253:            }
0254:
0255:            /**
0256:             * The advance line is the line drawn at the limit of the current cycle, 
0257:             * when erasing the previous cycle. 
0258:             * 
0259:             * @param stroke  the stroke (<code>null</code> not permitted).
0260:             */
0261:            public void setAdvanceLineStroke(Stroke stroke) {
0262:                if (stroke == null) {
0263:                    throw new IllegalArgumentException(
0264:                            "Null 'stroke' argument.");
0265:                }
0266:                this .advanceLineStroke = stroke;
0267:            }
0268:
0269:            /**
0270:             * The cycle bound can be associated either with the current or with the 
0271:             * last cycle.  It's up to the user's choice to decide which, as this is 
0272:             * just a convention.  By default, the cycle bound is mapped to the current
0273:             * cycle.
0274:             * <br>
0275:             * Note that this has no effect on visual appearance, as the cycle bound is
0276:             * mapped successively for both axis ends. Use this function for correct 
0277:             * results in translateValueToJava2D. 
0278:             *  
0279:             * @return <code>true</code> if the cycle bound is mapped to the last 
0280:             *         cycle, <code>false</code> if it is bound to the current cycle 
0281:             *         (default)
0282:             */
0283:            public boolean isBoundMappedToLastCycle() {
0284:                return this .boundMappedToLastCycle;
0285:            }
0286:
0287:            /**
0288:             * The cycle bound can be associated either with the current or with the 
0289:             * last cycle.  It's up to the user's choice to decide which, as this is 
0290:             * just a convention. By default, the cycle bound is mapped to the current 
0291:             * cycle. 
0292:             * <br>
0293:             * Note that this has no effect on visual appearance, as the cycle bound is
0294:             * mapped successively for both axis ends. Use this function for correct 
0295:             * results in valueToJava2D.
0296:             *  
0297:             * @param boundMappedToLastCycle Set it to true to map the cycle bound to 
0298:             *        the last cycle.
0299:             */
0300:            public void setBoundMappedToLastCycle(boolean boundMappedToLastCycle) {
0301:                this .boundMappedToLastCycle = boundMappedToLastCycle;
0302:            }
0303:
0304:            /**
0305:             * Selects a tick unit when the axis is displayed horizontally.
0306:             * 
0307:             * @param g2  the graphics device.
0308:             * @param drawArea  the drawing area.
0309:             * @param dataArea  the data area.
0310:             * @param edge  the side of the rectangle on which the axis is displayed.
0311:             */
0312:            protected void selectHorizontalAutoTickUnit(Graphics2D g2,
0313:                    Rectangle2D drawArea, Rectangle2D dataArea,
0314:                    RectangleEdge edge) {
0315:
0316:                double tickLabelWidth = estimateMaximumTickLabelWidth(g2,
0317:                        getTickUnit());
0318:
0319:                // Compute number of labels
0320:                double n = getRange().getLength() * tickLabelWidth
0321:                        / dataArea.getWidth();
0322:
0323:                setTickUnit((NumberTickUnit) getStandardTickUnits()
0324:                        .getCeilingTickUnit(n), false, false);
0325:
0326:            }
0327:
0328:            /**
0329:             * Selects a tick unit when the axis is displayed vertically.
0330:             * 
0331:             * @param g2  the graphics device.
0332:             * @param drawArea  the drawing area.
0333:             * @param dataArea  the data area.
0334:             * @param edge  the side of the rectangle on which the axis is displayed.
0335:             */
0336:            protected void selectVerticalAutoTickUnit(Graphics2D g2,
0337:                    Rectangle2D drawArea, Rectangle2D dataArea,
0338:                    RectangleEdge edge) {
0339:
0340:                double tickLabelWidth = estimateMaximumTickLabelWidth(g2,
0341:                        getTickUnit());
0342:
0343:                // Compute number of labels
0344:                double n = getRange().getLength() * tickLabelWidth
0345:                        / dataArea.getHeight();
0346:
0347:                setTickUnit((NumberTickUnit) getStandardTickUnits()
0348:                        .getCeilingTickUnit(n), false, false);
0349:
0350:            }
0351:
0352:            /** 
0353:             * A special Number tick that also hold information about the cycle bound 
0354:             * mapping for this tick.  This is especially useful for having a tick at 
0355:             * each axis end with the cycle bound value.  See also 
0356:             * isBoundMappedToLastCycle()
0357:             */
0358:            protected static class CycleBoundTick extends NumberTick {
0359:
0360:                /** Map to last cycle. */
0361:                public boolean mapToLastCycle;
0362:
0363:                /**
0364:                 * Creates a new tick.
0365:                 * 
0366:                 * @param mapToLastCycle  map to last cycle?
0367:                 * @param number  the number.
0368:                 * @param label  the label.
0369:                 * @param textAnchor  the text anchor.
0370:                 * @param rotationAnchor  the rotation anchor.
0371:                 * @param angle  the rotation angle.
0372:                 */
0373:                public CycleBoundTick(boolean mapToLastCycle, Number number,
0374:                        String label, TextAnchor textAnchor,
0375:                        TextAnchor rotationAnchor, double angle) {
0376:                    super (number, label, textAnchor, rotationAnchor, angle);
0377:                    this .mapToLastCycle = mapToLastCycle;
0378:                }
0379:            }
0380:
0381:            /**
0382:             * Calculates the anchor point for a tick.
0383:             * 
0384:             * @param tick  the tick.
0385:             * @param cursor  the cursor.
0386:             * @param dataArea  the data area.
0387:             * @param edge  the side on which the axis is displayed.
0388:             * 
0389:             * @return The anchor point.
0390:             */
0391:            protected float[] calculateAnchorPoint(ValueTick tick,
0392:                    double cursor, Rectangle2D dataArea, RectangleEdge edge) {
0393:                if (tick instanceof  CycleBoundTick) {
0394:                    boolean mapsav = this .boundMappedToLastCycle;
0395:                    this .boundMappedToLastCycle = ((CycleBoundTick) tick).mapToLastCycle;
0396:                    float[] ret = super .calculateAnchorPoint(tick, cursor,
0397:                            dataArea, edge);
0398:                    this .boundMappedToLastCycle = mapsav;
0399:                    return ret;
0400:                }
0401:                return super .calculateAnchorPoint(tick, cursor, dataArea, edge);
0402:            }
0403:
0404:            /**
0405:             * Builds a list of ticks for the axis.  This method is called when the 
0406:             * axis is at the top or bottom of the chart (so the axis is "horizontal").
0407:             * 
0408:             * @param g2  the graphics device.
0409:             * @param dataArea  the data area.
0410:             * @param edge  the edge.
0411:             * 
0412:             * @return A list of ticks.
0413:             */
0414:            protected List refreshTicksHorizontal(Graphics2D g2,
0415:                    Rectangle2D dataArea, RectangleEdge edge) {
0416:
0417:                List result = new java.util.ArrayList();
0418:
0419:                Font tickLabelFont = getTickLabelFont();
0420:                g2.setFont(tickLabelFont);
0421:
0422:                if (isAutoTickUnitSelection()) {
0423:                    selectAutoTickUnit(g2, dataArea, edge);
0424:                }
0425:
0426:                double unit = getTickUnit().getSize();
0427:                double cycleBound = getCycleBound();
0428:                double currentTickValue = Math.ceil(cycleBound / unit) * unit;
0429:                double upperValue = getRange().getUpperBound();
0430:                boolean cycled = false;
0431:
0432:                boolean boundMapping = this .boundMappedToLastCycle;
0433:                this .boundMappedToLastCycle = false;
0434:
0435:                CycleBoundTick lastTick = null;
0436:                float lastX = 0.0f;
0437:
0438:                if (upperValue == cycleBound) {
0439:                    currentTickValue = calculateLowestVisibleTickValue();
0440:                    cycled = true;
0441:                    this .boundMappedToLastCycle = true;
0442:                }
0443:
0444:                while (currentTickValue <= upperValue) {
0445:
0446:                    // Cycle when necessary
0447:                    boolean cyclenow = false;
0448:                    if ((currentTickValue + unit > upperValue) && !cycled) {
0449:                        cyclenow = true;
0450:                    }
0451:
0452:                    double xx = valueToJava2D(currentTickValue, dataArea, edge);
0453:                    String tickLabel;
0454:                    NumberFormat formatter = getNumberFormatOverride();
0455:                    if (formatter != null) {
0456:                        tickLabel = formatter.format(currentTickValue);
0457:                    } else {
0458:                        tickLabel = getTickUnit().valueToString(
0459:                                currentTickValue);
0460:                    }
0461:                    float x = (float) xx;
0462:                    TextAnchor anchor = null;
0463:                    TextAnchor rotationAnchor = null;
0464:                    double angle = 0.0;
0465:                    if (isVerticalTickLabels()) {
0466:                        if (edge == RectangleEdge.TOP) {
0467:                            angle = Math.PI / 2.0;
0468:                        } else {
0469:                            angle = -Math.PI / 2.0;
0470:                        }
0471:                        anchor = TextAnchor.CENTER_RIGHT;
0472:                        // If tick overlap when cycling, update last tick too
0473:                        if ((lastTick != null) && (lastX == x)
0474:                                && (currentTickValue != cycleBound)) {
0475:                            anchor = isInverted() ? TextAnchor.TOP_RIGHT
0476:                                    : TextAnchor.BOTTOM_RIGHT;
0477:                            result.remove(result.size() - 1);
0478:                            result.add(new CycleBoundTick(
0479:                                    this .boundMappedToLastCycle, lastTick
0480:                                            .getNumber(), lastTick.getText(),
0481:                                    anchor, anchor, lastTick.getAngle()));
0482:                            this .internalMarkerWhenTicksOverlap = true;
0483:                            anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT
0484:                                    : TextAnchor.TOP_RIGHT;
0485:                        }
0486:                        rotationAnchor = anchor;
0487:                    } else {
0488:                        if (edge == RectangleEdge.TOP) {
0489:                            anchor = TextAnchor.BOTTOM_CENTER;
0490:                            if ((lastTick != null) && (lastX == x)
0491:                                    && (currentTickValue != cycleBound)) {
0492:                                anchor = isInverted() ? TextAnchor.BOTTOM_LEFT
0493:                                        : TextAnchor.BOTTOM_RIGHT;
0494:                                result.remove(result.size() - 1);
0495:                                result.add(new CycleBoundTick(
0496:                                        this .boundMappedToLastCycle, lastTick
0497:                                                .getNumber(), lastTick
0498:                                                .getText(), anchor, anchor,
0499:                                        lastTick.getAngle()));
0500:                                this .internalMarkerWhenTicksOverlap = true;
0501:                                anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT
0502:                                        : TextAnchor.BOTTOM_LEFT;
0503:                            }
0504:                            rotationAnchor = anchor;
0505:                        } else {
0506:                            anchor = TextAnchor.TOP_CENTER;
0507:                            if ((lastTick != null) && (lastX == x)
0508:                                    && (currentTickValue != cycleBound)) {
0509:                                anchor = isInverted() ? TextAnchor.TOP_LEFT
0510:                                        : TextAnchor.TOP_RIGHT;
0511:                                result.remove(result.size() - 1);
0512:                                result.add(new CycleBoundTick(
0513:                                        this .boundMappedToLastCycle, lastTick
0514:                                                .getNumber(), lastTick
0515:                                                .getText(), anchor, anchor,
0516:                                        lastTick.getAngle()));
0517:                                this .internalMarkerWhenTicksOverlap = true;
0518:                                anchor = isInverted() ? TextAnchor.TOP_RIGHT
0519:                                        : TextAnchor.TOP_LEFT;
0520:                            }
0521:                            rotationAnchor = anchor;
0522:                        }
0523:                    }
0524:
0525:                    CycleBoundTick tick = new CycleBoundTick(
0526:                            this .boundMappedToLastCycle, new Double(
0527:                                    currentTickValue), tickLabel, anchor,
0528:                            rotationAnchor, angle);
0529:                    if (currentTickValue == cycleBound) {
0530:                        this .internalMarkerCycleBoundTick = tick;
0531:                    }
0532:                    result.add(tick);
0533:                    lastTick = tick;
0534:                    lastX = x;
0535:
0536:                    currentTickValue += unit;
0537:
0538:                    if (cyclenow) {
0539:                        currentTickValue = calculateLowestVisibleTickValue();
0540:                        upperValue = cycleBound;
0541:                        cycled = true;
0542:                        this .boundMappedToLastCycle = true;
0543:                    }
0544:
0545:                }
0546:                this .boundMappedToLastCycle = boundMapping;
0547:                return result;
0548:
0549:            }
0550:
0551:            /**
0552:             * Builds a list of ticks for the axis.  This method is called when the 
0553:             * axis is at the left or right of the chart (so the axis is "vertical").
0554:             * 
0555:             * @param g2  the graphics device.
0556:             * @param dataArea  the data area.
0557:             * @param edge  the edge.
0558:             * 
0559:             * @return A list of ticks.
0560:             */
0561:            protected List refreshVerticalTicks(Graphics2D g2,
0562:                    Rectangle2D dataArea, RectangleEdge edge) {
0563:
0564:                List result = new java.util.ArrayList();
0565:                result.clear();
0566:
0567:                Font tickLabelFont = getTickLabelFont();
0568:                g2.setFont(tickLabelFont);
0569:                if (isAutoTickUnitSelection()) {
0570:                    selectAutoTickUnit(g2, dataArea, edge);
0571:                }
0572:
0573:                double unit = getTickUnit().getSize();
0574:                double cycleBound = getCycleBound();
0575:                double currentTickValue = Math.ceil(cycleBound / unit) * unit;
0576:                double upperValue = getRange().getUpperBound();
0577:                boolean cycled = false;
0578:
0579:                boolean boundMapping = this .boundMappedToLastCycle;
0580:                this .boundMappedToLastCycle = true;
0581:
0582:                NumberTick lastTick = null;
0583:                float lastY = 0.0f;
0584:
0585:                if (upperValue == cycleBound) {
0586:                    currentTickValue = calculateLowestVisibleTickValue();
0587:                    cycled = true;
0588:                    this .boundMappedToLastCycle = true;
0589:                }
0590:
0591:                while (currentTickValue <= upperValue) {
0592:
0593:                    // Cycle when necessary
0594:                    boolean cyclenow = false;
0595:                    if ((currentTickValue + unit > upperValue) && !cycled) {
0596:                        cyclenow = true;
0597:                    }
0598:
0599:                    double yy = valueToJava2D(currentTickValue, dataArea, edge);
0600:                    String tickLabel;
0601:                    NumberFormat formatter = getNumberFormatOverride();
0602:                    if (formatter != null) {
0603:                        tickLabel = formatter.format(currentTickValue);
0604:                    } else {
0605:                        tickLabel = getTickUnit().valueToString(
0606:                                currentTickValue);
0607:                    }
0608:
0609:                    float y = (float) yy;
0610:                    TextAnchor anchor = null;
0611:                    TextAnchor rotationAnchor = null;
0612:                    double angle = 0.0;
0613:                    if (isVerticalTickLabels()) {
0614:
0615:                        if (edge == RectangleEdge.LEFT) {
0616:                            anchor = TextAnchor.BOTTOM_CENTER;
0617:                            if ((lastTick != null) && (lastY == y)
0618:                                    && (currentTickValue != cycleBound)) {
0619:                                anchor = isInverted() ? TextAnchor.BOTTOM_LEFT
0620:                                        : TextAnchor.BOTTOM_RIGHT;
0621:                                result.remove(result.size() - 1);
0622:                                result.add(new CycleBoundTick(
0623:                                        this .boundMappedToLastCycle, lastTick
0624:                                                .getNumber(), lastTick
0625:                                                .getText(), anchor, anchor,
0626:                                        lastTick.getAngle()));
0627:                                this .internalMarkerWhenTicksOverlap = true;
0628:                                anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT
0629:                                        : TextAnchor.BOTTOM_LEFT;
0630:                            }
0631:                            rotationAnchor = anchor;
0632:                            angle = -Math.PI / 2.0;
0633:                        } else {
0634:                            anchor = TextAnchor.BOTTOM_CENTER;
0635:                            if ((lastTick != null) && (lastY == y)
0636:                                    && (currentTickValue != cycleBound)) {
0637:                                anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT
0638:                                        : TextAnchor.BOTTOM_LEFT;
0639:                                result.remove(result.size() - 1);
0640:                                result.add(new CycleBoundTick(
0641:                                        this .boundMappedToLastCycle, lastTick
0642:                                                .getNumber(), lastTick
0643:                                                .getText(), anchor, anchor,
0644:                                        lastTick.getAngle()));
0645:                                this .internalMarkerWhenTicksOverlap = true;
0646:                                anchor = isInverted() ? TextAnchor.BOTTOM_LEFT
0647:                                        : TextAnchor.BOTTOM_RIGHT;
0648:                            }
0649:                            rotationAnchor = anchor;
0650:                            angle = Math.PI / 2.0;
0651:                        }
0652:                    } else {
0653:                        if (edge == RectangleEdge.LEFT) {
0654:                            anchor = TextAnchor.CENTER_RIGHT;
0655:                            if ((lastTick != null) && (lastY == y)
0656:                                    && (currentTickValue != cycleBound)) {
0657:                                anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT
0658:                                        : TextAnchor.TOP_RIGHT;
0659:                                result.remove(result.size() - 1);
0660:                                result.add(new CycleBoundTick(
0661:                                        this .boundMappedToLastCycle, lastTick
0662:                                                .getNumber(), lastTick
0663:                                                .getText(), anchor, anchor,
0664:                                        lastTick.getAngle()));
0665:                                this .internalMarkerWhenTicksOverlap = true;
0666:                                anchor = isInverted() ? TextAnchor.TOP_RIGHT
0667:                                        : TextAnchor.BOTTOM_RIGHT;
0668:                            }
0669:                            rotationAnchor = anchor;
0670:                        } else {
0671:                            anchor = TextAnchor.CENTER_LEFT;
0672:                            if ((lastTick != null) && (lastY == y)
0673:                                    && (currentTickValue != cycleBound)) {
0674:                                anchor = isInverted() ? TextAnchor.BOTTOM_LEFT
0675:                                        : TextAnchor.TOP_LEFT;
0676:                                result.remove(result.size() - 1);
0677:                                result.add(new CycleBoundTick(
0678:                                        this .boundMappedToLastCycle, lastTick
0679:                                                .getNumber(), lastTick
0680:                                                .getText(), anchor, anchor,
0681:                                        lastTick.getAngle()));
0682:                                this .internalMarkerWhenTicksOverlap = true;
0683:                                anchor = isInverted() ? TextAnchor.TOP_LEFT
0684:                                        : TextAnchor.BOTTOM_LEFT;
0685:                            }
0686:                            rotationAnchor = anchor;
0687:                        }
0688:                    }
0689:
0690:                    CycleBoundTick tick = new CycleBoundTick(
0691:                            this .boundMappedToLastCycle, new Double(
0692:                                    currentTickValue), tickLabel, anchor,
0693:                            rotationAnchor, angle);
0694:                    if (currentTickValue == cycleBound) {
0695:                        this .internalMarkerCycleBoundTick = tick;
0696:                    }
0697:                    result.add(tick);
0698:                    lastTick = tick;
0699:                    lastY = y;
0700:
0701:                    if (currentTickValue == cycleBound) {
0702:                        this .internalMarkerCycleBoundTick = tick;
0703:                    }
0704:
0705:                    currentTickValue += unit;
0706:
0707:                    if (cyclenow) {
0708:                        currentTickValue = calculateLowestVisibleTickValue();
0709:                        upperValue = cycleBound;
0710:                        cycled = true;
0711:                        this .boundMappedToLastCycle = false;
0712:                    }
0713:
0714:                }
0715:                this .boundMappedToLastCycle = boundMapping;
0716:                return result;
0717:            }
0718:
0719:            /**
0720:             * Converts a coordinate from Java 2D space to data space.
0721:             * 
0722:             * @param java2DValue  the coordinate in Java2D space.
0723:             * @param dataArea  the data area.
0724:             * @param edge  the edge.
0725:             * 
0726:             * @return The data value.
0727:             */
0728:            public double java2DToValue(double java2DValue,
0729:                    Rectangle2D dataArea, RectangleEdge edge) {
0730:                Range range = getRange();
0731:
0732:                double vmax = range.getUpperBound();
0733:                double vp = getCycleBound();
0734:
0735:                double jmin = 0.0;
0736:                double jmax = 0.0;
0737:                if (RectangleEdge.isTopOrBottom(edge)) {
0738:                    jmin = dataArea.getMinX();
0739:                    jmax = dataArea.getMaxX();
0740:                } else if (RectangleEdge.isLeftOrRight(edge)) {
0741:                    jmin = dataArea.getMaxY();
0742:                    jmax = dataArea.getMinY();
0743:                }
0744:
0745:                if (isInverted()) {
0746:                    double jbreak = jmax - (vmax - vp) * (jmax - jmin)
0747:                            / this .period;
0748:                    if (java2DValue >= jbreak) {
0749:                        return vp + (jmax - java2DValue) * this .period
0750:                                / (jmax - jmin);
0751:                    } else {
0752:                        return vp - (java2DValue - jmin) * this .period
0753:                                / (jmax - jmin);
0754:                    }
0755:                } else {
0756:                    double jbreak = (vmax - vp) * (jmax - jmin) / this .period
0757:                            + jmin;
0758:                    if (java2DValue <= jbreak) {
0759:                        return vp + (java2DValue - jmin) * this .period
0760:                                / (jmax - jmin);
0761:                    } else {
0762:                        return vp - (jmax - java2DValue) * this .period
0763:                                / (jmax - jmin);
0764:                    }
0765:                }
0766:            }
0767:
0768:            /**
0769:             * Translates a value from data space to Java 2D space.
0770:             * 
0771:             * @param value  the data value.
0772:             * @param dataArea  the data area.
0773:             * @param edge  the edge.
0774:             * 
0775:             * @return The Java 2D value.
0776:             */
0777:            public double valueToJava2D(double value, Rectangle2D dataArea,
0778:                    RectangleEdge edge) {
0779:                Range range = getRange();
0780:
0781:                double vmin = range.getLowerBound();
0782:                double vmax = range.getUpperBound();
0783:                double vp = getCycleBound();
0784:
0785:                if ((value < vmin) || (value > vmax)) {
0786:                    return Double.NaN;
0787:                }
0788:
0789:                double jmin = 0.0;
0790:                double jmax = 0.0;
0791:                if (RectangleEdge.isTopOrBottom(edge)) {
0792:                    jmin = dataArea.getMinX();
0793:                    jmax = dataArea.getMaxX();
0794:                } else if (RectangleEdge.isLeftOrRight(edge)) {
0795:                    jmax = dataArea.getMinY();
0796:                    jmin = dataArea.getMaxY();
0797:                }
0798:
0799:                if (isInverted()) {
0800:                    if (value == vp) {
0801:                        return this .boundMappedToLastCycle ? jmin : jmax;
0802:                    } else if (value > vp) {
0803:                        return jmax - (value - vp) * (jmax - jmin)
0804:                                / this .period;
0805:                    } else {
0806:                        return jmin + (vp - value) * (jmax - jmin)
0807:                                / this .period;
0808:                    }
0809:                } else {
0810:                    if (value == vp) {
0811:                        return this .boundMappedToLastCycle ? jmax : jmin;
0812:                    } else if (value >= vp) {
0813:                        return jmin + (value - vp) * (jmax - jmin)
0814:                                / this .period;
0815:                    } else {
0816:                        return jmax - (vp - value) * (jmax - jmin)
0817:                                / this .period;
0818:                    }
0819:                }
0820:            }
0821:
0822:            /**
0823:             * Centers the range about the given value.
0824:             * 
0825:             * @param value  the data value.
0826:             */
0827:            public void centerRange(double value) {
0828:                setRange(value - this .period / 2.0, value + this .period / 2.0);
0829:            }
0830:
0831:            /** 
0832:             * This function is nearly useless since the auto range is fixed for this 
0833:             * class to the period.  The period is extended if necessary to fit the 
0834:             * minimum size.
0835:             * 
0836:             * @param size  the size.
0837:             * @param notify  notify?
0838:             * 
0839:             * @see org.jfree.chart.axis.ValueAxis#setAutoRangeMinimumSize(double, 
0840:             *      boolean)
0841:             */
0842:            public void setAutoRangeMinimumSize(double size, boolean notify) {
0843:                if (size > this .period) {
0844:                    this .period = size;
0845:                }
0846:                super .setAutoRangeMinimumSize(size, notify);
0847:            }
0848:
0849:            /** 
0850:             * The auto range is fixed for this class to the period by default. 
0851:             * This function will thus set a new period.
0852:             * 
0853:             * @param length  the length.
0854:             * 
0855:             * @see org.jfree.chart.axis.ValueAxis#setFixedAutoRange(double)
0856:             */
0857:            public void setFixedAutoRange(double length) {
0858:                this .period = length;
0859:                super .setFixedAutoRange(length);
0860:            }
0861:
0862:            /** 
0863:             * Sets a new axis range. The period is extended to fit the range size, if 
0864:             * necessary.
0865:             * 
0866:             * @param range  the range.
0867:             * @param turnOffAutoRange  switch off the auto range.
0868:             * @param notify notify?
0869:             * 
0870:             * @see org.jfree.chart.axis.ValueAxis#setRange(Range, boolean, boolean) 
0871:             */
0872:            public void setRange(Range range, boolean turnOffAutoRange,
0873:                    boolean notify) {
0874:                double size = range.getUpperBound() - range.getLowerBound();
0875:                if (size > this .period) {
0876:                    this .period = size;
0877:                }
0878:                super .setRange(range, turnOffAutoRange, notify);
0879:            }
0880:
0881:            /**
0882:             * The cycle bound is defined as the higest value x such that 
0883:             * "offset + period * i = x", with i and integer and x &lt; 
0884:             * range.getUpperBound() This is the value which is at both ends of the 
0885:             * axis :  x...up|low...x
0886:             * The values from x to up are the valued in the current cycle.
0887:             * The values from low to x are the valued in the previous cycle.
0888:             * 
0889:             * @return The cycle bound.
0890:             */
0891:            public double getCycleBound() {
0892:                return Math.floor((getRange().getUpperBound() - this .offset)
0893:                        / this .period)
0894:                        * this .period + this .offset;
0895:            }
0896:
0897:            /**
0898:             * The cycle bound is a multiple of the period, plus optionally a start 
0899:             * offset.
0900:             * <P>
0901:             * <pre>cb = n * period + offset</pre><br>
0902:             * 
0903:             * @return The current offset.
0904:             * 
0905:             * @see #getCycleBound()
0906:             */
0907:            public double getOffset() {
0908:                return this .offset;
0909:            }
0910:
0911:            /**
0912:             * The cycle bound is a multiple of the period, plus optionally a start 
0913:             * offset.
0914:             * <P>
0915:             * <pre>cb = n * period + offset</pre><br>
0916:             * 
0917:             * @param offset The offset to set.
0918:             *
0919:             * @see #getCycleBound() 
0920:             */
0921:            public void setOffset(double offset) {
0922:                this .offset = offset;
0923:            }
0924:
0925:            /**
0926:             * The cycle bound is a multiple of the period, plus optionally a start 
0927:             * offset.
0928:             * <P>
0929:             * <pre>cb = n * period + offset</pre><br>
0930:             * 
0931:             * @return The current period.
0932:             * 
0933:             * @see #getCycleBound()
0934:             */
0935:            public double getPeriod() {
0936:                return this .period;
0937:            }
0938:
0939:            /**
0940:             * The cycle bound is a multiple of the period, plus optionally a start 
0941:             * offset.
0942:             * <P>
0943:             * <pre>cb = n * period + offset</pre><br>
0944:             * 
0945:             * @param period The period to set.
0946:             * 
0947:             * @see #getCycleBound()
0948:             */
0949:            public void setPeriod(double period) {
0950:                this .period = period;
0951:            }
0952:
0953:            /**
0954:             * Draws the tick marks and labels.
0955:             * 
0956:             * @param g2  the graphics device.
0957:             * @param cursor  the cursor.
0958:             * @param plotArea  the plot area.
0959:             * @param dataArea  the area inside the axes.
0960:             * @param edge  the side on which the axis is displayed.
0961:             * 
0962:             * @return The axis state.
0963:             */
0964:            protected AxisState drawTickMarksAndLabels(Graphics2D g2,
0965:                    double cursor, Rectangle2D plotArea, Rectangle2D dataArea,
0966:                    RectangleEdge edge) {
0967:                this .internalMarkerWhenTicksOverlap = false;
0968:                AxisState ret = super .drawTickMarksAndLabels(g2, cursor,
0969:                        plotArea, dataArea, edge);
0970:
0971:                // continue and separate the labels only if necessary
0972:                if (!this .internalMarkerWhenTicksOverlap) {
0973:                    return ret;
0974:                }
0975:
0976:                double ol = getTickMarkOutsideLength();
0977:                FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
0978:
0979:                if (isVerticalTickLabels()) {
0980:                    ol = fm.getMaxAdvance();
0981:                } else {
0982:                    ol = fm.getHeight();
0983:                }
0984:
0985:                double il = 0;
0986:                if (isTickMarksVisible()) {
0987:                    float xx = (float) valueToJava2D(
0988:                            getRange().getUpperBound(), dataArea, edge);
0989:                    Line2D mark = null;
0990:                    g2.setStroke(getTickMarkStroke());
0991:                    g2.setPaint(getTickMarkPaint());
0992:                    if (edge == RectangleEdge.LEFT) {
0993:                        mark = new Line2D.Double(cursor - ol, xx, cursor + il,
0994:                                xx);
0995:                    } else if (edge == RectangleEdge.RIGHT) {
0996:                        mark = new Line2D.Double(cursor + ol, xx, cursor - il,
0997:                                xx);
0998:                    } else if (edge == RectangleEdge.TOP) {
0999:                        mark = new Line2D.Double(xx, cursor - ol, xx, cursor
1000:                                + il);
1001:                    } else if (edge == RectangleEdge.BOTTOM) {
1002:                        mark = new Line2D.Double(xx, cursor + ol, xx, cursor
1003:                                - il);
1004:                    }
1005:                    g2.draw(mark);
1006:                }
1007:                return ret;
1008:            }
1009:
1010:            /**
1011:             * Draws the axis.
1012:             * 
1013:             * @param g2  the graphics device (<code>null</code> not permitted).
1014:             * @param cursor  the cursor position.
1015:             * @param plotArea  the plot area (<code>null</code> not permitted).
1016:             * @param dataArea  the data area (<code>null</code> not permitted).
1017:             * @param edge  the edge (<code>null</code> not permitted).
1018:             * @param plotState  collects information about the plot 
1019:             *                   (<code>null</code> permitted).
1020:             * 
1021:             * @return The axis state (never <code>null</code>).
1022:             */
1023:            public AxisState draw(Graphics2D g2, double cursor,
1024:                    Rectangle2D plotArea, Rectangle2D dataArea,
1025:                    RectangleEdge edge, PlotRenderingInfo plotState) {
1026:
1027:                AxisState ret = super .draw(g2, cursor, plotArea, dataArea,
1028:                        edge, plotState);
1029:                if (isAdvanceLineVisible()) {
1030:                    double xx = valueToJava2D(getRange().getUpperBound(),
1031:                            dataArea, edge);
1032:                    Line2D mark = null;
1033:                    g2.setStroke(getAdvanceLineStroke());
1034:                    g2.setPaint(getAdvanceLinePaint());
1035:                    if (edge == RectangleEdge.LEFT) {
1036:                        mark = new Line2D.Double(cursor, xx, cursor
1037:                                + dataArea.getWidth(), xx);
1038:                    } else if (edge == RectangleEdge.RIGHT) {
1039:                        mark = new Line2D.Double(cursor - dataArea.getWidth(),
1040:                                xx, cursor, xx);
1041:                    } else if (edge == RectangleEdge.TOP) {
1042:                        mark = new Line2D.Double(xx, cursor
1043:                                + dataArea.getHeight(), xx, cursor);
1044:                    } else if (edge == RectangleEdge.BOTTOM) {
1045:                        mark = new Line2D.Double(xx, cursor, xx, cursor
1046:                                - dataArea.getHeight());
1047:                    }
1048:                    g2.draw(mark);
1049:                }
1050:                return ret;
1051:            }
1052:
1053:            /**
1054:             * Reserve some space on each axis side because we draw a centered label at
1055:             * each extremity. 
1056:             * 
1057:             * @param g2  the graphics device.
1058:             * @param plot  the plot.
1059:             * @param plotArea  the plot area.
1060:             * @param edge  the edge.
1061:             * @param space  the space already reserved.
1062:             * 
1063:             * @return The reserved space.
1064:             */
1065:            public AxisSpace reserveSpace(Graphics2D g2, Plot plot,
1066:                    Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
1067:
1068:                this .internalMarkerCycleBoundTick = null;
1069:                AxisSpace ret = super .reserveSpace(g2, plot, plotArea, edge,
1070:                        space);
1071:                if (this .internalMarkerCycleBoundTick == null) {
1072:                    return ret;
1073:                }
1074:
1075:                FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
1076:                Rectangle2D r = TextUtilities.getTextBounds(
1077:                        this .internalMarkerCycleBoundTick.getText(), g2, fm);
1078:
1079:                if (RectangleEdge.isTopOrBottom(edge)) {
1080:                    if (isVerticalTickLabels()) {
1081:                        space.add(r.getHeight() / 2, RectangleEdge.RIGHT);
1082:                    } else {
1083:                        space.add(r.getWidth() / 2, RectangleEdge.RIGHT);
1084:                    }
1085:                } else if (RectangleEdge.isLeftOrRight(edge)) {
1086:                    if (isVerticalTickLabels()) {
1087:                        space.add(r.getWidth() / 2, RectangleEdge.TOP);
1088:                    } else {
1089:                        space.add(r.getHeight() / 2, RectangleEdge.TOP);
1090:                    }
1091:                }
1092:
1093:                return ret;
1094:
1095:            }
1096:
1097:            /**
1098:             * Provides serialization support.
1099:             *
1100:             * @param stream  the output stream.
1101:             *
1102:             * @throws IOException  if there is an I/O error.
1103:             */
1104:            private void writeObject(ObjectOutputStream stream)
1105:                    throws IOException {
1106:
1107:                stream.defaultWriteObject();
1108:                SerialUtilities.writePaint(this .advanceLinePaint, stream);
1109:                SerialUtilities.writeStroke(this .advanceLineStroke, stream);
1110:
1111:            }
1112:
1113:            /**
1114:             * Provides serialization support.
1115:             *
1116:             * @param stream  the input stream.
1117:             *
1118:             * @throws IOException  if there is an I/O error.
1119:             * @throws ClassNotFoundException  if there is a classpath problem.
1120:             */
1121:            private void readObject(ObjectInputStream stream)
1122:                    throws IOException, ClassNotFoundException {
1123:
1124:                stream.defaultReadObject();
1125:                this .advanceLinePaint = SerialUtilities.readPaint(stream);
1126:                this .advanceLineStroke = SerialUtilities.readStroke(stream);
1127:
1128:            }
1129:
1130:            /**
1131:             * Tests the axis for equality with another object.
1132:             * 
1133:             * @param obj  the object to test against.
1134:             * 
1135:             * @return A boolean.
1136:             */
1137:            public boolean equals(Object obj) {
1138:                if (obj == this ) {
1139:                    return true;
1140:                }
1141:                if (!(obj instanceof  CyclicNumberAxis)) {
1142:                    return false;
1143:                }
1144:                if (!super .equals(obj)) {
1145:                    return false;
1146:                }
1147:                CyclicNumberAxis that = (CyclicNumberAxis) obj;
1148:                if (this .period != that.period) {
1149:                    return false;
1150:                }
1151:                if (this .offset != that.offset) {
1152:                    return false;
1153:                }
1154:                if (!PaintUtilities.equal(this .advanceLinePaint,
1155:                        that.advanceLinePaint)) {
1156:                    return false;
1157:                }
1158:                if (!ObjectUtilities.equal(this .advanceLineStroke,
1159:                        that.advanceLineStroke)) {
1160:                    return false;
1161:                }
1162:                if (this .advanceLineVisible != that.advanceLineVisible) {
1163:                    return false;
1164:                }
1165:                if (this .boundMappedToLastCycle != that.boundMappedToLastCycle) {
1166:                    return false;
1167:                }
1168:                return true;
1169:            }
1170:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.