简单的自定义Swing JComponent总是平坦的

Tom*_* K. 1 java swing paint jcomponent paintcomponent

我正在玩Swing,我正在研究一个非常简单的Swing组件.我有一个继承自JComponent类的组件,它的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);
}
Run Code Online (Sandbox Code Playgroud)

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

看起来,布局管理器总是将此组件的大小调整为1个高度(无论最小值).

Hei*_*bug 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);
}
Run Code Online (Sandbox Code Playgroud)

编辑:一个小建议:当你想覆盖一个方法时,在签名之前放置@override表示法是非常有用的:

@Override
public void superMethodToBeOverridden(){}
Run Code Online (Sandbox Code Playgroud)

这样,在您定义新方法而不是覆盖现有方法的情况下,编译器会通知您错误消息.


cam*_*ckr 5

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

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

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