我编写了这个程序,找到了一种方法,可以将String
居中放在任意大小的BufferedImage
上(在这种情况下,BufferedImage
的大小与JPanel
它的位置和位置。当我调整JFrame
的大小时,文本在BufferedImage
重新定位时会闪烁,我不知道为什么。
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
class test extends JPanel
{
double scale = 0;
String draw = "1";
test()
{
setPreferredSize(new Dimension(600, 600));
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
paintText(g2, 0, 0);
}
public void paintText(Graphics2D g, int x, int y)
{
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D big = (Graphics2D) bi.getGraphics();
FontMetrics fm = big.getFontMetrics();
scale = bi.getHeight()/(fm.getHeight());
double xt = -(((scale*bi.getWidth())-bi.getWidth())/2);
double yt = -(((scale*bi.getHeight())-bi.getHeight())/2);
big.translate(xt, yt);
big.scale(scale, scale);
big.drawString(draw, (bi.getWidth()/2)-(fm.stringWidth(draw)/2), (bi.getHeight()/2)+(fm.getHeight()/4)+1);
g.drawImage(bi, x, y, this);
}
public static void main(String[] args)
{
JFrame frame = new JFrame("test");
frame.add(new test());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
答案 0 :(得分:3)
主要问题是你试图翻译BufferedImage
中的文本中心,随着窗口大小的改变,计算会导致一定程度的漂移,这意味着他们不会产生准确的位置。
经过多次填充后,我基本上抛弃了您的BufferedImage
和setScale
方法,并简单地根据scale
属性推导了一种新字体。
现在,您仍然可以生成BufferedImage
,但我会使用生成的FontMetrics
来确定图像的实际大小,并简单地将图像渲染到帧的中心位置......但那就是我
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
class Test101 extends JPanel {
double scale = 0;
String draw = "1";
Test101() {
setPreferredSize(new Dimension(600, 600));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
paintText(g2, 0, 0);
int x = getWidth() / 2;
int y = getHeight() / 2;
g2.setColor(Color.RED);
g2.drawLine(x, 0, x, getHeight());
g2.drawLine(0, y, getWidth(), y);
}
public void paintText(Graphics2D g, int x, int y) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
FontMetrics fm = g.getFontMetrics();
System.out.println(fm.getAscent());
scale = getHeight() / (fm.getHeight());
Font font = g.getFont().deriveFont(Font.PLAIN, AffineTransform.getScaleInstance(scale, scale));
g2d.setFont(font);
g2d.setColor(Color.WHITE);
fm = g.getFontMetrics(font);
int xPos = (getWidth() - fm.stringWidth(draw)) / 2;
int yPos = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(draw, xPos, yPos);
g2d.dispose();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("test");
frame.add(new Test101());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
答案 1 :(得分:0)
我认为这是因为您的GUI在Image所在的同一个线程中运行,尝试在自己的Thread中执行JFrame。