简体   繁体   English

在Java Swing中实现实现的优雅方式?

[英]Elegant way to accomplish realization in Java Swing?

I often have the problem that a Swing method or property requires the object to be realized. 我经常遇到Swing方法或属性需要实现对象的问题。 For example, to draw on a JPanel I may need to know how tall a particular font is, but this information is not available until after the panel is realized, so I will get a null pointer before that. 例如,要在JPanel上绘图,我可能需要知道特定字体的高度,但是这个信息在面板实现之后才可用,所以在此之前我会得到一个空指针。 To make matters worse it is not always clear (to me at least) which methods require the object to be realized and which do not. 更糟糕的是,(至少对我来说)并不总是清楚哪些方法需要实现对象,哪些方法不需要。

Obviously I can do something stupid like: 显然我可以做一些愚蠢的事情:

  1. draw dummy text to force realization 绘制虚拟文本以强制实现
  2. get font metrics 获取字体指标
  3. erase dummy text 删除虚拟文本
  4. calculate and draw real text 计算并绘制真实文本

It seems incredibly harebrained to have to do this. 必须要做到这一点似乎非常难以置信。 Is there a more elegant way to force realization so I can get reliable access to the font metrics? 是否有更优雅的方式来强制实现,以便我可以获得对字体指标的可靠访问?

Typical example code: 典型示例代码:

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

Part of the problem is that the object I am drawing on is owned by Piccolo, a graph drawing library, so the library owns paintComponent, not me. 问题的一部分是我正在绘制的对象由Piccolo(一个图形绘制库)拥有,因此库拥有paintComponent,而不是我。 On digging through the Piccolo source code, it appears I need to override one of their internal methods, paint(PPaintContext paintContext), which basically should be equivalent to overriding paintComponent. 在挖掘Piccolo源代码时,似乎我需要覆盖它们的一个内部方法paint(PPaintContext paintContext),它基本上应该等同于覆盖paintComponent。

As discussed here , each Swing component has a UI delegate that calculates the correct preferred size for a component, given the user's chosen Look & Feel. 如所讨论的在这里 ,每个摆动部件具有计算用于一个组件的正确优选尺寸的UI代表,给定的用户选择的外观和感觉。 As a result, the most elegant solution is to let the layout manager leverage the components's preferred size. 因此,最优雅的解决方案是让布局管理器利用组件的首选大小。 Failing to do so often leads to his pathologic behavior . 如果不这样做往往导致他的病理行为 As shown here and here , you can validate() the enclosing container to obtain the desired geometry before setVisible() , but doing so is a sign that another approach may be warranted. 如此此处所示,您可以validate()封闭容器以在setVisible()之前获取所需的几何体,但这样做表明可能需要采用另一种方法。 As a concrete example, this BoxLayout example is better done using GroupLayout , illustrated here and here . 作为一个具体的例子,这个BoxLayout 示例最好使用GroupLayout完成, 这里这里说明。

Typically, you should only need to examine FontMetrics in order to calculate the preferred size of your own custom components, as shown here . 通常情况下,你应该只需要检查FontMetrics为了计算自己的自定义组件的首选尺寸,如图所示这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM