java.awt.Label 派生类的paint(Graphics g) 方法未调用
Posted
技术标签:
【中文标题】java.awt.Label 派生类的paint(Graphics g) 方法未调用【英文标题】:paint(Graphics g) method of java.awt.Label derived class not called 【发布时间】:2022-01-02 04:57:54 【问题描述】:我儿子学校的课程仍然包括学习 Java AWT 的学生。虽然我觉得这不是最好的办法,但我也改不了,因为这是教育部规定的。无论如何,我试着帮助我儿子练习,就像我多年前自己编写的 AWT 一样。但是我在渲染标签时遇到了问题。我实际上是在 AWT 中创建一个简单的表,因为缺少表。方法是采用 GridLayout 并向其添加标签。这很好用,但我希望在列和行之间有分隔线。因此,我对标签进行了子分类并像这样覆盖了油漆:
在我做的 Table 类中
public class Table extends Container
...
this.setLayout(new GridLayout(rows+1, cols));
for(int i=0; i<cols; i++)
for(int y=0; y< rows; y++)
TableLabel label = new TableLabel(rowData[i][y].toString());
add(label);
...
指的是
public class TableLabel extends Label
public TableLabel(String labelText)
super(labelText);
public void paint(Graphics g)
super.paint(g);
System.out.println("paint");
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.BLUE);
g2.drawRect(getX(), getY(), getWidth(), getHeight());
public void update(Graphics g)
super.update(g);
System.out.println("update");
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.BLUE);
g2.drawRect(getX(), getY(), getWidth(), getHeight());
渲染没有改变。根据调试器的说法,无论是绘制还是更新都不会被调用。 println 也没有写入控制台。我错过了什么?该应用程序在 Java 11 下编译和运行。我知道,AWT 和版本 11 有点连线,但这是给定的设置。提前谢谢你。
【问题讨论】:
这里有一个关于 AWT 的快速教程,我正在看这个,也许会有帮助。上面的代码是否重现了问题? oracle.com/java/technologies/painting.html 我想在列和行之间有分隔线。 - 阅读GridLayout
API。您可以指定组件之间的水平/垂直间距。因此面板的背景将显示为您的线条。
你的绘画代码不正确:1)不需要重写update()。所有的绘画都是在paint() 方法中完成的。 2)绘画是相对于组件完成的,而不是面板。所以 x/y 值应该是 0,你需要从宽度/高度中减去 1。
【参考方案1】:
以下代码对我有用。你能扩展你的代码以包含一个可重现的问题吗?请准确描述问题所在,以便我们确定我们都在看同一件事。
public class AwtPaint
public static void main( String[] args )
SwingUtilities.invokeLater( AwtPaint::init );
private static void init()
JFrame frame = new JFrame();
Table myTable = new Table( 3, 3 );
frame.add( myTable );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
class Table extends Container
public Table( int rows, int cols )
this.setLayout(new GridLayout(rows+1, cols));
for(int i=0; i<cols; i++)
for(int y=0; y< rows; y++)
TableLabel label = new TableLabel( "Col: " + i + ", row: " + y );
add(label);
class TableLabel extends Label
public TableLabel(String labelText)
super(labelText);
public void paint(Graphics g)
super.paint(g);
System.out.println("paint");
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.BLUE);
g2.drawRect(getX(), getY(), getWidth(), getHeight());
public void update(Graphics g)
super.update(g);
System.out.println("update");
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.BLUE);
g2.drawRect(getX(), getY(), getWidth(), getHeight());
【讨论】:
总是添加@Override
。也许 - 我不确定 - drawRect(0, 0, ...
。无需致电super.paint
。【参考方案2】:
感谢您的所有反馈。我仍然不知道到底出了什么问题,但是当我按照 Joop 的建议输入“@Override”时,Eclipse 向我显示了一个错误,说我的签名未知。我看不出文档有什么不同,但删除了代码并再次创建了方法,这次使用的是 Eclipse 的 Overwrite 功能。现在它起作用了。可能是行中某处不可打印的字符?!
顺便说一下,虽然现在调用了paint,但蓝色边框仍未渲染。我用“setColor”替换了“setPaint”,但没有成功。我也尝试了设置hgap和vgap的提议,但是由于标签的背景颜色与表格的Container相同,因此间隙是不可见的。并且在设置容器的背景时,标签会更改,但容器不会更改。这是容器的问题。在我更改表不再扩展容器而是面板后,对表背景的更改不再转发到标签。现在我可以使用 setBackground 为表格和标签设置不同的颜色,因为我在 paint 方法中编码的任何内容都没有效果。我想有一个理由想出 Swing ;-)
【讨论】:
以上是关于java.awt.Label 派生类的paint(Graphics g) 方法未调用的主要内容,如果未能解决你的问题,请参考以下文章
使用 WS_EX_COMPOSITE 时不发送 WM_PAINT