Java 我们如何在没有事先调用paintComponent的情况下进行文本测量?

Java 我们如何在没有事先调用paintComponent的情况下进行文本测量?,java,swing,graphics,text,measurement,Java,Swing,Graphics,Text,Measurement,嗨,所有我需要做一些文字测量使用,但这个类要求我提供一个图形对象 据我所知,抓取图形对象的唯一方法是通过paintComponent/paint方法: @Override public void paintComponent(java.awt.Graphics g){ //... 但是,我需要在调用paintComponent方法之前进行此测量。我想知道这个问题的最佳解决方案是什么 我是否要创建一个虚拟JLabel来执行此任务?无需创建虚拟GUI组件。例如,您可以创建一个buffereImag

嗨,所有我需要做一些文字测量使用,但这个类要求我提供一个图形对象

据我所知,抓取图形对象的唯一方法是通过paintComponent/paint方法:

@Override public void paintComponent(java.awt.Graphics g){ //...
但是,我需要在调用
paintComponent
方法之前进行此测量。我想知道这个问题的最佳解决方案是什么


我是否要创建一个虚拟JLabel来执行此任务?

无需创建虚拟GUI组件。例如,您可以创建一个
buffereImage

Graphics g = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getGraphics();
在这方面可能有用。这会将结果与从文本组件的
FontMetrics
获得的结果进行比较,并扩展@aioobe的
BufferedImage
建议

但是,我需要在调用paintComponent方法之前进行此测量

您可能应该重写组件的getPreferredSize()方法。这就是Swing组件如何在组件可见之前确定其大小和布局

JLabel使用以下各项:

FontMetrics fm = getFontMetrics(getFont());

或者,如果需要FontRenderContext(),则可以使用对象的
getGraphics()
方法。通常我建议不要使用这种方法,但这是因为人们会尝试使用图形对象进行自定义绘制。但是,在这种情况下,您只需要图形对象测量文本,这样就可以了。

或者您可以在组件构造函数中执行此操作

Font font = Font.createFont(Font.TRUETYPE_FONT, new File("ARIAL.TTF"));
font = font.deriveFont(12f);
FontMetrics fontMetrics = getFontMetrics(font);

根据aioobe的回答,这是一种获得图形的聪明方法。也许每个人都意识到了这一点,但是图形对象附带了一种特殊的字体,这种字体与aioobe获取图形的通用方式可以是任何东西

我必须这样做(Jython):

在那之后,这给出了一个准确的数字,在任何事情都还没有实现之前。。。万岁

hw_width = g.fontMetrics.stringWidth( "Hello World" )

顺便说一句,我想知道的是“直接构建的FontRenderContext很可能不代表任何实际的图形设备,并可能导致意外或不正确的结果”告诉我们不要这样做吗?但它前面的句子解释说,如果它是从图形对象获得的,那么它是可以的。(因为FontRenderContext不是凭空创建的……它是由图形对象精心构造的。)
buffereImage.TYPE_INT\u ARGB
为什么(大写)
A
?这似乎没有必要。@AndrewThompson您的意思是我们应该使用
缓冲图像。键入\u INT\u RGB
?@Pacerier回答我这个问题。我们不打算编写的BI支持透明性有什么好处?+1用于使用a)使用
FontRenderContext
而不是
FontMetrics
。b) 链接到文档。c) 链接到v。7.FontMetrics有什么问题?FontMetrics没有问题,但它是抽象的;它必须在某些上下文中进行检查,例如
FontRenderContext
Graphics2D
context.Ic中,所以
getGraphics
就是为了这种目的,不是吗?天哪,非常大胆的东西。。。我的意思是覆盖preferredSize()。我想到了一个想法:既然preferredSize只会在实现过程中被调用,那么你会如何处理这些信息呢?我建议这并不比实现后调整组件尺寸好,但不可取,因为这是危险的做法。如果你有什么想法,请告诉我你对艾奥比建议的看法。@Mikoverent,我对艾奥比的建议没有任何想法,因为我不理解它或问题的要求。当海报不理解Swing是如何工作的时,通常会出现这样的问题。问题并没有给出具体的原因(或示例),为什么OP认为在调用paintComponent()之前需要该大小。我的建议是重写getPreferredSize()方法,因为Swing组件就是这样做的。我看不出不采用这种方法的原因。谢谢。在我的用例中,我想创建一个表,其中一列从一开始的宽度正好适合渲染日期:渲染显然取决于日期格式,但也取决于字体。我认为在“setVisible”之后这样做应该很好。。。但是在…@mikoverent,
我想创建一个表,其中一列从一开始的宽度正好适合渲染日期
-请参阅。很好。或者只是FontMetrics FontMetrics=getFontMetrics(getFont())。。。i、 e.使用组件的字体。
hw_width = g.fontMetrics.stringWidth( "Hello World" )