Window 和 Java 中的水平居中文本
Horizontally Centering Text in a Window with Java
我正在尝试弄清楚如何使用 Graphics2D 和 FontMetrics 在 window 中将文本水平居中。我做了一个方法,希望在将字符串更改为 Font 类型后测量字符串的长度,但它不能很好地使文本居中。
如何正确居中文本?
标题没有很好地居中:
我的主类class:
import java.io.File;
import java.io.IOException;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainClass extends JPanel{
static final int WINDOW_WIDTH = 1600;
static final int WINDOW_HEIGHT = 900;
// Displays the game window.
private static void displayGameWindow() {
Color tan = new Color(155, 136, 120);
JFrame frame = new JFrame("Bandit King");
frame.setBackground(tan);
frame.getContentPane().add(new MainClass());
frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// Imports a font.
private static void registerFont() {
try {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
Font f = Font.createFont(Font.TRUETYPE_FONT, new File("OLDSH.TTF"));
ge.registerFont(f);
} catch (IOException|FontFormatException e) {
e.printStackTrace();
System.out.println("ERROR loading font, switching to serif.");
Font f = new Font("Serif", Font.PLAIN, 12);
}
}
// Calls functions to display the screen
@Override
public void paint(Graphics g) {
Dimension d = this.getPreferredSize();
Graphics2D g2d = (Graphics2D) g;
g.fillRect(0, 0, d.width, d.height);
// default font settings
String fontName = "OldStyle 1 HPLHS";
String fontType = "BOLD";
int[] color = {0, 0, 0};
int fontSize = 25;
// display game title
String[] title = {"Bandit King"};
int titlePos = DisplayText.findHorizontalCenter(g2d, title[0], d.width);
DisplayText.displayText(g2d,
title, fontName, "BOLD",
color,
titlePos, 70, 60, 1);
g2d.drawRect(0, 0, d.width - 1, d.height - 1);
// display menu
String[] menuArr = {
"(a) Start a new game",
"(b) Load a saved game",
"(c) Exit the game",
"(d) Resume the game"};
DisplayText.displayText(g2d,
menuArr, fontName, fontType, color, 40, 210, fontSize, 2);
}
public static void main(String[] args) {
registerFont();
displayGameWindow();
}
}
我的 DisplayText class:
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
public class DisplayText {
/**
* Displays text to window
*
* PARAMETERS:
* g2d A Graphics2D object
* text The text to be drawn to screen
* fontName The name of the font to be used.
* fontType Whether the font is bold, italic, or neither.
* color Array of length 3, to represent RGB color
* xPos The x-position of the text.
* yPos The y-position of the text.
* fontSize The size of the font.
* menuSpacing How far apart menu text should be. (Never zero!)
*/
public static void displayText(Graphics2D g2d,
String[] textItems, String fontName, String fontType,
int[] color,
int xPos, int yPos, int fontSize, double menuSpacing) {
// Check for problems
// if textItems is empty
if (textItems.length < 1) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"no items in String[] textItems");
return;
// if color array isn't length 3.
} else if (color.length != 3) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"color.length != 3");
return;
// if menuSpacing isn't a positive number or > 0.
} else if (menuSpacing <= 0) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"menuSpacing <= 0");
}
// assign appropriate int according to fontType
fontType = fontType.toLowerCase();
int fontNum;
switch(fontType) {
case "bold" :
fontNum = Font.BOLD;
break;
case "italic" :
fontNum = Font.ITALIC;
break;
case "plain" :
fontNum = Font.PLAIN;
break;
default :
fontNum = Font.PLAIN;
break;
}
g2d.setFont(new Font(fontName, fontNum, fontSize));
g2d.setColor(new Color(color[0], color[1], color[2]));
// Determine whether to print several lines or one.
if (textItems.length == 1) {
g2d.drawString(textItems[0], xPos, yPos);
} else {
// Draw several lines
for (int i = 0; i < textItems.length; i++) {
g2d.drawString(textItems[i], xPos, yPos);
// Spaces menu items by the height of the font and menuSpacing
yPos += (int) (g2d.getFontMetrics().getAscent() * menuSpacing);
}
}
}
// Finds the x-position centered text should be at.
public static int findHorizontalCenter(Graphics2D g2d,
String s, int w) {
Font f = g2d.getFont();
FontMetrics fm = g2d.getFontMetrics(f);
int width = fm.stringWidth(s);
System.out.println(width);
int x = (MainClass.WINDOW_WIDTH - width)/2;
return x;
}
}
int x = MainClass.WINDOW_WIDTH / 2 - width;
应该是
int x = MainClass.WINDOW_WIDTH / 2 - width/2;
尝试设置字体大小,然后获取文本的宽度。
我正在尝试弄清楚如何使用 Graphics2D 和 FontMetrics 在 window 中将文本水平居中。我做了一个方法,希望在将字符串更改为 Font 类型后测量字符串的长度,但它不能很好地使文本居中。
如何正确居中文本?
标题没有很好地居中:
我的主类class:
import java.io.File;
import java.io.IOException;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainClass extends JPanel{
static final int WINDOW_WIDTH = 1600;
static final int WINDOW_HEIGHT = 900;
// Displays the game window.
private static void displayGameWindow() {
Color tan = new Color(155, 136, 120);
JFrame frame = new JFrame("Bandit King");
frame.setBackground(tan);
frame.getContentPane().add(new MainClass());
frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// Imports a font.
private static void registerFont() {
try {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
Font f = Font.createFont(Font.TRUETYPE_FONT, new File("OLDSH.TTF"));
ge.registerFont(f);
} catch (IOException|FontFormatException e) {
e.printStackTrace();
System.out.println("ERROR loading font, switching to serif.");
Font f = new Font("Serif", Font.PLAIN, 12);
}
}
// Calls functions to display the screen
@Override
public void paint(Graphics g) {
Dimension d = this.getPreferredSize();
Graphics2D g2d = (Graphics2D) g;
g.fillRect(0, 0, d.width, d.height);
// default font settings
String fontName = "OldStyle 1 HPLHS";
String fontType = "BOLD";
int[] color = {0, 0, 0};
int fontSize = 25;
// display game title
String[] title = {"Bandit King"};
int titlePos = DisplayText.findHorizontalCenter(g2d, title[0], d.width);
DisplayText.displayText(g2d,
title, fontName, "BOLD",
color,
titlePos, 70, 60, 1);
g2d.drawRect(0, 0, d.width - 1, d.height - 1);
// display menu
String[] menuArr = {
"(a) Start a new game",
"(b) Load a saved game",
"(c) Exit the game",
"(d) Resume the game"};
DisplayText.displayText(g2d,
menuArr, fontName, fontType, color, 40, 210, fontSize, 2);
}
public static void main(String[] args) {
registerFont();
displayGameWindow();
}
}
我的 DisplayText class:
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
public class DisplayText {
/**
* Displays text to window
*
* PARAMETERS:
* g2d A Graphics2D object
* text The text to be drawn to screen
* fontName The name of the font to be used.
* fontType Whether the font is bold, italic, or neither.
* color Array of length 3, to represent RGB color
* xPos The x-position of the text.
* yPos The y-position of the text.
* fontSize The size of the font.
* menuSpacing How far apart menu text should be. (Never zero!)
*/
public static void displayText(Graphics2D g2d,
String[] textItems, String fontName, String fontType,
int[] color,
int xPos, int yPos, int fontSize, double menuSpacing) {
// Check for problems
// if textItems is empty
if (textItems.length < 1) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"no items in String[] textItems");
return;
// if color array isn't length 3.
} else if (color.length != 3) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"color.length != 3");
return;
// if menuSpacing isn't a positive number or > 0.
} else if (menuSpacing <= 0) {
System.out.println("DisplayText.displayText() ERROR" +
System.lineSeparator() +
"menuSpacing <= 0");
}
// assign appropriate int according to fontType
fontType = fontType.toLowerCase();
int fontNum;
switch(fontType) {
case "bold" :
fontNum = Font.BOLD;
break;
case "italic" :
fontNum = Font.ITALIC;
break;
case "plain" :
fontNum = Font.PLAIN;
break;
default :
fontNum = Font.PLAIN;
break;
}
g2d.setFont(new Font(fontName, fontNum, fontSize));
g2d.setColor(new Color(color[0], color[1], color[2]));
// Determine whether to print several lines or one.
if (textItems.length == 1) {
g2d.drawString(textItems[0], xPos, yPos);
} else {
// Draw several lines
for (int i = 0; i < textItems.length; i++) {
g2d.drawString(textItems[i], xPos, yPos);
// Spaces menu items by the height of the font and menuSpacing
yPos += (int) (g2d.getFontMetrics().getAscent() * menuSpacing);
}
}
}
// Finds the x-position centered text should be at.
public static int findHorizontalCenter(Graphics2D g2d,
String s, int w) {
Font f = g2d.getFont();
FontMetrics fm = g2d.getFontMetrics(f);
int width = fm.stringWidth(s);
System.out.println(width);
int x = (MainClass.WINDOW_WIDTH - width)/2;
return x;
}
}
int x = MainClass.WINDOW_WIDTH / 2 - width;
应该是
int x = MainClass.WINDOW_WIDTH / 2 - width/2;
尝试设置字体大小,然后获取文本的宽度。