簡體   English   中英

調用setPreferredSize()后,getWidth()和getHeight()為0

[英]getWidth() and getHeight() are 0 after calling setPreferredSize()

我現在已經在我的項目上工作了幾個小時,但卻一直對此感到沮喪。

我有一個父JFrame,它添加了一個JPanel,它將用於渲染和顯示我正在開發的模擬。 沒有將要添加到JPanel的swing對象,因為我將僅使用它來使用圖形對象渲染形狀。

我的代碼如下:

public class SimulationPanel extends JPanel {

private BufferedImage junction;
private Graphics2D graphics;

public SimulationPanel() {
    super();
    initPanel();

}

private void initPanel() {
    this.setPreferredSize(new Dimension(600, 600)); //TODO: bug with not sizing the junction correctly.
    junction = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
    graphics = junction.createGraphics();
    setBackground(Color.white);


    System.out.println(getWidth());
}

代碼專門在initPanel()方法的第二行中斷,我嘗試創建一個新的BufferedImage。

異常的輸出聲明“線程中的異常”AWT-EventQueue-0“java.lang.IllegalArgumentException:Width(0)和height(0)必須> 0”

我真的不確定為什么會這樣。 我試圖使用Stack Overflow的過去的答案,但他們沒有成功幫助。

這是我的第一篇文章,所以我希望它不是太糟糕。

謝謝。

設置首選大小時,可以告訴各種Java布局管理器在將面板添加到容器后如何布置面板。 但是直到它實際上被添加到容器中,它將沒有寬度或高度,即使在它之后,它可能沒有你要求的寬度和高度。

一種選擇是直接使用600作為新緩沖圖像的寬度和高度,當您將面板添加到JFrame時,請確保在JFrame上調用pack()以允許窗口大小調整為您的首選大小面板。

在組件的paintComponent方法中創建一個BufferedImage緩存。 在那里,您將知道組件的實際大小,並將其考慮在內以進行渲染。 該圖像充當組件內容的緩存,但您未考慮其大小是緩存信息的一部分。

@Override protected void paintComponent(Graphics g) {
  // create cache image if necessary
  if (null == image ||
      image.getWidth() != getWidth() ||
      image.getHeight() != getHeight() ||) {
    image = new BufferedImage(getWidth(), getHeight());
    imageIsInvalid = true;
  }

  // render to cache if needed
  if (imageIsInvalid()) {
    renderToImage();
  }

  // redraw component from cache
  // TODO take the clip into account
  g.drawImage(image, 0, 0, null);
}

這不起作用的原因是沒有調用pack() (設置所有的寬度和高度值),直到面板啟動之后,這就是為什么還沒有設置高度和寬度。 如果寬度或高度是非正整數,BufferedImage將拋出異常。

那你為什么不自己設定價值呢? 以下是在您的示例中如何執行此操作:

private void initPanel() {
    final int width = 600;
    final int height = 600;
    this.setPreferredSize(new Dimension(width, height));
    junction = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    graphics = junction.createGraphics();
    setBackground(Color.white);
}

或者:如果您需要使用組件調整圖像大小,則需要。 我很確定在調用pack()時會觸發ComponentListener.componentResized()事件,因此即使您沒有調整組件大小,這也應該在您啟動組件時起作用。 所以在你的代碼中這樣做:

private void initPanel() {
    this.setPreferredSize(new Dimension(600, 600));

    this.addComponentListener(new ComponentListener() {

        public void componentResized(ComponentEvent e) {
            Component c = (Component) e.getSource();
            Dimension d = c.getSize();
            resizeImage(d);
        }

    });

    this.setBackground(Color.white);
}

public void resizeImage(Dimension d) {
    junction = new BufferedImage(d.getWidth(), d.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
    graphics = junction.createGraphics();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM