我经常遇到这样的问题,Swing 方法或属性需要实现对象。例如,要在 JPanel 上绘图,我可能需要知道特定字体的高度,但此信息在面板实现后才可用,因此在此之前我将获得一个空指针。更糟糕的是,并不总是很清楚(至少对我而言)哪些方法需要实现对象,哪些不需要。
显然我可以做一些愚蠢的事情,比如:
- 绘制虚拟文本以强制实现
- 获取字体指标
- 删除虚拟文本
- 计算并绘制真实文本
不得不这样做似乎非常轻率。是否有更优雅的方式来强制实现,以便我可以可靠地访问字体指标?
典型示例代码:
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。
最佳答案
讨论 here ,每个 Swing 组件都有一个 UI 代理,它根据用户选择的外观和感觉为组件计算正确的首选大小。因此,最优雅的解决方案是让布局管理器利用组件的首选大小。不这样做通常会导致他的 pathologic behavior .如图here和 here ,您可以在 setVisible()
之前validate()
封闭容器以获得所需的几何形状,但这样做表明可能需要另一种方法。作为一个具体的例子,这个 BoxLayout
example最好使用 GroupLayout
来完成,如图 here和 here .
通常,您应该只需要检查 FontMetrics
来计算您自己的自定义组件的首选大小,如图所示 here .
关于java - 在 Java Swing 中实现实现的优雅方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22846448/