📄 drawableaxis.java
字号:
package balistic;
import java.awt.*;
import java.awt.image.*;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.util.Locale;
import java.text.ParseException;
public class DrawableAxis extends Component {
static final boolean VERTICAL = true;
static final boolean HORIZONTAL = false;
static final int pMajorTickLength = 3;
static final int pMinorTickLength = 1;
int iLength;
int maxWidth;
Font f;
FontMetrics fm;
int fontAscent, fontHeight;
int xnow, ynow;
boolean bOrientation;
double axisStart, axisFinish;
double increment;
DecimalFormat decform;
Font numberFont;
boolean bHaveLabel;
String sLabel;
Image iLabel;
Font labelFont;
public DrawableAxis(int iLength, boolean bVertical, double start, double finish,
Font f) {
this.iLength = iLength;
this.bOrientation = bVertical;
axisStart = start;
axisFinish = finish;
NumberFormat numform = NumberFormat.getInstance(Locale.US);
if (numform instanceof DecimalFormat) {
decform = (DecimalFormat) numform;
decform.applyPattern("0.###");
} else decform = null;
numberFont = f;
increment = chooseIncrement(axisFinish-axisStart,iLength,bVertical);
bHaveLabel = false;
}
public void setLabel(String s1, Font lf ) {
sLabel = s1;
labelFont = lf;
bHaveLabel = true;
}
public void setLabel(Image i1) {
iLabel = i1;
bHaveLabel = true;
}
public void draw(Graphics g, int x, int y) {
xnow = x; ynow = y;
maxWidth = 0;
if (bOrientation==VERTICAL) {
g.drawLine(xnow,ynow,xnow,ynow-iLength);
} else {
g.drawLine(xnow,ynow,xnow+iLength,ynow);
}
fm = Toolkit.getDefaultToolkit().getFontMetrics(numberFont);
fontAscent = fm.getAscent();
fontHeight = fm.getHeight();
g.setFont(numberFont);
makeTicks(g,increment,pMajorTickLength,true);
makeTicks(g,increment/5,pMinorTickLength,false);
if (bHaveLabel) drawLabel(g);
}
private void drawLabel(Graphics g) {
int width;
if (bOrientation==HORIZONTAL) {
FontMetrics lfm = Toolkit.getDefaultToolkit().getFontMetrics(labelFont);
width = lfm.stringWidth(sLabel);
// fontHeight is the height of the tick font.
g.setFont(labelFont);
g.drawString(sLabel,xnow+(iLength-width)/2,ynow+pMajorTickLength+fontHeight+
lfm.getHeight());
} else {
width = iLabel.getWidth(null);
int height = iLabel.getHeight(null);
//System.out.println("Label width "+width+" height "+height);
g.drawImage(iLabel,xnow-pMajorTickLength-maxWidth-width-3,
ynow-(iLength+height)/2,null);
}
}
private void makeTicks(Graphics g,double spacing, int ticklength, boolean numbered) {
int iMark;
double axisMark = axisStart;
while (axisMark < axisFinish) {
iMark = (int)(iLength*(axisMark-axisStart)/(axisFinish-axisStart));
String s1;
if (decform == null) s1 = Double.toString(axisMark);
else s1 = decform.format(axisMark);
if (bOrientation==VERTICAL) {
g.drawLine(xnow,ynow-iMark,xnow-ticklength,ynow-iMark);
if (numbered) textToLeft(s1,g,xnow-ticklength,ynow-iMark);
} else {
g.drawLine(xnow+iMark,ynow,xnow+iMark,ynow+ticklength);
if (numbered) textBelow(s1,g,xnow+iMark,ynow+ticklength);
}
axisMark += spacing;
}
}
protected void textBelow(String s1, Graphics g, int x, int y) {
int width = fm.stringWidth(s1);
g.drawString(s1,x-width/2,y+fontHeight);
}
protected void textToLeft(String s1, Graphics g, int x, int y) {
int width = fm.stringWidth(s1);
if (width>maxWidth) maxWidth = width;
g.drawString(s1,x-width-1,y-fontHeight/2+fontAscent);
}
// A method to help axes choose their increments.
// Use increments of 10, 20, 25 or 50 in whatever power of ten is appropriate.
private double chooseIncrement(double domain, int pixels, boolean bOrientation)
{
double bases[] = {1, 2, 2.5, 5};
if (domain<0) return(0.0);
FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(numberFont);
int height = fm.getHeight();
// estimate the increment to allow 30 pixels per label.
//double estimatedIncrement = domain*30/pixels;
double estimatedIncrement = domain*20/pixels;
// Use that estimate to get an order of magnitude to look for the real label.
int order = (int) Math.floor(Math.log(estimatedIncrement)/Math.log(10.0));
int sizeNeeded;
double numLabels = 5, lastLabel = 1.0;
// Loop through powers of ten.
while (order<5) {
// Loop through acceptable increments.
for (int i = 0; i<4; i++) {
double testIncrement = Math.pow(10,order)*bases[i];
// how many pixels per label this increment leaves.
int widthAvailable = (int) (pixels*testIncrement/domain);
if (bOrientation==DrawableAxis.HORIZONTAL) {
// how many labels we need to draw.
numLabels = Math.floor(domain/testIncrement);
// find the last label b/c it is likely the largest.
lastLabel = numLabels*testIncrement;
// Then see how wide it is.
sizeNeeded= fm.stringWidth(Double.toString(lastLabel));
} else sizeNeeded = height;
// If the label width (or height) is larger than a percentage of the
// available width per label, than keep looking. If the label width
// is small enough, then return.
if (sizeNeeded*1.4< widthAvailable) return testIncrement;
}
order += 1;
}
return(20.0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -