⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 progressbarui.java

📁 用于java swing的皮肤软件
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package com.digitprop.tonic;


import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;


/**	UI delegate for JProgressBars.
 * 
 * 	@author	Markus Fischer
 *
 *  	<p>This software is under the <a href="http://www.gnu.org/copyleft/lesser.html" target="_blank">GNU Lesser General Public License</a>
 */

/*
 * ------------------------------------------------------------------------
 * Copyright (C) 2004 Markus Fischer
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free 
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 * MA 02111-1307  USA
 * 
 * You can contact the author at:
 *    Markus Fischer
 *    www.digitprop.com
 *    info@digitprop.com
 * ------------------------------------------------------------------------
 */
public class ProgressBarUI extends BasicProgressBarUI
{
	private static final Dimension PREFERRED_INNER_HORIZONTAL=new Dimension(146,
																									12);
	private static final Dimension PREFERRED_INNER_VERTICAL=new Dimension(12, 146);

	//performance stuff
	private static boolean ADJUSTTIMER=true;   //makes a BIG difference;

	//make this false for
	//performance tests
	//debugging; PENDING (kwalrath): convert to logging API 
	private static boolean DEBUGALL=false;   //severe performance impact
	private static boolean DEBUGTIMER=false;   //severe performance impact
	private static boolean BASICDEBUG=false;

	//performance data collection
	private static boolean LOGSTATS=false;
	private int				  cachedPercent;
	private int				  cellLength;
	private int				  cellSpacing;

	// The "selectionForeground" is the color of the text when it is painted
	// over a filled area of the progress bar. The "selectionBackground"
	// is for the text over the unfilled progress bar area.
	private Color selectionForeground;

	// The "selectionForeground" is the color of the text when it is painted
	// over a filled area of the progress bar. The "selectionBackground"
	// is for the text over the unfilled progress bar area.
	private Color						 selectionBackground;
	private boolean					 isIndeterminate=false;
	private Animator					 animator;
	private PropertyChangeListener propertyListener;
	protected JProgressBar			 progressBar;
	protected ChangeListener		 changeListener;

	/**
	 * The current state of the indeterminate animation's cycle.
	 * 0, the initial value, means paint the first frame.
	 * When the progress bar is indeterminate and showing,
	 * the default animation thread updates this variable
	 * by invoking incrementAnimationIndex()
	 * every repaintInterval milliseconds.
	 */
	private int animationIndex=0;

	/**
	 * The number of frames per cycle. Under the default implementation,
	 * this depends on the cycleTime and repaintInterval.  It
	 * must be an even number for the default painting algorithm.  This
	 * value is set in the initIndeterminateValues method.
	 */
	private int numFrames;   //0 1|numFrames-1 ... numFrames/2

	/**
	 * Interval (in ms) between repaints of the indeterminate progress bar.
	 * The value of this method is set
	 * (every time the progress bar changes to indeterminate mode)
	 * using the
	 * "ProgressBar.repaintInterval" key in the defaults table.
	 */
	private int repaintInterval;

	/**
	 * The number of milliseconds until the animation cycle repeats.
	 * The value of this method is set
	 * (every time the progress bar changes to indeterminate mode)
	 * using the
	 * "ProgressBar.cycleTime" key in the defaults table.
	 */
	private int cycleTime;   //must be repaintInterval*2*aPositiveInteger
	private long startTime=0;
	private long lastLoopTime=0;
	private int numLoops=0;

	/**
	 * Used to hold the location and size of the bouncing box (returned
	 * by getBox) to be painted.
	 */
	private Rectangle boxRect;

	/**
	 * The rectangle to be updated the next time the
	 * animation thread calls repaint.  For bouncing-box
	 * animation this rect should include the union of
	 * the currently displayed box (which needs to be erased)
	 * and the box to be displayed next.
	 * This rectangle's values are set in
	 * the setAnimationIndex method.
	 */
	private Rectangle nextPaintRect;

	//cache


	/** The component's painting area, not including the border. */
	private Rectangle componentInnards;   //the current painting area
	private Rectangle oldComponentInnards;   //used to see if the size changed

	/** For bouncing-box animation, the change in position per frame. */
	private double delta=0.0;
	private int    maxPosition=0;   //maximum X (horiz) or Y box location


	/**	Creates and returns a UI delegate for the specified component */
	public static ComponentUI createUI(JComponent component)
	{
		return new ProgressBarUI();
	}


