【问题标题】:Elegant way to accomplish realization in Java Swing?在 Java Swing 中完成实现的优雅方式?
【发布时间】:2014-05-15 19:14:53
【问题描述】:

我经常遇到Swing方法或属性需要实现对象的问题。例如,要在 JPanel 上绘图,我可能需要知道特定字体的高度,但此信息要等到面板实现后才能获得,因此在此之前我会得到一个空指针。更糟糕的是,并不总是清楚(至少对我而言)哪些方法需要实现对象,哪些不需要。

显然我可以做一些愚蠢的事情,比如:

  1. 绘制虚拟文本强制实现
  2. 获取字体指标
  3. 删除虚拟文本
  4. 计算并绘制真实文本

不得不这样做似乎令人难以置信的轻率。有没有更优雅的方式来强制实现,以便我可以可靠地访问字体指标?

典型示例代码:

void draw( Point2D center ){

    String sLabel = owner.getLabel();
    NodeData.DATA_TYPE eType = owner.data_type;

    int iSymbolWidth = 10;

    // build text
    if( sLabel == null ) sLabel = "";
    Font font = new Font( "TimesRoman", Font.PLAIN, 12 );
    text_node.setTextPaint( Color.DARK_GRAY );
    text_node.setText( sLabel );
    text_node.setFont( font );
    Panel_Main panel = owner.application.getDisplayPanel();
    java.awt.FontMetrics fm = panel.canvas.getGraphics().getFontMetrics(); // <--- ERROR HERE
    int iText_AdvanceWidth = ( int ) ( fm.stringWidth( sLabel ) * 1.2 ) + LABEL_MARGIN * 2;
    int iText_Height = fm.getHeight();
            .... etc

部分问题是我正在绘制的对象归 Piccolo(一个图形绘制库)所有,因此该库拥有paintComponent,而不是我。在挖掘 Piccolo 源代码时,似乎我需要重写它们的内部方法之一,paint(PPaintContext paintContext),它基本上应该等同于重写paintComponent。

【问题讨论】:

  • 谢谢!这里有一个提示...您的字体定义为 12 Points(请参阅 Font 构造函数中的第三个参数)。一英寸有72个点。
  • 自定义绘画应该在paintComponent()方法中完成。此方法只会在已实现的组件上调用。
  • @ElliottFrisch 这是一个危险的假设
  • @MadProgrammer 这就是我在报纸时代学到的身份——它也是一个提示,而不是一个答案。

标签: java swing rendering font-size


【解决方案1】:

正如here 所讨论的,每个 Swing 组件都有一个 UI 委托,它根据用户选择的外观和感觉计算组件的正确首选大小。因此,最优雅的解决方案是让布局管理器利用组件的首选大小。不这样做通常会导致他的pathologic behavior。如herehere 所示,您可以validate() 封闭容器在setVisible() 之前获得所需的几何图形,但这样做表明可能需要另一种方法。作为一个具体的例子,这个BoxLayoutexample最好使用GroupLayout完成,如图herehere

通常,您只需检查FontMetrics 即可计算您自己的自定义组件的首选大小,如here 所示。

【讨论】:

  • 从我的代码示例中应该很明显,我正在做自定义绘画,所以我想这会导致需要覆盖paintComponent。
  • 在这种情况下,您可以利用TextLayout,看到herehere
猜你喜欢
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多