强制显示JLabel子类

时间:2014-01-28 09:00:48

标签: java image swing jlabel subclassing

我有一个扩展JLabel的类,用于在标签的整个innerArea上显示图像。
为此,我像这样覆盖paintComponent:

protected void paintComponent(Graphics g) {

    super.paintComponent(g);

    if(image != null) {
        SwingUtilities.calculateInnerArea(this, innerArea);
        g.drawImage(image, 0, 0, innerArea.width, innerArea.height, this);
    }

}

我认为它应该使用构造函数,如下所示:

public ImageLabel(String img) {

    super();
    this.image = new ImageIcon(this.getClass().getResource(img)).getImage();
    repaint();

}

但我有问题,标签基本没有尺寸,因为它没有实际内容 使用super(" ");时,所有内容都看起来像我实际预期的那样。

现在我想知道 - 这是解决这个问题的合法方法还是我错过了其他一些(可能更好)的方式?

2 个答案:

答案 0 :(得分:2)

虽然技术上你可以在JLabel绘画,但最好是在JPanel上绘画。您拥有的代码似乎很好,只需将其转换为JPanel

  

“但我有问题,标签基本上没有尺寸,因为它没有实际内容。”

绘画时,您还要记得覆盖getPreferredSize()。 paint并不是真正的内容,所以没有优先大小。它通过传递参数的原因是传递给它的String是content,这使得标签的首选大小与传递给它的String相匹配。但就像我说的那样,使用像这样的JPanel

public class ImagePanel extends JPanel {
    private final int D_W = 400;
    private final int D_W = 400;
    private BufferedIMage imag;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
    }

    @Override 
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }
}

答案 1 :(得分:1)

peeskillet已经给出了适当的答案(https://stackoverflow.com/a/21401576/3182664)。但是,为了实现通常的行为(即遵守Component#setPreferredSize(Dimension)方法设置的常规合同),实际上应该覆盖getPreferredSize()方法:

@Override 
public Dimension getPreferredSize() {
    if (isPreferredSizeSet()) {
        return super.getPreferredSize();
    }
    return new Dimension(D_W, D_H);

    // Could also return this, to make the panel's 
    // preferred size match the image size
    //return new Dimension(image.getWidth(this), image.getHeight(this));
}