7

我有一个扩展 JComponent 的自定义组件,它覆盖了 paintComponent(Graphics g) 方法,但是当我尝试将它添加到我的 JPanel 时它不起作用,没有绘制任何内容。这是我的代码:

public class SimpleComponent extends JComponent{

int x, y, width, height;

public SimpleComponent(int x, int y, int width, int height){
    this.x = x;
    this.y = y;
}

@Override
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(Color.BLACK);
    g2.fillRect(x, y, width, height);
}
}


public class TestFrame{
public static void main(String[] args){
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel.setPreferredSize(new Dimension(400, 400));
    frame.add(panel);
    frame.pack();
    frame.setResizable(false);

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
    panel.add(comp);
    frame.setVisible(true);
}
}
4

2 回答 2

4

它工作正常——组件被添加到 JPanel,但它有多大?如果你在 GUI 渲染后检查这个,你可能会发现你的组件的大小是 0, 0。

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
panel.add(comp);
frame.setVisible(true);

System.out.println(comp.getSize());

考虑让您的 JComponent 覆盖 getPreferredSize 并返回一个有意义的 Dimension:

public Dimension getPreferredSize() {
  return new Dimension(width, height);
}

如果您想使用 x 和 y,您可能也希望覆盖getLocation()

编辑
您还需要设置宽度和高度字段!

public SimpleComponent(int x, int y, int width, int height) {
  this.x = x;
  this.y = y;
  this.width = width; // *** added
  this.height = height; // *** added
}
于 2012-10-06T11:17:08.610 回答
-2

哇! 绝对不是正确答案!

您犯下的第一个绝对红衣主教罪是在非 EDT 线程中完成所有这些!!!这里没有篇幅可以解释……网络上只有大约 300 亿个地方可以了解它。

一旦所有这些代码Runnable在 EDT(事件调度线程)中执行,然后:

不需要覆盖preferredSize(尽管您可以根据需要)...但您确实需要设置它。

您绝对不应该直接设置大小(heightwidth,或setSize())!

您需要的是让java.awt.Container, panel, 在您的示例中“自行布局”......有一个方法Container.doLayout(),但正如 API 文档中所说:

使该容器布置其组件。大多数程序不应直接调用此方法,而应调用 validate 方法。

因此,解决方案是:

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100);
comp.setPreferredSize( new Dimension( 90, 90 ) );
panel.add(comp);

// the key to unlocking the mystery
panel.validate();

frame.setVisible(true);

顺便说一句,请从我的经验中获益:我已经花了好几个小时试图理解这一切validate, invalidate, paintComponent, paint,等等。我仍然觉得我只是触及了表面。

于 2016-02-18T19:27:57.297 回答