I often have the problem that a Swing method or property requires the object to be realized. 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. 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:
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. 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.
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. 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. As a concrete example, this BoxLayout
example is better done using GroupLayout
, illustrated here and here .
Typically, you should only need to examine FontMetrics
in order to calculate the preferred size of your own custom components, as shown here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.