2013-05-16 75 views
2

我一直在環顧四周,致力於使JPanel能夠具有圖像背景。我知道有很多信息可以提供這一點(example 1example 2)。這些都不是我正在尋找的。Java - 具有背景圖像和正常功能的JPanel

我正在尋找的是一種方法,只是添加功能或功能,以設置一個背景圖像在JPanel同時保持一切。我現在面臨的問題是我有幾個類擴展了JPanel,當我改變它們以擴展新的ImagePanel類時,構造函數失敗(顯然,參數不同)。我爲這些文件中的一個創建了構造函數super(new BorderLayout());,並且目前爲止我可以使其運行的唯一方法是丟棄佈局或背景圖像。我無法一起工作。

以下是最新絕望的嘗試:

import java.awt.*; 
import javax.swing.JPanel; 

class ImagePanel extends JPanel { 

    private Image img; 

    public ImagePanel(Image img, LayoutManager layout) { 
    this.img = img; 
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null)); 
    setPreferredSize(size); 
    setMinimumSize(size); 
    setMaximumSize(size); 
    setSize(size); 
    setLayout(null); 
    super.setLayout(layout); 
    } 

    public void paintComponent(Graphics g) { 
    g.drawImage(img, 0, 0, null); 
    } 

} 

如果有人可以幫助我,或指向我往什麼我要找的,這將是巨大的。我不需要任何超級瘋狂的功能,如背景縮放或類似的東西。我只是想讓圖像成爲背景,並以其他方式維護其功能。

謝謝。

+0

您是否嚴格要「JPanel」,還是可以考慮其他組件? – afsantos

+0

那麼,我希望它只是一個'JPanel'。這似乎是最簡單的,功能明智的,但是再一次,我來這裏是有原因的。無論我猜測什麼作品。如果使用'JLabel'圖標方法有問題,所以我寧願使用「超級」'JPanel'來處理它。 –

+0

您可以簡單地使用'JLabel'並在其上設置適當的'LayoutManager'。順便說一句,不要調用'setPreferredSize(size); setMinimumSize(size); setMaximumSize(size); setSize(size); setLayout(null); '(實際上不推薦使用這些方法)。而是使用適當的'LayoutManager'。 –

回答

1

如果您樂於接受建議,可以考慮JLayeredPane

這些容器有層,每層都能夠存儲組件。
所以,你可能有一個JPanelJLabel在這個問題上,你的背景圖像在底層,並將其他任何其他JPanel,在更高層。

如果你想堅持你的ImagePanel,你可能應該打super.paintComponent以及。

class ImagePanel extends JPanel { 
     ... 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(img, 0, 0, this); 
    } 
} 
+1

你應該畫你調用'super.paintCOmponent'後的背景圖像,你應該傳遞'this'而不是'null'作爲'ImageObserver'。調用'super.paintComponent'與子組件無關。它僅默認執行默認UI委託所執行的操作。對於不透明的JPanel,它使用背景顏色填充面板,爲'JLabel'繪製文本和/或圖像等等...... –

+0

糾正我,如果我錯了,但不會調用'super 'drawImage'之前的'paintComponent'會將圖像*渲染到內部組件上,從而創建前景圖像,而不是? – afsantos

+1

編號'paintComponent'只繪製當前組件。 「孩子們的繪畫」由「paintChildren」進行。 'paint'方法將按照(近似)的順序調用:'paintComponent','paintBorder',然後'paintChildren'。所以,當你的代碼站立時,如果你的'ImagePanel'是不透明的,你永遠不會看到背景圖像。 –

2

施工人員不能在死者之間轉移。也就是說,如果你擴展一個類而不提供和父類相同的構造函數,那麼你就不能使用這些構造函數簽名。

例如,在您的示例源代碼中,不能調用new ImagePane(new BorderLayout()),因爲ImagePane沒有與該簽名匹配的構造函數,儘管JPanel的確如此。

這很重要,因爲它可以讓用戶使用特定的初始化路徑,該路徑對於您的類的版本可能是唯一的。

如果你想從父類重新使用現有的構造函數,那麼你需要自己的類中提供這些簽名或呼叫super(...);用必需的參數

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.LayoutManager; 
import javax.swing.JPanel; 

public class ImagePanel extends JPanel { 

    private Image img; 

    public ImagePanel(LayoutManager layout) { 
     super(layout); 
    } 

    public ImagePanel(Image img, LayoutManager layout) { 
     this(layout); 
     this.img = img; 
    } 

    public Image getImage() { 
     return img; 
    } 

    public void setImage(Image value) { 
     if (img != value) { 
      Image old = img; 
      img = value; 
      firePropertyChange("image", old, img); 
      revalidate(); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     Image img = getImage(); 
     return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(this), img.getHeight(this)); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (img != null) { 
      g.drawImage(img, 0, 0, this); 
     } 
    } 

} 

我也建議您可以通過Performing Custom Painting瞭解關於自定義繪畫的更多詳細信息...

+2

如果有兒童需要比圖片更多的空間,getPreferredSize()方法不應該返回最大尺寸嗎?我同意這可能有點挑剔;-) –

+0

@GuillaumePolet它是一個不錯的選擇,值得不。這將歸結爲OP想要做什麼。我(希望)展示了getPreferredSize的使用;)012( – MadProgrammer

+0

)_I(希望)展示了getPreferredSize_的使用。我同意這將歸結爲歐普想要做的事情。 +1 –