	/**	Installs the UI settings for the specified component */
	public void installUI(JComponent c)
	{
		progressBar=(JProgressBar)c;
		installDefaults();
		installListeners();
	}

	
	/**	Uninstalls the UI settings for the specified component */
	public void uninstallUI(JComponent c)
	{
		uninstallDefaults();
		uninstallListeners();
		stopAnimationTimer();
		progressBar=null;
	}


	protected void installDefaults()
	{
		progressBar.setOpaque(true);
		LookAndFeel.installBorder(progressBar, "ProgressBar.border");
		LookAndFeel.installColorsAndFont(progressBar, "ProgressBar.background",
													"ProgressBar.foreground",
													"ProgressBar.font");
		cellLength=UIManager.getInt("ProgressBar.cellLength");
		cellSpacing=UIManager.getInt("ProgressBar.cellSpacing");
		selectionForeground=UIManager.getColor("ProgressBar.selectionForeground");
		selectionBackground=UIManager.getColor("ProgressBar.selectionBackground");
	}


	protected void uninstallDefaults()
	{
		LookAndFeel.uninstallBorder(progressBar);
	}


	protected void installListeners()
	{
		//Listen for changes in the progress bar's data.
		changeListener=new ChangeHandler();
		progressBar.addChangeListener(changeListener);

		//Listen for changes between determinate and indeterminate state.
		propertyListener=new PropertyChangeHandler();
		progressBar.addPropertyChangeListener(propertyListener);
	}


	/**
	 * Starts the animation thread, creating and initializing
	 * it if necessary.  This method is invoked when
	 * the progress bar changes to indeterminate mode.
	 * If you implement your own animation thread,
	 * you must override this method.
	 *
	 * @since 1.4
	 */
	protected void startAnimationTimer()
	{
		if(animator==null)
		{
			animator=new Animator();
		}

		animator.start(getRepaintInterval());
	}


	/**
	 * Stops the animation thread.  This method is invoked when
	 * the progress bar changes from
	 * indeterminate to determinate mode
	 * and when this UI is uninstalled.
	 * If you implement your own animation thread,
	 * you must override this method.
	 *
	 * @since 1.4
	 */
	protected void stopAnimationTimer()
	{
		if(animator!=null)
		{
			animator.stop();
		}
	}


	/**
	 * Removes all listeners installed by this object.
	 */
	protected void uninstallListeners()
	{
		progressBar.removeChangeListener(changeListener);
		progressBar.removePropertyChangeListener(propertyListener);
	}


	// Many of the Basic*UI components have the following methods.
	// This component does not have these methods because *ProgressBarUI
	//  is not a compound component and does not accept input.
	//
	// protected void installComponents()
	// protected void uninstallComponents()
	// protected void installKeyboardActions()
	// protected void uninstallKeyboardActions()
	protected Dimension getPreferredInnerHorizontal()
	{
		return PREFERRED_INNER_HORIZONTAL;
	}


	protected Dimension getPreferredInnerVertical()
	{
		return PREFERRED_INNER_VERTICAL;
	}


	/**
	 * The "selectionForeground" is the color of the text when it is painted
	 * over a filled area of the progress bar.
	 */
	protected Color getSelectionForeground()
	{
		return selectionForeground;
	}


	/**
	 * The "selectionBackground" is the color of the text when it is painted
	 * over an unfilled area of the progress bar.
	 */
	protected Color getSelectionBackground()
	{
		return selectionBackground;
	}


	private int getCachedPercent()
	{
		return cachedPercent;
	}


	private void setCachedPercent(int cachedPercent)
	{
		this.cachedPercent=cachedPercent;
	}


	/**
	 * Returns the width (if HORIZONTAL) or height (if VERTICAL)
	 * of each of the indivdual cells/units to be rendered in the
	 * progress bar. However, for text rendering simplification and
	 * aesthetic considerations, this function will return 1 when
	 * the progress string is being rendered.
	 *
	 * @return the value representing the spacing between cells
	 * @see    #setCellLength
	 * @see    JProgressBar#isStringPainted
	 */
	protected int getCellLength()
	{
		if(progressBar.isStringPainted())
		{
			return 1;
		}
		else
		{
			return cellLength;
		}
	}


	protected void setCellLength(int cellLen)
	{
		this.cellLength=cellLen;
	}


	/**
	 * Returns the spacing between each of the cells/units in the
	 * progress bar. However, for text rendering simplification and
	 * aesthetic considerations, this function will return 0 when
	 * the progress string is being rendered.
	 *
	 * @return the value representing the spacing between cells
	 * @see    #setCellSpacing
	 * @see    JProgressBar#isStringPainted
	 */
	protected int getCellSpacing()
	{
		if(progressBar.isStringPainted())
		{
			return 0;
		}
		else
		{
			return cellSpacing;
		}
	}


