在Java中绘制具有特定大小的字符
我有一个显示10x10单元格网格的Java编程。在每个单元格中,我想画一个字符,让它占据整个单元格 我目前正在使用以下代码,但大小不太合适在Java中绘制具有特定大小的字符,java,graphics,fonts,character,Java,Graphics,Fonts,Character,我有一个显示10x10单元格网格的Java编程。在每个单元格中,我想画一个字符,让它占据整个单元格 我目前正在使用以下代码,但大小不太合适 graphics.setFont(new Font("monospaced", Font.PLAIN, 12)); for(int x = 0; x < GRID_WIDTH; x++) { for(int y = 0; y < GRID_HEIGHT; y++) { graphics.drawString(Charac
graphics.setFont(new Font("monospaced", Font.PLAIN, 12));
for(int x = 0; x < GRID_WIDTH; x++) {
for(int y = 0; y < GRID_HEIGHT; y++) {
graphics.drawString(Character.toString(grid[x][y]), x * CELL_WIDTH, (y + 1) * CELL_HEIGHT);
}
}
graphics.setFont(新字体(“单间距”,Font.PLAIN,12));
对于(int x=0;x
Java中是否有任何方法可以绘制10x10(或
CELL\u WIDTH
xCELL\u HEIGHT
)字符?我在一个项目中构建了这些方法,我在阅读此问题=D时碰巧打开了该项目。请注意,该方法的大小应该适合您的特定情况。默认大小为130,这对于您的案例来说可能太高了。您可以根据需要对其进行调整,但这演示了基本原理。在您的情况下,请这样使用它们:
Font baseFont = new Font("monospaced", Font.PLAIN, 12);
for(int x = 0; x < GRID_WIDTH; x++) {
for(int y = 0; y < GRID_HEIGHT; y++) {
graphics.setFont(pickOptimalFontSize(graphics, Character.toString(grid[x][y]), CELL_WIDTH, CELL_HEIGHT, baseFont));
drawString(graphics, Character.toString(grid[x][y]), x * CELL_WIDTH, (y + 1) * CELL_HEIGHT, "left", "center");
}
}
public static void drawString(Graphics g, String str, double x, double y, String hAlign, String vAlign) {
FontMetrics metrics = g.getFontMetrics();
double dX = x;
double dY = y;
if(hAlign == null || "left".equals(hAlign.toLowerCase())) {
} else if("center".equals(hAlign.toLowerCase())) {
dX -= metrics.getStringBounds(str, g).getWidth()/2;
} else if("right".equals(hAlign.toLowerCase())) {
dX -= metrics.getStringBounds(str, g).getWidth();
}
if(vAlign == null || "bottom".equals(vAlign.toLowerCase())) {
} else if("center".equals(vAlign.toLowerCase())) {
dY += metrics.getAscent()/2;
} else if("top".equals(vAlign.toLowerCase())) {
dY += metrics.getAscent();
}
g.drawString(str, (int)dX, (int)dY);
}
private static Font pickOptimalFontSize (Graphics2D g, String title, int width, int height, Font baseFont) {
Rectangle2D rect = null;
float fontSize = 130; //initial value
Font font;
do {
fontSize-=1;
font = baseFont.deriveFont(fontSize);
rect = getStringBoundsRectangle2D(g, title, font);
} while (rect.getWidth() >= width || rect.getHeight() >= height);
return font;
}
public static Rectangle2D getStringBoundsRectangle2D (Graphics g, String title, Font font) {
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
Rectangle2D rect = fm.getStringBounds(title, g);
return rect;
}
Font-baseFont=新字体(“等距”,Font.PLAIN,12);
对于(int x=0;x=width | | rect.getHeight()>=height);
返回字体;
}
公共静态矩形2D getStringBoundsRectangle2D(图形g、字符串标题、字体){
g、 setFont(字体);
FontMetrics fm=g.getFontMetrics();
矩形2d rect=fm.getStringBounds(标题g);
返回矩形;
}
我找到了一个我想要的解决方案:我创建了一个名为CharacterImageGenerator
的类,该类生成(并缓存)图像
s个字符。然后,每当我想画一个角色时,我就绘制并缩放这些图像
public class CharacterImageGenerator {
private FontMetrics metrics;
private Color color;
private Map<Character, Image> images;
public CharacterImageGenerator(FontMetrics metrics, Color color) {
this.metrics = metrics;
this.color = color;
images = new HashMap<Character, Image>();
}
public Image getImage(char c) {
if(images.containsKey(c))
return images.get(c);
Rectangle2D bounds = new TextLayout(Character.toString(c), metrics.getFont(), metrics.getFontRenderContext()).getOutline(null).getBounds();
if(bounds.getWidth() == 0 || bounds.getHeight() == 0) {
images.put(c, null);
return null;
}
Image image = new BufferedImage((int)bounds.getWidth(), (int)bounds.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = image.getGraphics();
g.setColor(color);
g.setFont(metrics.getFont());
g.drawString(Character.toString(c), 0, (int)(bounds.getHeight() - bounds.getMaxY()));
images.put(c, image);
return image;
}
}
然后缩放并绘制到我想要的大小
private void drawCharacter(int x, int y, char c) {
graphics.drawImage(characterGenerator.getImage(c), PADDING + (x * TILE_WIDTH), PADDING + (y * TILE_HEIGHT), TILE_WIDTH, TILE_HEIGHT, null);
}
您需要计算单个字符的宽度和高度,以确定单元格中实际适合的字体大小。由于每个字体和字体的每个字符具有/可以具有不同的特征,因此每个字符和字体的特征都会发生变化。通读更多细节如果这是我的程序,我会使用JLabel或JTextField,并给它一个所需字体大小的字符,然后让版面管理员决定如何最佳调整字体大小。看看你心中是否有一个特定的大小,然后你可以通过调整正确方向的大小,然后检查高度和宽度,直到你已经足够接近它。我更想弄清楚如何将一个字符缩放为10×10的正方形而不是找到适合该单元格的字体大小。
fm.getStringBounds
似乎给出了奇怪的结果,因为它为字体大小9提供了10.47的高度,但当我查看绘制的内容时,高度是6像素。这会导致整个pickOptimalFontSize
方法选择一个比所需尺寸小得多的尺寸。@DanielGibbs FontMetrics使用起来非常奇怪,对于某些字体,它们不会返回完美的匹配,特别是当您谈论1px的差异时。请注意,pickOptimalFontSize中的循环一次递增1个大小。如果要使用这些微小的增量,则应设置fontSize=16;。。。。。fontSize-=.2f;尝试调整该方法。就像我说的,它是为一个需要大字体的特定项目而构建的。使用AWT时,需要降低数值。增量不是问题所在。问题在于字体度量返回的边界是错误的。他们说一个角色的身高是6,而它的身高是10.47。
private void drawCharacter(int x, int y, char c) {
graphics.drawImage(characterGenerator.getImage(c), PADDING + (x * TILE_WIDTH), PADDING + (y * TILE_HEIGHT), TILE_WIDTH, TILE_HEIGHT, null);
}