1

我只是在玩 Swing,并且正在开发一个非常简单的 Swing 组件。我有一个从JComponentclass 继承的组件,它的 UI 继承自ComponentUI. 该paint()方法如下所示:

public void paint(Graphics g, JComponent c) {
    int x = c.getX();
    int y = c.getY();
    c.setBounds(x, y, 100, 25);
    int width = c.getWidth();
    int height = c.getHeight();
    Rectangle r = g.getClipBounds();
    g.fillRect(0, 0, 10, 10);
    g.drawString("Baf!", 3, 3);
}

但是完全不可能得到r.height大于 1 的另一个值。组件是给定的宽度,但高度总是只有一个点。有没有其他人使用过类似的组件?不幸的是,没有任何简单的教程。所有教程都是难以理解的复杂(或过时)。

似乎布局管理器将此组件的大小始终调整为 1 高度(无论最小值)。

4

2 回答 2

5

您的代码有几个问题:

对于扩展 JComponent 的类的关注点:

  1. public void paint(Graphics g, JComponent c) {}

    不是一个有效的签名,所以你没有覆盖方法paint,而是创建一个新的paint方法。

  2. 你应该重写paintComponent(Graphics g) 方法而不是paint。

  3. 由于您正在扩展 JComponent,因此您需要首先在覆盖的 paintComponent 方法中调用 super.paintComponent(g) :

    public class JPanelExtended{ public void paintComponent(Graphics g){ super.paintComponent(g); ... } }

对于扩展 ComponentUI 的类,您甚至应该在超类上显式调用方法 paint:

public void paint(Graphics g, JComponent c) {
    super.paint(g,c);
}

编辑:一个小建议:当你想重写一个方法时,将@override 符号放在签名之前非常有用:

@Override
public void superMethodToBeOverridden(){}

这样,编译器将通过错误消息通知您,以防您定义新方法而不覆盖现有方法。

于 2011-09-13T14:14:52.447 回答
5

永远不要在绘画方法中调用 setBound()。这是布局管理器的工作,而不是您的绘画代码。

我猜主要问题(除了 Heisenbug 的观点)是你没有给你组件一个大小。这是通过覆盖 getPreferredSize() 以返回适合您的组件的大小来完成的。

阅读 Swing 教程中关于自定义绘画的部分以获取更多信息和工作示例。

于 2011-09-13T14:31:41.373 回答