	protected void setCellSpacing(int cellSpace)
	{
		this.cellSpacing=cellSpace;
	}


	/**
	 * This determines the amount of the progress bar that should be filled
	 * based on the percent done gathered from the model. This is a common
	 * operation so it was abstracted out. It assumes that your progress bar
	 * is linear. That is, if you are making a circular progress indicator,
	 * you will want to override this method.
	 */
	protected int getAmountFull(Insets b, int width, int height)
	{
		int				   amountFull=0;
		BoundedRangeModel model=progressBar.getModel();

		if((model.getMaximum()-model.getMinimum())!=0)
		{
			if(progressBar.getOrientation()==JProgressBar.HORIZONTAL)
			{
				amountFull=(int)Math.round(width*progressBar.getPercentComplete());
			}
			else
			{
				amountFull=(int)Math.round(height*progressBar.getPercentComplete());
			}
		}

		return amountFull;
	}


	/**	Paints the specified component */
	public void paint(Graphics g, JComponent c)
	{
		if(isIndeterminate)
		{
			paintIndeterminate(g, c);
		}
		else
		{
			paintDeterminate(g, c);
		}
	}


	/**
	 * Stores the position and size of
	 * the bouncing box that would be painted for the current animation index
	 * in <code>r</code> and returns <code>r</code>.
	 * Subclasses that add to the painting performed
	 * in this class's implementation of <code>paintIndeterminate</code> --
	 * to draw an outline around the bouncing box, for example --
	 * can use this method to get the location of the bouncing
	 * box that was just painted.
	 * By overriding this method,
	 * you have complete control over the size and position
	 * of the bouncing box,
	 * without having to reimplement <code>paintIndeterminate</code>.
	 *
	 * @param r  the Rectangle instance to be modified;
	 *           may be <code>null</code>
	 * @return   <code>null</code> if no box should be drawn;
	 *           otherwise, returns the passed-in rectangle
	 *           (if non-null)
	 *           or a new rectangle
	 *
	 * @see #setAnimationIndex
	 * @since 1.4
	 */
	protected Rectangle getBox(Rectangle r)
	{
		int currentFrame=getAnimationIndex();
		int middleFrame=numFrames/2;

		if(DEBUGALL)
		{
			System.out.println("----begin getBox----");
			System.out.println("    getBox argument: "+r);
			System.out.println("    currentFrame = "+currentFrame);
			System.out.println("    middleFrame = "+middleFrame);
		}

		if(sizeChanged() || delta==0.0 || maxPosition==0.0)
		{
			updateSizes();
		}

		r=getGenericBox(r);

		if(r==null)
		{
			if(DEBUGALL)
			{
				System.out.println("    Exiting because r is null");
			}

			return null;
		}
		if(middleFrame<=0)
		{
			if(DEBUGALL)
			{
				System.out.println("    Exiting because middleFrame <= 0.");
			}

			return null;
		}

		//assert currentFrame >= 0 && currentFrame < numFrames
		if(progressBar.getOrientation()==JProgressBar.HORIZONTAL)
		{
			if(currentFrame<middleFrame)
			{
				r.x=componentInnards.x+(int)Math.round(delta*(double)currentFrame);
			}
			else
			{
				r.x=maxPosition-(int)Math.round(delta*(currentFrame-middleFrame));
			}
		}
		else
		{   //VERTICAL indeterminate progress bar
			if(currentFrame<middleFrame)
			{
				r.y=componentInnards.y+(int)Math.round(delta*currentFrame);
			}
			else
			{
				r.y=maxPosition-(int)Math.round(delta*(currentFrame-middleFrame));
			}
		}

		if(DEBUGALL)
		{
			System.out.println("    getBox return value: "+r);
			System.out.println("----end getBox----");
		}

		return r;
	}


	/**
	 * Updates delta, max position.
	 * Assumes componentInnards is correct (e.g. call after sizeChanged()).
	 */
	private void updateSizes()
	{
		if(DEBUGALL)
		{
			System.out.println("----begin updateSizes----");
		}

		int length=0;

		if(progressBar.getOrientation()==JProgressBar.HORIZONTAL)
		{
			length=getBoxLength(componentInnards.width, componentInnards.height);
			maxPosition=componentInnards.x+componentInnards.width-length;
		}
		else
		{   //VERTICAL progress bar
			length=getBoxLength(componentInnards.height, componentInnards.width);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -