/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package net.java.visualvm.modules.glassfish.ui;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.ImageCapabilities;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.VolatileImage;
import javax.swing.JComponent;
import javax.swing.border.Border;
/**
*
* @author Jaroslav Bachorik
*/
public class Tachometer extends JComponent {
private int val = 0;
private int max = 100;
private int min = 0;
private final static Dimension MINIMUM_SIZE = new Dimension(80, 80);
private final static double MAX_ANGLE = 270d;
@Override
public void paint(Graphics g) {
try {
Border border = getBorder();
Insets insets = new Insets(0, 0, 0, 0);
if (border != null) {
insets = border.getBorderInsets(this);
}
int diameter = Math.min(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom)) - 4;
VolatileImage img = createVolatileImage(getBounds().width - (insets.left + insets.right), getBounds().height - (insets.top + insets.bottom), new ImageCapabilities(true));
Graphics2D gr = img.createGraphics();
gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gr.drawOval(insets.left, insets.top, diameter, diameter);
TextLayout textTl = new TextLayout("fERRARI", getFont(), gr.getFontRenderContext());
AffineTransform at = new AffineTransform();
at.translate(0, (float)getBounds().getHeight() - (insets.top + insets.bottom) - (float)textTl.getBounds().getHeight());
at.scale(2d, 2d);
// at.shear(1.3d, 0.8d);
Shape textShape = textTl.getOutline(at);
gr.fill(textShape);
// GlyphVector gv = getFont().createGlyphVector(gr.getFontRenderContext(), "fERRARI");
// Rectangle bounds = gv.getPixelBounds(gr.getFontRenderContext(), 0, 0);
// double scale = (double)(getBounds().width - (insets.left + insets.right)) / (double)bounds.width;
// for(int i=0;i<gv.getNumGlyphs();i++) {
// gv.setGlyphTransform(i, AffineTransform.getScaleInstance(scale, 1d));
// gv.
// }
// gr.drawGlyphVector(gv, insets.left + 2, getBounds().height - (insets.top + insets.bottom) - 2 - bounds.height);
int lineLenght = diameter / 2 - 10;
gr.drawLine(diameter / 2, diameter / 2, diameter / 2 - getXOnArc(lineLenght, getAngle()), diameter / 2 - getYOnArc(lineLenght, getAngle()));
gr.dispose();
g.drawImage(img, insets.left, insets.top, this);
if (border != null) {
border.paintBorder(this, g, 0, 0, getBounds().width, getBounds().height);
}
} catch (AWTException e) {}
}
@Override
public Dimension getMinimumSize() {
return MINIMUM_SIZE;
}
@Override
public Dimension getPreferredSize() {
return MINIMUM_SIZE;
}
public void setMinValue(int minValue) {
min = minValue;
repaint();
}
public void setMaxValue(int maxValue) {
max = maxValue;
repaint();
}
public void setValue(int value) {
val = value;
repaint();
}
private static int getYOnArc(int diameter, int angle) {
return (int)(Math.sin(getRadians(angle)) * (double)diameter);
}
private static int getXOnArc(int diameter, int angle) {
return (int)(Math.cos(getRadians(angle)) * (double)diameter);
}
private static double getRadians(int angle) {
return 0.0175d * angle - Math.PI / 4;
}
private int getAngle() {
double ratio = (double)val / (double)(max - min);
int angle = (int)(ratio * MAX_ANGLE);
return angle;
}
}