/**
* @author bret5
*/
package jmemorize.gui.swing.widgets;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
/**
* @author bret5 Copyright(C) 2007 bret5
*
* This class extends JProgressBar in order to show two values for progress,
* which are presumably related so that they can be shown on a stacked bar.
*
* The underlying data object, the BoundedRangeModel, already has a data member,
* extent, representing the length of an inner range, so all we have to do is
* expose methods for adjusting the value of extent and implement a paint method
* which paints the inner range in a separate color.
*
* The drawback to this painting implementation is that if isStringPainted, then
* the rectangle representing the extent paints over the text. - Workaround - if
* you want the the text to be visible through the extent rectangle, set the
* extentForeground to a partially transparent color. See the included main for
* an example.
*
* TODO - fixing this requires fully implementing paint (background, both
* rectangles, and the text in three colors).
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 1, or (at your option) any later version.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA.
*/
public class ExtentProgressBar extends JProgressBar
{
private Color extentForeground;
public void setExtent(int n)
{
getModel().setExtent(n);
repaint();
}
public int getExtent()
{
return getModel().getExtent();
}
/**
* Set the color used to paint the bar representing the extent value
*
* @param fg
*/
public void setExtentForeground(Color fg)
{
extentForeground = fg;
}
/**
* Get the color used to paint the extent value
*
* @return the color used to paint the extent value
*/
public Color getExtentForeground()
{
return extentForeground;
}
protected void paintComponent(Graphics g)
{
// first use the superclass to paint the bar
super.paintComponent(g);
Insets insets = getInsets();
// get the old color
Color oldColor = g.getColor();
// set the color
g.setColor(extentForeground);
// figure the bar
double value = getModel().getValue();
double extent = getModel().getExtent();
double maximum = getModel().getMaximum();
double minimum = getModel().getMinimum();
double outerRange = maximum - minimum;
int x = getX() + insets.left;
int y, w, h = 0;
int barHeight = getHeight() - (insets.top + insets.bottom);
int barWidth = getWidth() - (insets.left + insets.right);
if (getOrientation() == HORIZONTAL)
{
y = getY() + insets.top;
x += (int)(barWidth * (value / outerRange));
w = (int)(barWidth * (extent / outerRange));
h = barHeight;
}
else
{
// Vertical bars start at the bottom and go up
y = getY() + barHeight;
y -= (int)(barHeight * (value / outerRange));
h = (int)(barHeight * (extent / outerRange));
y -= h;
w = barWidth;
}
g.fillRect(x, y, w, h);
// reset the color
g.setColor(oldColor);
}
private static void createAndShowGUI()
{
// Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
// Create and set up the window.
JFrame frame = new JFrame("Demo ExtentProgressBar");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add the ubiquitous "Hello World" label.
final ExtentProgressBar bar = new ExtentProgressBar();
bar.setMinimum(0);
bar.setMaximum(10);
bar.setValue(3);
bar.setExtent(4);
Color grn = Color.GREEN.darker();
Color transparentGreen = new Color(grn.getRed(), grn.getGreen(), grn.getBlue(), 128);
bar.setForeground(Color.BLUE);
bar.setExtentForeground(transparentGreen);
bar.setString("Hello World");
bar.setStringPainted(true);
frame.getContentPane().add(bar);
frame.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent arg0)
{
switch (arg0.getKeyCode())
{
case KeyEvent.VK_LEFT:
bar.setValue(bar.getValue() - 1);
break;
case KeyEvent.VK_RIGHT:
bar.setValue(bar.getValue() + 1);
break;
case KeyEvent.VK_UP:
bar.setExtent(bar.getExtent() + 1);
break;
case KeyEvent.VK_DOWN:
bar.setExtent(bar.getExtent() - 1);
break;
case KeyEvent.VK_1:
bar.setOrientation(JProgressBar.HORIZONTAL);
break;
case KeyEvent.VK_2:
bar.setOrientation(JProgressBar.VERTICAL);
break;
}
}
});
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}