Source Code Cross Referenced for BasicProgressBarUI.java in  » 6.0-JDK-Core » swing » javax » swing » plaf » basic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.plaf.basic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.swing.plaf.basic;
0027
0028        import sun.swing.SwingUtilities2;
0029        import java.awt.*;
0030        import java.awt.geom.AffineTransform;
0031        import java.awt.event.*;
0032        import javax.swing.*;
0033        import javax.swing.event.*;
0034        import javax.swing.plaf.*;
0035        import java.beans.PropertyChangeListener;
0036        import java.beans.PropertyChangeEvent;
0037        import java.io.Serializable;
0038        import sun.swing.DefaultLookup;
0039
0040        /**
0041         * A Basic L&F implementation of ProgressBarUI.
0042         *
0043         * @version 1.80 05/05/07
0044         * @author Michael C. Albers
0045         * @author Kathy Walrath
0046         */
0047        public class BasicProgressBarUI extends ProgressBarUI {
0048            private int cachedPercent;
0049            private int cellLength, cellSpacing;
0050            // The "selectionForeground" is the color of the text when it is painted
0051            // over a filled area of the progress bar. The "selectionBackground"
0052            // is for the text over the unfilled progress bar area.
0053            private Color selectionForeground, selectionBackground;
0054
0055            private Animator animator;
0056
0057            protected JProgressBar progressBar;
0058            protected ChangeListener changeListener;
0059            private Handler handler;
0060
0061            /** 
0062             * The current state of the indeterminate animation's cycle.
0063             * 0, the initial value, means paint the first frame.
0064             * When the progress bar is indeterminate and showing,
0065             * the default animation thread updates this variable
0066             * by invoking incrementAnimationIndex()
0067             * every repaintInterval milliseconds.
0068             */
0069            private int animationIndex = 0;
0070
0071            /**
0072             * The number of frames per cycle. Under the default implementation,
0073             * this depends on the cycleTime and repaintInterval.  It
0074             * must be an even number for the default painting algorithm.  This
0075             * value is set in the initIndeterminateValues method.
0076             */
0077            private int numFrames; //0 1|numFrames-1 ... numFrames/2
0078
0079            /**
0080             * Interval (in ms) between repaints of the indeterminate progress bar.
0081             * The value of this method is set 
0082             * (every time the progress bar changes to indeterminate mode)
0083             * using the 
0084             * "ProgressBar.repaintInterval" key in the defaults table.
0085             */
0086            private int repaintInterval;
0087
0088            /**
0089             * The number of milliseconds until the animation cycle repeats.
0090             * The value of this method is set 
0091             * (every time the progress bar changes to indeterminate mode)
0092             * using the 
0093             * "ProgressBar.cycleTime" key in the defaults table.
0094             */
0095            private int cycleTime; //must be repaintInterval*2*aPositiveInteger
0096
0097            //performance stuff
0098            private static boolean ADJUSTTIMER = true; //makes a BIG difference;
0099            //make this false for
0100            //performance tests
0101
0102            /**                                                             
0103             * Used to hold the location and size of the bouncing box (returned
0104             * by getBox) to be painted.
0105             *
0106             * @since 1.5
0107             */
0108            protected Rectangle boxRect;
0109
0110            /**                                                             
0111             * The rectangle to be updated the next time the         
0112             * animation thread calls repaint.  For bouncing-box            
0113             * animation this rect should include the union of    
0114             * the currently displayed box (which needs to be erased)       
0115             * and the box to be displayed next.
0116             * This rectangle's values are set in 
0117             * the setAnimationIndex method.
0118             */
0119            private Rectangle nextPaintRect;
0120
0121            //cache
0122            /** The component's painting area, not including the border. */
0123            private Rectangle componentInnards; //the current painting area
0124            private Rectangle oldComponentInnards; //used to see if the size changed
0125
0126            /** For bouncing-box animation, the change in position per frame. */
0127            private double delta = 0.0;
0128
0129            private int maxPosition = 0; //maximum X (horiz) or Y box location
0130
0131            public static ComponentUI createUI(JComponent x) {
0132                return new BasicProgressBarUI();
0133            }
0134
0135            public void installUI(JComponent c) {
0136                progressBar = (JProgressBar) c;
0137                installDefaults();
0138                installListeners();
0139                if (progressBar.isIndeterminate()) {
0140                    initIndeterminateValues();
0141                }
0142            }
0143
0144            public void uninstallUI(JComponent c) {
0145                if (progressBar.isIndeterminate()) {
0146                    cleanUpIndeterminateValues();
0147                }
0148                uninstallDefaults();
0149                uninstallListeners();
0150                progressBar = null;
0151            }
0152
0153            protected void installDefaults() {
0154                LookAndFeel
0155                        .installProperty(progressBar, "opaque", Boolean.TRUE);
0156                LookAndFeel.installBorder(progressBar, "ProgressBar.border");
0157                LookAndFeel.installColorsAndFont(progressBar,
0158                        "ProgressBar.background", "ProgressBar.foreground",
0159                        "ProgressBar.font");
0160                cellLength = UIManager.getInt("ProgressBar.cellLength");
0161                cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
0162                selectionForeground = UIManager
0163                        .getColor("ProgressBar.selectionForeground");
0164                selectionBackground = UIManager
0165                        .getColor("ProgressBar.selectionBackground");
0166            }
0167
0168            protected void uninstallDefaults() {
0169                LookAndFeel.uninstallBorder(progressBar);
0170            }
0171
0172            protected void installListeners() {
0173                //Listen for changes in the progress bar's data.
0174                changeListener = getHandler();
0175                progressBar.addChangeListener(changeListener);
0176
0177                //Listen for changes between determinate and indeterminate state.
0178                progressBar.addPropertyChangeListener(getHandler());
0179            }
0180
0181            private Handler getHandler() {
0182                if (handler == null) {
0183                    handler = new Handler();
0184                }
0185                return handler;
0186            }
0187
0188            /**
0189             * Starts the animation thread, creating and initializing
0190             * it if necessary. This method is invoked when an
0191             * indeterminate progress bar should start animating.
0192             * Reasons for this may include:
0193             * <ul>
0194             *    <li>The progress bar is determinate and becomes displayable
0195             *    <li>The progress bar is displayable and becomes determinate
0196             *    <li>The progress bar is displayable and determinate and this
0197             *        UI is installed
0198             * </ul>
0199             * If you implement your own animation thread,
0200             * you must override this method.
0201             *
0202             * @since 1.4
0203             * @see #stopAnimationTimer
0204             */
0205            protected void startAnimationTimer() {
0206                if (animator == null) {
0207                    animator = new Animator();
0208                }
0209
0210                animator.start(getRepaintInterval());
0211            }
0212
0213            /**
0214             * Stops the animation thread.
0215             * This method is invoked when the indeterminate
0216             * animation should be stopped. Reasons for this may include:
0217             * <ul>
0218             *    <li>The progress bar changes to determinate
0219             *    <li>The progress bar is no longer part of a displayable hierarchy
0220             *    <li>This UI in uninstalled
0221             * </ul>
0222             * If you implement your own animation thread,
0223             * you must override this method.
0224             *
0225             * @since 1.4
0226             * @see #startAnimationTimer
0227             */
0228            protected void stopAnimationTimer() {
0229                if (animator != null) {
0230                    animator.stop();
0231                }
0232            }
0233
0234            /**
0235             * Removes all listeners installed by this object.
0236             */
0237            protected void uninstallListeners() {
0238                progressBar.removeChangeListener(changeListener);
0239                progressBar.removePropertyChangeListener(getHandler());
0240                handler = null;
0241            }
0242
0243            /**
0244             * Returns the baseline.
0245             *
0246             * @throws NullPointerException {@inheritDoc}
0247             * @throws IllegalArgumentException {@inheritDoc}
0248             * @see javax.swing.JComponent#getBaseline(int, int)
0249             * @since 1.6
0250             */
0251            public int getBaseline(JComponent c, int width, int height) {
0252                super .getBaseline(c, width, height);
0253                if (progressBar.isStringPainted()
0254                        && progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0255                    FontMetrics metrics = progressBar
0256                            .getFontMetrics(progressBar.getFont());
0257                    Insets insets = progressBar.getInsets();
0258                    int y = insets.top;
0259                    height = height - insets.top - insets.bottom;
0260                    return y
0261                            + (height + metrics.getAscent()
0262                                    - metrics.getLeading() - metrics
0263                                    .getDescent()) / 2;
0264                }
0265                return -1;
0266            }
0267
0268            /**
0269             * Returns an enum indicating how the baseline of the component
0270             * changes as the size changes.
0271             *
0272             * @throws NullPointerException {@inheritDoc}
0273             * @see javax.swing.JComponent#getBaseline(int, int)
0274             * @since 1.6
0275             */
0276            public Component.BaselineResizeBehavior getBaselineResizeBehavior(
0277                    JComponent c) {
0278                super .getBaselineResizeBehavior(c);
0279                if (progressBar.isStringPainted()
0280                        && progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0281                    return Component.BaselineResizeBehavior.CENTER_OFFSET;
0282                }
0283                return Component.BaselineResizeBehavior.OTHER;
0284            }
0285
0286            // Many of the Basic*UI components have the following methods.
0287            // This component does not have these methods because *ProgressBarUI
0288            //  is not a compound component and does not accept input.
0289            //
0290            // protected void installComponents()
0291            // protected void uninstallComponents()
0292            // protected void installKeyboardActions()
0293            // protected void uninstallKeyboardActions()
0294
0295            protected Dimension getPreferredInnerHorizontal() {
0296                Dimension horizDim = (Dimension) DefaultLookup.get(progressBar,
0297                        this , "ProgressBar.horizontalSize");
0298                if (horizDim == null) {
0299                    horizDim = new Dimension(146, 12);
0300                }
0301                return horizDim;
0302            }
0303
0304            protected Dimension getPreferredInnerVertical() {
0305                Dimension vertDim = (Dimension) DefaultLookup.get(progressBar,
0306                        this , "ProgressBar.verticalSize");
0307                if (vertDim == null) {
0308                    vertDim = new Dimension(12, 146);
0309                }
0310                return vertDim;
0311            }
0312
0313            /**
0314             * The "selectionForeground" is the color of the text when it is painted
0315             * over a filled area of the progress bar.
0316             */
0317            protected Color getSelectionForeground() {
0318                return selectionForeground;
0319            }
0320
0321            /**
0322             * The "selectionBackground" is the color of the text when it is painted
0323             * over an unfilled area of the progress bar.
0324             */
0325            protected Color getSelectionBackground() {
0326                return selectionBackground;
0327            }
0328
0329            private int getCachedPercent() {
0330                return cachedPercent;
0331            }
0332
0333            private void setCachedPercent(int cachedPercent) {
0334                this .cachedPercent = cachedPercent;
0335            }
0336
0337            /**
0338             * Returns the width (if HORIZONTAL) or height (if VERTICAL)
0339             * of each of the indivdual cells/units to be rendered in the
0340             * progress bar. However, for text rendering simplification and 
0341             * aesthetic considerations, this function will return 1 when
0342             * the progress string is being rendered.
0343             *
0344             * @return the value representing the spacing between cells
0345             * @see    #setCellLength
0346             * @see    JProgressBar#isStringPainted
0347             */
0348            protected int getCellLength() {
0349                if (progressBar.isStringPainted()) {
0350                    return 1;
0351                } else {
0352                    return cellLength;
0353                }
0354            }
0355
0356            protected void setCellLength(int cellLen) {
0357                this .cellLength = cellLen;
0358            }
0359
0360            /**
0361             * Returns the spacing between each of the cells/units in the
0362             * progress bar. However, for text rendering simplification and 
0363             * aesthetic considerations, this function will return 0 when
0364             * the progress string is being rendered.
0365             *
0366             * @return the value representing the spacing between cells
0367             * @see    #setCellSpacing
0368             * @see    JProgressBar#isStringPainted
0369             */
0370            protected int getCellSpacing() {
0371                if (progressBar.isStringPainted()) {
0372                    return 0;
0373                } else {
0374                    return cellSpacing;
0375                }
0376            }
0377
0378            protected void setCellSpacing(int cellSpace) {
0379                this .cellSpacing = cellSpace;
0380            }
0381
0382            /**
0383             * This determines the amount of the progress bar that should be filled
0384             * based on the percent done gathered from the model. This is a common
0385             * operation so it was abstracted out. It assumes that your progress bar
0386             * is linear. That is, if you are making a circular progress indicator,
0387             * you will want to override this method.
0388             */
0389            protected int getAmountFull(Insets b, int width, int height) {
0390                int amountFull = 0;
0391                BoundedRangeModel model = progressBar.getModel();
0392
0393                if ((model.getMaximum() - model.getMinimum()) != 0) {
0394                    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0395                        amountFull = (int) Math.round(width
0396                                * progressBar.getPercentComplete());
0397                    } else {
0398                        amountFull = (int) Math.round(height
0399                                * progressBar.getPercentComplete());
0400                    }
0401                }
0402                return amountFull;
0403            }
0404
0405            /**
0406             * Delegates painting to one of two methods:
0407             * paintDeterminate or paintIndeterminate.
0408             */
0409            public void paint(Graphics g, JComponent c) {
0410                if (progressBar.isIndeterminate()) {
0411                    paintIndeterminate(g, c);
0412                } else {
0413                    paintDeterminate(g, c);
0414                }
0415            }
0416
0417            /**
0418             * Stores the position and size of
0419             * the bouncing box that would be painted for the current animation index
0420             * in <code>r</code> and returns <code>r</code>.
0421             * Subclasses that add to the painting performed
0422             * in this class's implementation of <code>paintIndeterminate</code> --
0423             * to draw an outline around the bouncing box, for example --
0424             * can use this method to get the location of the bouncing
0425             * box that was just painted.
0426             * By overriding this method,
0427             * you have complete control over the size and position 
0428             * of the bouncing box,
0429             * without having to reimplement <code>paintIndeterminate</code>.
0430             *
0431             * @param r  the Rectangle instance to be modified;
0432             *           may be <code>null</code>
0433             * @return   <code>null</code> if no box should be drawn;
0434             *           otherwise, returns the passed-in rectangle
0435             *           (if non-null)
0436             *           or a new rectangle
0437             *
0438             * @see #setAnimationIndex
0439             * @since 1.4
0440             */
0441            protected Rectangle getBox(Rectangle r) {
0442                int currentFrame = getAnimationIndex();
0443                int middleFrame = numFrames / 2;
0444
0445                if (sizeChanged() || delta == 0.0 || maxPosition == 0.0) {
0446                    updateSizes();
0447                }
0448
0449                r = getGenericBox(r);
0450
0451                if (r == null) {
0452                    return null;
0453                }
0454                if (middleFrame <= 0) {
0455                    return null;
0456                }
0457
0458                //assert currentFrame >= 0 && currentFrame < numFrames
0459                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0460                    if (currentFrame < middleFrame) {
0461                        r.x = componentInnards.x
0462                                + (int) Math.round(delta
0463                                        * (double) currentFrame);
0464                    } else {
0465                        r.x = maxPosition
0466                                - (int) Math.round(delta
0467                                        * (currentFrame - middleFrame));
0468                    }
0469                } else { //VERTICAL indeterminate progress bar
0470                    if (currentFrame < middleFrame) {
0471                        r.y = componentInnards.y
0472                                + (int) Math.round(delta * currentFrame);
0473                    } else {
0474                        r.y = maxPosition
0475                                - (int) Math.round(delta
0476                                        * (currentFrame - middleFrame));
0477                    }
0478                }
0479                return r;
0480            }
0481
0482            /**
0483             * Updates delta, max position.
0484             * Assumes componentInnards is correct (e.g. call after sizeChanged()).
0485             */
0486            private void updateSizes() {
0487                int length = 0;
0488
0489                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0490                    length = getBoxLength(componentInnards.width,
0491                            componentInnards.height);
0492                    maxPosition = componentInnards.x + componentInnards.width
0493                            - length;
0494
0495                } else { //VERTICAL progress bar
0496                    length = getBoxLength(componentInnards.height,
0497                            componentInnards.width);
0498                    maxPosition = componentInnards.y + componentInnards.height
0499                            - length;
0500                }
0501
0502                //If we're doing bouncing-box animation, update delta.
0503                delta = 2.0 * (double) maxPosition / (double) numFrames;
0504            }
0505
0506            /**
0507             * Assumes that the component innards, max position, etc. are up-to-date.
0508             */
0509            private Rectangle getGenericBox(Rectangle r) {
0510                if (r == null) {
0511                    r = new Rectangle();
0512                }
0513
0514                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0515                    r.width = getBoxLength(componentInnards.width,
0516                            componentInnards.height);
0517                    if (r.width < 0) {
0518                        r = null;
0519                    } else {
0520                        r.height = componentInnards.height;
0521                        r.y = componentInnards.y;
0522                    }
0523                    // end of HORIZONTAL
0524
0525                } else { //VERTICAL progress bar
0526                    r.height = getBoxLength(componentInnards.height,
0527                            componentInnards.width);
0528                    if (r.height < 0) {
0529                        r = null;
0530                    } else {
0531                        r.width = componentInnards.width;
0532                        r.x = componentInnards.x;
0533                    }
0534                } // end of VERTICAL
0535
0536                return r;
0537            }
0538
0539            /**
0540             * Returns the length
0541             * of the "bouncing box" to be painted.
0542             * This method is invoked by the 
0543             * default implementation of <code>paintIndeterminate</code>
0544             * to get the width (if the progress bar is horizontal)
0545             * or height (if vertical) of the box.
0546             * For example:
0547             * <blockquote>
0548             * <pre>
0549             *boxRect.width = getBoxLength(componentInnards.width,
0550             *                             componentInnards.height);
0551             * </pre>
0552             * </blockquote>
0553             *
0554             * @param availableLength  the amount of space available
0555             *                         for the bouncing box to move in;
0556             *                         for a horizontal progress bar,
0557             *                         for example,
0558             *                         this should be
0559             *                         the inside width of the progress bar
0560             *                         (the component width minus borders)
0561             * @param otherDimension   for a horizontal progress bar, this should be
0562             *                         the inside height of the progress bar; this
0563             *                         value might be used to constrain or determine
0564             *                         the return value 
0565             *
0566             * @return the size of the box dimension being determined; 
0567             *         must be no larger than <code>availableLength</code>
0568             *
0569             * @see javax.swing.SwingUtilities#calculateInnerArea
0570             * @since 1.5
0571             */
0572            protected int getBoxLength(int availableLength, int otherDimension) {
0573                return (int) Math.round(availableLength / 6.0);
0574            }
0575
0576            /**
0577             * All purpose paint method that should do the right thing for all
0578             * linear bouncing-box progress bars. 
0579             * Override this if you are making another kind of 
0580             * progress bar.
0581             *
0582             * @see #paintDeterminate
0583             *
0584             * @since 1.4
0585             */
0586            protected void paintIndeterminate(Graphics g, JComponent c) {
0587                if (!(g instanceof  Graphics2D)) {
0588                    return;
0589                }
0590
0591                Insets b = progressBar.getInsets(); // area for border
0592                int barRectWidth = progressBar.getWidth() - (b.right + b.left);
0593                int barRectHeight = progressBar.getHeight()
0594                        - (b.top + b.bottom);
0595
0596                if (barRectWidth <= 0 || barRectHeight <= 0) {
0597                    return;
0598                }
0599
0600                Graphics2D g2 = (Graphics2D) g;
0601
0602                // Paint the bouncing box.
0603                boxRect = getBox(boxRect);
0604                if (boxRect != null) {
0605                    g2.setColor(progressBar.getForeground());
0606                    g2.fillRect(boxRect.x, boxRect.y, boxRect.width,
0607                            boxRect.height);
0608                }
0609
0610                // Deal with possible text painting
0611                if (progressBar.isStringPainted()) {
0612                    if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0613                        paintString(g2, b.left, b.top, barRectWidth,
0614                                barRectHeight, boxRect.x, boxRect.width, b);
0615                    } else {
0616                        paintString(g2, b.left, b.top, barRectWidth,
0617                                barRectHeight, boxRect.y, boxRect.height, b);
0618                    }
0619                }
0620            }
0621
0622            /**
0623             * All purpose paint method that should do the right thing for almost
0624             * all linear, determinate progress bars. By setting a few values in
0625             * the defaults
0626             * table, things should work just fine to paint your progress bar.
0627             * Naturally, override this if you are making a circular or
0628             * semi-circular progress bar.
0629             * 
0630             * @see #paintIndeterminate
0631             *
0632             * @since 1.4
0633             */
0634            protected void paintDeterminate(Graphics g, JComponent c) {
0635                if (!(g instanceof  Graphics2D)) {
0636                    return;
0637                }
0638
0639                Insets b = progressBar.getInsets(); // area for border
0640                int barRectWidth = progressBar.getWidth() - (b.right + b.left);
0641                int barRectHeight = progressBar.getHeight()
0642                        - (b.top + b.bottom);
0643
0644                if (barRectWidth <= 0 || barRectHeight <= 0) {
0645                    return;
0646                }
0647
0648                int cellLength = getCellLength();
0649                int cellSpacing = getCellSpacing();
0650                // amount of progress to draw
0651                int amountFull = getAmountFull(b, barRectWidth, barRectHeight);
0652
0653                Graphics2D g2 = (Graphics2D) g;
0654                g2.setColor(progressBar.getForeground());
0655
0656                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0657                    // draw the cells
0658                    if (cellSpacing == 0 && amountFull > 0) {
0659                        // draw one big Rect because there is no space between cells
0660                        g2.setStroke(new BasicStroke((float) barRectHeight,
0661                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
0662                    } else {
0663                        // draw each individual cell
0664                        g2.setStroke(new BasicStroke((float) barRectHeight,
0665                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
0666                                0.f, new float[] { cellLength, cellSpacing },
0667                                0.f));
0668                    }
0669
0670                    if (BasicGraphicsUtils.isLeftToRight(c)) {
0671                        g2.drawLine(b.left, (barRectHeight / 2) + b.top,
0672                                amountFull + b.left, (barRectHeight / 2)
0673                                        + b.top);
0674                    } else {
0675                        g2.drawLine((barRectWidth + b.left),
0676                                (barRectHeight / 2) + b.top, barRectWidth
0677                                        + b.left - amountFull,
0678                                (barRectHeight / 2) + b.top);
0679                    }
0680
0681                } else { // VERTICAL
0682                    // draw the cells
0683                    if (cellSpacing == 0 && amountFull > 0) {
0684                        // draw one big Rect because there is no space between cells
0685                        g2.setStroke(new BasicStroke((float) barRectWidth,
0686                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
0687                    } else {
0688                        // draw each individual cell
0689                        g2
0690                                .setStroke(new BasicStroke(
0691                                        (float) barRectWidth,
0692                                        BasicStroke.CAP_BUTT,
0693                                        BasicStroke.JOIN_BEVEL,
0694                                        0f,
0695                                        new float[] { cellLength, cellSpacing },
0696                                        0f));
0697                    }
0698
0699                    g2.drawLine(barRectWidth / 2 + b.left, b.top
0700                            + barRectHeight, barRectWidth / 2 + b.left, b.top
0701                            + barRectHeight - amountFull);
0702                }
0703
0704                // Deal with possible text painting
0705                if (progressBar.isStringPainted()) {
0706                    paintString(g, b.left, b.top, barRectWidth, barRectHeight,
0707                            amountFull, b);
0708                }
0709            }
0710
0711            protected void paintString(Graphics g, int x, int y, int width,
0712                    int height, int amountFull, Insets b) {
0713                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0714                    if (BasicGraphicsUtils.isLeftToRight(progressBar)) {
0715                        if (progressBar.isIndeterminate()) {
0716                            boxRect = getBox(boxRect);
0717                            paintString(g, x, y, width, height, boxRect.x,
0718                                    boxRect.width, b);
0719                        } else {
0720                            paintString(g, x, y, width, height, x, amountFull,
0721                                    b);
0722                        }
0723                    } else {
0724                        paintString(g, x, y, width, height, x + width
0725                                - amountFull, amountFull, b);
0726                    }
0727                } else {
0728                    if (progressBar.isIndeterminate()) {
0729                        boxRect = getBox(boxRect);
0730                        paintString(g, x, y, width, height, boxRect.y,
0731                                boxRect.height, b);
0732                    } else {
0733                        paintString(g, x, y, width, height, y + height
0734                                - amountFull, amountFull, b);
0735                    }
0736                }
0737            }
0738
0739            /**
0740             * Paints the progress string.
0741             *
0742             * @param g Graphics used for drawing.
0743             * @param x x location of bounding box
0744             * @param y y location of bounding box
0745             * @param width width of bounding box
0746             * @param height height of bounding box
0747             * @param fillStart start location, in x or y depending on orientation,
0748             *        of the filled portion of the progress bar.
0749             * @param amountFull size of the fill region, either width or height
0750             *        depending upon orientation.
0751             * @param b Insets of the progress bar.
0752             */
0753            private void paintString(Graphics g, int x, int y, int width,
0754                    int height, int fillStart, int amountFull, Insets b) {
0755                if (!(g instanceof  Graphics2D)) {
0756                    return;
0757                }
0758
0759                Graphics2D g2 = (Graphics2D) g;
0760                String progressString = progressBar.getString();
0761                g2.setFont(progressBar.getFont());
0762                Point renderLocation = getStringPlacement(g2, progressString,
0763                        x, y, width, height);
0764                Rectangle oldClip = g2.getClipBounds();
0765
0766                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0767                    g2.setColor(getSelectionBackground());
0768                    SwingUtilities2.drawString(progressBar, g2, progressString,
0769                            renderLocation.x, renderLocation.y);
0770                    g2.setColor(getSelectionForeground());
0771                    g2.clipRect(fillStart, y, amountFull, height);
0772                    SwingUtilities2.drawString(progressBar, g2, progressString,
0773                            renderLocation.x, renderLocation.y);
0774                } else { // VERTICAL
0775                    g2.setColor(getSelectionBackground());
0776                    AffineTransform rotate = AffineTransform
0777                            .getRotateInstance(Math.PI / 2);
0778                    g2.setFont(progressBar.getFont().deriveFont(rotate));
0779                    renderLocation = getStringPlacement(g2, progressString, x,
0780                            y, width, height);
0781                    SwingUtilities2.drawString(progressBar, g2, progressString,
0782                            renderLocation.x, renderLocation.y);
0783                    g2.setColor(getSelectionForeground());
0784                    g2.clipRect(x, fillStart, width, amountFull);
0785                    SwingUtilities2.drawString(progressBar, g2, progressString,
0786                            renderLocation.x, renderLocation.y);
0787                }
0788                g2.setClip(oldClip);
0789            }
0790
0791            /**
0792             * Designate the place where the progress string will be painted.
0793             * This implementation places it at the center of the progress
0794             * bar (in both x and y). Override this if you want to right,
0795             * left, top, or bottom align the progress string or if you need
0796             * to nudge it around for any reason.
0797             */
0798            protected Point getStringPlacement(Graphics g,
0799                    String progressString, int x, int y, int width, int height) {
0800                FontMetrics fontSizer = SwingUtilities2.getFontMetrics(
0801                        progressBar, g, progressBar.getFont());
0802                int stringWidth = SwingUtilities2.stringWidth(progressBar,
0803                        fontSizer, progressString);
0804
0805                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0806                    return new Point(x
0807                            + Math.round(width / 2 - stringWidth / 2), y
0808                            + ((height + fontSizer.getAscent()
0809                                    - fontSizer.getLeading() - fontSizer
0810                                    .getDescent()) / 2));
0811                } else { // VERTICAL
0812                    return new Point(x
0813                            + ((width - fontSizer.getAscent()
0814                                    + fontSizer.getLeading() + fontSizer
0815                                    .getDescent()) / 2), y
0816                            + Math.round(height / 2 - stringWidth / 2));
0817                }
0818            }
0819
0820            public Dimension getPreferredSize(JComponent c) {
0821                Dimension size;
0822                Insets border = progressBar.getInsets();
0823                FontMetrics fontSizer = progressBar.getFontMetrics(progressBar
0824                        .getFont());
0825
0826                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0827                    size = new Dimension(getPreferredInnerHorizontal());
0828                    // Ensure that the progress string will fit
0829                    if (progressBar.isStringPainted()) {
0830                        // I'm doing this for completeness.
0831                        String progString = progressBar.getString();
0832                        int stringWidth = SwingUtilities2.stringWidth(
0833                                progressBar, fontSizer, progString);
0834                        if (stringWidth > size.width) {
0835                            size.width = stringWidth;
0836                        }
0837                        // This uses both Height and Descent to be sure that 
0838                        // there is more than enough room in the progress bar
0839                        // for everything.
0840                        // This does have a strange dependency on 
0841                        // getStringPlacememnt() in a funny way.
0842                        int stringHeight = fontSizer.getHeight()
0843                                + fontSizer.getDescent();
0844                        if (stringHeight > size.height) {
0845                            size.height = stringHeight;
0846                        }
0847                    }
0848                } else {
0849                    size = new Dimension(getPreferredInnerVertical());
0850                    // Ensure that the progress string will fit.
0851                    if (progressBar.isStringPainted()) {
0852                        String progString = progressBar.getString();
0853                        int stringHeight = fontSizer.getHeight()
0854                                + fontSizer.getDescent();
0855                        if (stringHeight > size.width) {
0856                            size.width = stringHeight;
0857                        }
0858                        // This is also for completeness.
0859                        int stringWidth = SwingUtilities2.stringWidth(
0860                                progressBar, fontSizer, progString);
0861                        if (stringWidth > size.height) {
0862                            size.height = stringWidth;
0863                        }
0864                    }
0865                }
0866
0867                size.width += border.left + border.right;
0868                size.height += border.top + border.bottom;
0869                return size;
0870            }
0871
0872            /**
0873             * The Minimum size for this component is 10. The rationale here 
0874             * is that there should be at least one pixel per 10 percent.
0875             */
0876            public Dimension getMinimumSize(JComponent c) {
0877                Dimension pref = getPreferredSize(progressBar);
0878                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0879                    pref.width = 10;
0880                } else {
0881                    pref.height = 10;
0882                }
0883                return pref;
0884            }
0885
0886            public Dimension getMaximumSize(JComponent c) {
0887                Dimension pref = getPreferredSize(progressBar);
0888                if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
0889                    pref.width = Short.MAX_VALUE;
0890                } else {
0891                    pref.height = Short.MAX_VALUE;
0892                }
0893                return pref;
0894            }
0895
0896            /**
0897             * Gets the index of the current animation frame.
0898             *
0899             * @since 1.4
0900             */
0901            protected int getAnimationIndex() {
0902                return animationIndex;
0903            }
0904
0905            /**
0906             * Returns the number of frames for the complete animation loop
0907             * used by an indeterminate JProgessBar. The progress chunk will go
0908             * from one end to the other and back during the entire loop. This
0909             * visual behavior may be changed by subclasses in other Look and Feels.
0910             * 
0911             * @return the number of frames
0912             * @since 1.6
0913             */
0914            protected final int getFrameCount() {
0915                return numFrames;
0916            }
0917
0918            /**
0919             * Sets the index of the current animation frame
0920             * to the specified value and requests that the
0921             * progress bar be repainted.
0922             * Subclasses that don't use the default painting code
0923             * might need to override this method
0924             * to change the way that the <code>repaint</code> method
0925             * is invoked.
0926             *
0927             * @param newValue the new animation index; no checking
0928             *                 is performed on its value
0929             * @see #incrementAnimationIndex
0930             *
0931             * @since 1.4
0932             */
0933            protected void setAnimationIndex(int newValue) {
0934                if (animationIndex != newValue) {
0935                    if (sizeChanged()) {
0936                        animationIndex = newValue;
0937                        maxPosition = 0; //needs to be recalculated
0938                        delta = 0.0; //needs to be recalculated
0939                        progressBar.repaint();
0940                        return;
0941                    }
0942
0943                    //Get the previous box drawn.
0944                    nextPaintRect = getBox(nextPaintRect);
0945
0946                    //Update the frame number.
0947                    animationIndex = newValue;
0948
0949                    //Get the next box to draw.
0950                    if (nextPaintRect != null) {
0951                        boxRect = getBox(boxRect);
0952                        if (boxRect != null) {
0953                            nextPaintRect.add(boxRect);
0954                        }
0955                    }
0956                } else { //animationIndex == newValue
0957                    return;
0958                }
0959
0960                if (nextPaintRect != null) {
0961                    progressBar.repaint(nextPaintRect);
0962                } else {
0963                    progressBar.repaint();
0964                }
0965            }
0966
0967            private boolean sizeChanged() {
0968                if ((oldComponentInnards == null) || (componentInnards == null)) {
0969                    return true;
0970                }
0971
0972                oldComponentInnards.setRect(componentInnards);
0973                componentInnards = SwingUtilities.calculateInnerArea(
0974                        progressBar, componentInnards);
0975                return !oldComponentInnards.equals(componentInnards);
0976            }
0977
0978            /**
0979             * Sets the index of the current animation frame,
0980             * to the next valid value,
0981             * which results in the progress bar being repainted.
0982             * The next valid value is, by default,
0983             * the current animation index plus one.
0984             * If the new value would be too large, 
0985             * this method sets the index to 0.
0986             * Subclasses might need to override this method
0987             * to ensure that the index does not go over
0988             * the number of frames needed for the particular 
0989             * progress bar instance.
0990             * This method is invoked by the default animation thread
0991             * every <em>X</em> milliseconds, 
0992             * where <em>X</em> is specified by the "ProgressBar.repaintInterval"
0993             * UI default.
0994             *
0995             * @see #setAnimationIndex
0996             * @since 1.4
0997             */
0998            protected void incrementAnimationIndex() {
0999                int newValue = getAnimationIndex() + 1;
1000
1001                if (newValue < numFrames) {
1002                    setAnimationIndex(newValue);
1003                } else {
1004                    setAnimationIndex(0);
1005                }
1006            }
1007
1008            /**
1009             * Returns the desired number of milliseconds between repaints.
1010             * This value is meaningful
1011             * only if the progress bar is in indeterminate mode.
1012             * The repaint interval determines how often the 
1013             * default animation thread's timer is fired.
1014             * It's also used by the default indeterminate progress bar
1015             * painting code when determining
1016             * how far to move the bouncing box per frame.
1017             * The repaint interval is specified by
1018             * the "ProgressBar.repaintInterval" UI default.
1019             * 
1020             * @return  the repaint interval, in milliseconds
1021             */
1022            private int getRepaintInterval() {
1023                return repaintInterval;
1024            }
1025
1026            private int initRepaintInterval() {
1027                repaintInterval = DefaultLookup.getInt(progressBar, this ,
1028                        "ProgressBar.repaintInterval", 50);
1029                return repaintInterval;
1030            }
1031
1032            /**
1033             * Returns the number of milliseconds per animation cycle.
1034             * This value is meaningful
1035             * only if the progress bar is in indeterminate mode.
1036             * The cycle time is used by the default indeterminate progress bar
1037             * painting code when determining
1038             * how far to move the bouncing box per frame.
1039             * The cycle time is specified by
1040             * the "ProgressBar.cycleTime" UI default
1041             * and adjusted, if necessary,
1042             * by the initIndeterminateDefaults method.
1043             * 
1044             * @return  the cycle time, in milliseconds
1045             */
1046            private int getCycleTime() {
1047                return cycleTime;
1048            }
1049
1050            private int initCycleTime() {
1051                cycleTime = DefaultLookup.getInt(progressBar, this ,
1052                        "ProgressBar.cycleTime", 3000);
1053                return cycleTime;
1054            }
1055
1056            /** Initialize cycleTime, repaintInterval, numFrames, animationIndex. */
1057            private void initIndeterminateDefaults() {
1058                initRepaintInterval(); //initialize repaint interval
1059                initCycleTime(); //initialize cycle length
1060
1061                // Make sure repaintInterval is reasonable.
1062                if (repaintInterval <= 0) {
1063                    repaintInterval = 100;
1064                }
1065
1066                // Make sure cycleTime is reasonable.
1067                if (repaintInterval > cycleTime) {
1068                    cycleTime = repaintInterval * 20;
1069                } else {
1070                    // Force cycleTime to be a even multiple of repaintInterval.
1071                    int factor = (int) Math.ceil(((double) cycleTime)
1072                            / ((double) repaintInterval * 2));
1073                    cycleTime = repaintInterval * factor * 2;
1074                }
1075            }
1076
1077            /**
1078             * Invoked by PropertyChangeHandler.
1079             *
1080             *  NOTE: This might not be invoked until after the first
1081             *  paintIndeterminate call.
1082             */
1083            private void initIndeterminateValues() {
1084                initIndeterminateDefaults();
1085                //assert cycleTime/repaintInterval is a whole multiple of 2.
1086                numFrames = cycleTime / repaintInterval;
1087                initAnimationIndex();
1088
1089                boxRect = new Rectangle();
1090                nextPaintRect = new Rectangle();
1091                componentInnards = new Rectangle();
1092                oldComponentInnards = new Rectangle();
1093
1094                // we only bother installing the HierarchyChangeListener if we
1095                // are indeterminate
1096                progressBar.addHierarchyListener(getHandler());
1097
1098                // start the animation thread if necessary
1099                if (progressBar.isDisplayable()) {
1100                    startAnimationTimer();
1101                }
1102            }
1103
1104            /** Invoked by PropertyChangeHandler. */
1105            private void cleanUpIndeterminateValues() {
1106                // stop the animation thread if necessary
1107                if (progressBar.isDisplayable()) {
1108                    stopAnimationTimer();
1109                }
1110
1111                cycleTime = repaintInterval = 0;
1112                numFrames = animationIndex = 0;
1113                maxPosition = 0;
1114                delta = 0.0;
1115
1116                boxRect = nextPaintRect = null;
1117                componentInnards = oldComponentInnards = null;
1118
1119                progressBar.removeHierarchyListener(getHandler());
1120            }
1121
1122            // Called from initIndeterminateValues to initialize the animation index.
1123            // This assumes that numFrames is set to a correct value.
1124            private void initAnimationIndex() {
1125                if ((progressBar.getOrientation() == JProgressBar.HORIZONTAL)
1126                        && (BasicGraphicsUtils.isLeftToRight(progressBar))) {
1127                    // If this is a left-to-right progress bar,
1128                    // start at the first frame.
1129                    setAnimationIndex(0);
1130                } else {
1131                    // If we go right-to-left or vertically, start at the right/bottom.
1132                    setAnimationIndex(numFrames / 2);
1133                }
1134            }
1135
1136            //
1137            // Animation Thread
1138            //
1139            /**
1140             * Implements an animation thread that invokes repaint
1141             * at a fixed rate.  If ADJUSTTIMER is true, this thread
1142             * will continuously adjust the repaint interval to 
1143             * try to make the actual time between repaints match
1144             * the requested rate.  
1145             */
1146            private class Animator implements  ActionListener {
1147                private Timer timer;
1148                private long previousDelay; //used to tune the repaint interval
1149                private int interval; //the fixed repaint interval
1150                private long lastCall; //the last time actionPerformed was called
1151                private int MINIMUM_DELAY = 5;
1152
1153                /**
1154                 * Creates a timer if one doesn't already exist, 
1155                 * then starts the timer thread.
1156                 */
1157                private void start(int interval) {
1158                    previousDelay = interval;
1159                    lastCall = 0;
1160
1161                    if (timer == null) {
1162                        timer = new Timer(interval, this );
1163                    } else {
1164                        timer.setDelay(interval);
1165                    }
1166
1167                    if (ADJUSTTIMER) {
1168                        timer.setRepeats(false);
1169                        timer.setCoalesce(false);
1170                    }
1171
1172                    timer.start();
1173                }
1174
1175                /**
1176                 * Stops the timer thread.
1177                 */
1178                private void stop() {
1179                    timer.stop();
1180                }
1181
1182                /**
1183                 * Reacts to the timer's action events.
1184                 */
1185                public void actionPerformed(ActionEvent e) {
1186                    if (ADJUSTTIMER) {
1187                        long time = System.currentTimeMillis();
1188
1189                        if (lastCall > 0) { //adjust nextDelay
1190                            //XXX maybe should cache this after a while
1191                            //actual = time - lastCall
1192                            //difference = actual - interval
1193                            //nextDelay = previousDelay - difference
1194                            //          = previousDelay - (time - lastCall - interval)
1195                            int nextDelay = (int) (previousDelay - time
1196                                    + lastCall + getRepaintInterval());
1197                            if (nextDelay < MINIMUM_DELAY) {
1198                                nextDelay = MINIMUM_DELAY;
1199                            }
1200                            timer.setInitialDelay(nextDelay);
1201                            previousDelay = nextDelay;
1202                        }
1203                        timer.start();
1204                        lastCall = time;
1205                    }
1206
1207                    incrementAnimationIndex(); //paint next frame
1208                }
1209            }
1210
1211            /**
1212             * This inner class is marked &quot;public&quot; due to a compiler bug.
1213             * This class should be treated as a &quot;protected&quot; inner class.
1214             * Instantiate it only within subclasses of BasicProgressBarUI.
1215             */
1216            public class ChangeHandler implements  ChangeListener {
1217                // NOTE: This class exists only for backward compatability. All
1218                // its functionality has been moved into Handler. If you need to add
1219                // new functionality add it to the Handler, but make sure this      
1220                // class calls into the Handler.
1221                public void stateChanged(ChangeEvent e) {
1222                    getHandler().stateChanged(e);
1223                }
1224            }
1225
1226            private class Handler implements  ChangeListener,
1227                    PropertyChangeListener, HierarchyListener {
1228                // ChangeListener
1229                public void stateChanged(ChangeEvent e) {
1230                    BoundedRangeModel model = progressBar.getModel();
1231                    int newRange = model.getMaximum() - model.getMinimum();
1232                    int newPercent;
1233                    int oldPercent = getCachedPercent();
1234
1235                    if (newRange > 0) {
1236                        newPercent = (int) ((100 * (long) model.getValue()) / newRange);
1237                    } else {
1238                        newPercent = 0;
1239                    }
1240
1241                    if (newPercent != oldPercent) {
1242                        setCachedPercent(newPercent);
1243                        progressBar.repaint();
1244                    }
1245                }
1246
1247                // PropertyChangeListener
1248                public void propertyChange(PropertyChangeEvent e) {
1249                    String prop = e.getPropertyName();
1250                    if ("indeterminate" == prop) {
1251                        if (progressBar.isIndeterminate()) {
1252                            initIndeterminateValues();
1253                        } else {
1254                            //clean up
1255                            cleanUpIndeterminateValues();
1256                        }
1257                        progressBar.repaint();
1258                    }
1259                }
1260
1261                // we don't want the animation to keep running if we're not displayable
1262                public void hierarchyChanged(HierarchyEvent he) {
1263                    if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
1264                        if (progressBar.isIndeterminate()) {
1265                            if (progressBar.isDisplayable()) {
1266                                startAnimationTimer();
1267                            } else {
1268                                stopAnimationTimer();
1269                            }
1270                        }
1271                    }
1272                }
1273            }
1274        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.