![](/img/trans.png)
[英]Is there A Java Function or Library to Insert formatted Text into arbitrary file?
[英]Java - best library to help draw text at arbitrary anchor points
我熟悉如何使用各種 FontMetrics 函數將文本垂直、水平等居中。 但是,我正在尋找一個支持在相對於字符串的給定 xy 位置繪制文本的庫(例如,我希望字符串的中心位於 x、y,或者我希望它的右上角在這里,等等。 )
我發現JCommon及其文本錨點聲稱可以做到這一點,但我無法讓它正常工作, 而且論壇迄今為止沒有響應。
我知道我可以自己編寫所有實用程序函數,但我想盡可能避免重新發明輪子。
我不知道有任何庫,但我猜如果你自己做,你只會使用 Graphics.translate() 將文本轉換為相對位置。
最后不得不自己做。 代碼如下:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestFontLayout extends JPanel {
public enum AnchorPoint{
UPPER_LEFT,
TOP_CENTER,
UPPER_RIGHT,
RIGHT_CENTER,
LOWER_RIGHT,
BOTTOM_CENTER,
LOWER_LEFT,
LEFT_CENTER,
CENTER
};
public void drawText(TextLayout text, AnchorPoint point, Graphics2D g2, float x, float y) {
float translationX = 0.0f;
float translationY = 0.0f;
Rectangle2D bounds = text.getBounds();
float midYOffset = (float) bounds.getHeight()/2;
float midXOffset = (float) -bounds.getWidth()/2;
float topYOffset = (float) bounds.getHeight();
float bottomYOffset = 0.0f;
float leftXOffset = 0.0f;
float rightXOffset = (float) -bounds.getWidth();
// Adjust x values
switch (point) {
// Left
case UPPER_LEFT:
case LOWER_LEFT:
case LEFT_CENTER:
translationX = leftXOffset;
break;
// Mid
case TOP_CENTER:
case BOTTOM_CENTER:
case CENTER:
translationX = midXOffset;
break;
// Right
case UPPER_RIGHT:
case RIGHT_CENTER:
case LOWER_RIGHT:
translationX = rightXOffset;
}
// Adjust y values
switch (point) {
// Top
case UPPER_LEFT:
case UPPER_RIGHT:
case TOP_CENTER:
translationY = topYOffset;
break;
// Mid
case LEFT_CENTER:
case CENTER:
case RIGHT_CENTER:
translationY = midYOffset;
break;
// Bottom
case LOWER_LEFT:
case BOTTOM_CENTER:
case LOWER_RIGHT:
translationY = bottomYOffset;
}
text.draw(g2, x + translationX, y + translationY);
}
public TestFontLayout() {
super();
setPreferredSize(new Dimension(400,400));
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Ensure that the default painting occurs
super.paintComponent(g);
Point2D loc = new Point2D.Double(getWidth()/2,getHeight()/2);
Font font = Font.decode("Helvetica");
FontRenderContext frc = g2.getFontRenderContext();
TextLayout layout = new TextLayout("This is a string", font, frc);
g2.setColor(Color.RED);
g2.drawRect(getWidth()/2, getHeight()/2, 1,1);
g2.setColor(Color.PINK);
drawText(layout, AnchorPoint.UPPER_LEFT, g2, 0, 0);
g2.setColor(Color.BLUE);
drawText(layout, AnchorPoint.TOP_CENTER, g2, getWidth()/2, 0);
g2.setColor(Color.ORANGE);
drawText(layout, AnchorPoint.UPPER_RIGHT, g2, getWidth(), 0);
g2.setColor(Color.CYAN);
drawText(layout, AnchorPoint.RIGHT_CENTER, g2, getWidth(), getHeight()/2);
g2.setColor(Color.ORANGE);
drawText(layout, AnchorPoint.LOWER_RIGHT, g2, getWidth(), getHeight());
g2.setColor(Color.BLACK);
drawText(layout, AnchorPoint.BOTTOM_CENTER, g2, getWidth()/2, getHeight());
g2.setColor(Color.YELLOW);
drawText(layout, AnchorPoint.LOWER_LEFT, g2, 0, getHeight());
g2.setColor(Color.DARK_GRAY);
drawText(layout, AnchorPoint.LEFT_CENTER, g2, 0, getHeight()/2);
g2.setColor(Color.MAGENTA);
drawText(layout, AnchorPoint.CENTER, g2, getWidth()/2, getHeight()/2);
}
public static void main(String[] args) {
JFrame frame = new JFrame("");
frame.add(new TestFontLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
您可能會查看TextLayout
。 draw()
和getBounds()
方法可以簡化編碼。
我發現TestFontLayout
通過代碼I82Much是非常有用的,謝謝。 垂直對齊有一個小錯誤。 我的解決方法是使用bounds.getY()
而不是bounds.getHeight()
進行“偏移”計算。 此外, drawText(...)
方法已被修改為返回自定義Box
類以提供繪制文本的角坐標,以便下一次繪制可以使用 Box 角對齊更多文本。 這是我的代碼版本。
import static java.awt.Color.BLACK;
import static java.awt.Color.BLUE;
import static java.awt.Color.CYAN;
import static java.awt.Color.DARK_GRAY;
import static java.awt.Color.MAGENTA;
import static java.awt.Color.ORANGE;
import static java.awt.Color.PINK;
import static java.awt.Color.RED;
import static java.awt.Color.YELLOW;
import static java.awt.Font.PLAIN;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestFontLayout2 extends JPanel
{
private static final long serialVersionUID = 1L;
public enum Anchor
{
UPPER_LEFT,
UPPER_CENTER,
UPPER_RIGHT,
MIDDLE_LEFT,
MIDDLE_CENTER,
MIDDLE_RIGHT,
LOWER_LEFT,
LOWER_CENTER,
LOWER_RIGHT
};
public static Box drawText(Graphics2D g2d, String text, Anchor point, float xpos, float ypos)
{
return drawText(g2d, new TextLayout(text, g2d.getFont(), g2d.getFontRenderContext()), point, xpos, ypos);
}
public static Box drawText(Graphics2D g2d, String text, Anchor point, float xpos, float ypos, Font font)
{
return drawText(g2d, new TextLayout(text, font, g2d.getFontRenderContext()), point, xpos, ypos);
}
public static Box drawText(Graphics2D g2d, TextLayout text, Anchor anchor, float xpos, float ypos)
{
Rectangle2D bounds = text.getBounds();
float xOffsetLeft = 0.0f;
float xOffsetRight = (float) -bounds.getWidth();
float xOffsetCenter = (float) -bounds.getWidth() / 2.0f;
// Bounds.getY() is the (negative) offset between the baseline and the top of the text.
// Bounds.getHeight() is the distance above plus the distance below the text baseline.
float yOffsetTop = (float) bounds.getY();
float yOffsetBottom = (float) (bounds.getHeight()+bounds.getY());
float yOffsetMiddle = (float) (-bounds.getHeight()) / 2.0f;
float xOffset = 0.0f;
float yOffset = 0.0f;
// Adjust x values
switch (anchor)
{
// Left
case UPPER_LEFT:
case MIDDLE_LEFT:
case LOWER_LEFT:
xOffset = xOffsetLeft;
break;
// Center
case UPPER_CENTER:
case MIDDLE_CENTER:
case LOWER_CENTER:
xOffset = xOffsetCenter;
break;
// Right
case UPPER_RIGHT:
case MIDDLE_RIGHT:
case LOWER_RIGHT:
xOffset = xOffsetRight;
break;
}
// Adjust y values
switch (anchor)
{
// Top
case UPPER_LEFT:
case UPPER_CENTER:
case UPPER_RIGHT:
yOffset = yOffsetTop;
break;
// Middle
case MIDDLE_LEFT:
case MIDDLE_CENTER:
case MIDDLE_RIGHT:
yOffset = yOffsetMiddle;
break;
// Bottom
case LOWER_LEFT:
case LOWER_CENTER:
case LOWER_RIGHT:
yOffset = yOffsetBottom;
break;
}
// Draw text at baseline position.
float xbase = xpos + xOffset;
float ybase = ypos - yOffset;
text.draw(g2d, xbase, ybase);
// Enclose text within a box.
int xrect = rnd(xbase + bounds.getX());
int yrect = rnd(ybase + bounds.getY());
int wrect = rnd(bounds.getWidth());
int hrect = rnd(bounds.getHeight());
Box box = new Box(xrect, yrect, xrect+wrect, yrect+hrect);
// Debug: draw rectangle around text.
// g2d.drawRect(xrect, yrect, wrect, hrect);
return box;
}
private static int rnd(double value)
{
return (int) Math.round(value);
}
public static class Box
{
private int tl[] = {0, 0}; public int[] getTL() { return tl; }
private int br[] = {0, 0}; public int[] getBR() { return br; }
private int tr[] = {0, 0}; public int[] getTR() { return tr; }
private int bl[] = {0, 0}; public int[] getBL() { return bl; }
public Box(int tlx, int tly, int brx, int bry)
{
tl[0] = tlx; tl[1] = tly;
br[0] = brx; br[1] = bry;
tr[0] = brx; tr[1] = tly;
bl[0] = tlx; bl[1] = bry;
}
}
public TestFontLayout2()
{
super();
setPreferredSize(new Dimension(600,300));
}
@Override
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
// Ensure that the default painting occurs
super.paintComponent(g);
Font font = new Font("SansSerif", PLAIN, 21);
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout layout1 = new TextLayout("This is a string", font, frc);
TextLayout layout2 = new TextLayout("This is text", font, frc);
g2d.setColor(RED);
g2d.drawRect(getWidth()/2, getHeight()/2, 1,1);
g2d.setColor(PINK);
Box box = drawText(g2d, layout1, Anchor.UPPER_LEFT, 0, 0);
g2d.setColor(BLUE);
box = drawText(g2d, layout2, Anchor.UPPER_CENTER, getWidth()/2, 0);
g2d.setColor(ORANGE);
box = drawText(g2d, layout1, Anchor.UPPER_RIGHT, getWidth(), 0);
g2d.setColor(DARK_GRAY);
box = drawText(g2d, layout2, Anchor.MIDDLE_LEFT, 0, getHeight()/2);
g2d.setColor(MAGENTA);
box = drawText(g2d, layout1, Anchor.MIDDLE_CENTER, getWidth()/2, getHeight()/2);
box = drawText(g2d, layout1, Anchor.UPPER_LEFT, box.getBL()[0], box.getBL()[1]);
g2d.setColor(CYAN);
box = drawText(g2d, layout2, Anchor.MIDDLE_RIGHT, getWidth(), getHeight()/2);
g2d.setColor(YELLOW);
box = drawText(g2d, layout1, Anchor.LOWER_LEFT, 0, getHeight());
g2d.setColor(BLACK);
box = drawText(g2d, layout2, Anchor.LOWER_CENTER, getWidth()/2, getHeight());
g2d.setColor(ORANGE);
box = drawText(g2d, layout1, Anchor.LOWER_RIGHT, getWidth(), getHeight());
}
public static void main(String[] args)
{
println("Draw text at specified anchor points...");
JFrame frame = new JFrame("");
frame.add(new TestFontLayout2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static void println(Object obj)
{
System.out.println(obj.toString());
}
}
// vi:set tabstop=4 hardtabs=4 shiftwidth=4 expandtab:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.