getGraphics()什么时候会返回一个有效的图形实例?

时间:2010-02-16 18:23:59

标签: java swing

我正在尝试渲染一个自定义Swing组件,我扩展了JComponent类。

为了简化组件要求,我们只需要将我的组件汇总为需要渲染一些字符串,每个字符串都有自己的字体。

我需要将我的组件的大小精确到我渲染的字符串的总宽度和高度。

为了确定这个大小,我使用FontMetrics来计算每个字符串的尺寸。有了这些信息,我可以弄清楚我的组件的大小,并适当调整大小。

问题是,当我访问getGraphics()时,它总是为null,所以我无法得到FontMetrics实例。如果我等待从覆盖的paintComponent()方法计算我的组件大小,它已经太晚了(组件已经有一个大小,对吧?)。

文档说“如果此组件当前不可显示,则此方法将返回null”。那么我何时知道组件何时可以显示并且有一个Graphics对象供我调整组件的大小呢?

调用frame setVisible(true)后,渲染组件的Swing调用顺序是什么?

由于


更新:2010年2月6日星期二23:34

正如评论中所提到的,GridLayout根本不尊重任何setXxxSize()。对于任何感兴趣的人,我发布了使用GridLayout,BoxLayout和FlowLayout的结果,使用一个简单的框架,接收5个固定大小的200宽50高的组件(通过设置min,max和preferred)。

测试结果:

GridLayout 始终沿宽度和高度调整大小(如评论中所述)

FlowLayout 始终尊重组件大小。

至于 BoxLayout ...

PAGE_AXIS Y_AXIS 将组件的宽度缩小到大小的一半(104),但没有缩小高度。

LINE_AXIS X_AXIS 将组件的高度缩小到看似零但没有触及宽度的位置。

2 个答案:

答案 0 :(得分:7)

首先,您可以使用TextLayout类及其相关内容来测量字符串。例如

public static void main(final String[] args) throws Exception
{
    final FontRenderContext frc = new FontRenderContext(null, true, true);
    final Font font = new Font("serif", Font.PLAIN, 18);
    final TextLayout layout = new TextLayout("This is a test", font, frc);
    final Rectangle2D bounds = layout.getBounds();
    System.err.println((int) (bounds.getWidth() + .5));
}

其次,您可以使用ComponentListener通知您的组件何时可见,但这不是“提前”测量字符串所必需的!

答案 1 :(得分:2)

使用JLabel渲染你的字符串然后你就可以使用thel标签的getPreferredSize()方法。