I've found it 'simpler' to get the Shape
of the text and work with that.
import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class TextBoundingBox {
private JComponent ui = null;
public static String string = "Red outline shows bounds of text";
public static Font font = new Font(Font.SANS_SERIF, Font.BOLD, 36);
TextBoundingBox() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new JLabel(new ImageIcon(getImage())));
}
private static BufferedImage getImage() {
Shape shape = getShapeOfText(font, string);
Rectangle2D boundsRectangle = shape.getBounds2D();
double w = boundsRectangle.getWidth();
double h = boundsRectangle.getHeight();
int wBig = (int) (w * 1.1);
int hBig = (int) (h * 2);
BufferedImage bi = new BufferedImage(
wBig, hBig, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, wBig, hBig);
g.setColor(Color.BLACK);
g.fill(moveShapeToCenter(shape, wBig, hBig));
g.setColor(Color.RED);
g.draw(moveShapeToCenter(boundsRectangle, wBig, hBig));
g.dispose();
return bi;
}
public static Shape moveShapeToCenter(Shape shape, int w, int h) {
Rectangle2D b = shape.getBounds2D();
double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
return move.createTransformedShape(shape);
}
public static Shape getShapeOfText(Font font, String msg) {
BufferedImage bi = new BufferedImage(
1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, msg);
return gv.getOutline();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
TextBoundingBox o = new TextBoundingBox();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…