title: Why do getWidth() and getHeight() return 0 before paintComponent() is called?
body: <blockquote>
    <p><em>Edit:</em> <strong>I have solved the underlying problem.</strong> I used <code>SwingUtilities.invokeLater()</code> to solve the issue. My <a href="https://stackoverflow.com/questions/16615957/when-does-a-jtabbedpane-component-get-its-size">other question</a> provides more information for those who are interested.</p>
  </blockquote>
  
  <p>I have a GUI that displays an image on a <code>JPanel</code> in <code>paintComponent()</code> with <code>g.drawImage()</code>. I wrote a subclass of <code>JPanel</code> called <code>CanvasPanelView</code> to override <code>paintComponent()</code> and do a few other things, like set the bounds of where the image is drawn. The problem is that I need to get the JPanel's width and height and when I call <code>this.getWidth()</code> and <code>this.getHeight()</code> in the class that extends JPanel, they both return <code>0</code>.</p>
  
  <p>The process starts in an action listener inner class:</p>
  
  <pre><code>class MenuBarFileOpenListener implements ActionListener {
      public void actionPerformed(ActionEvent event) {
          File fileChooserReturnValue = view.showAndGetValueOfFileChooser();
  
          if (fileChooserReturnValue != null) {
              try {
                  DocumentModel newDocument = new DocumentModel(ImageIO.read(fileChooserReturnValue), fileChooserReturnValue.getAbsolutePath(), fileChooserReturnValue.getName());
                  model.addDocument(newDocument);
                  view.addDocument(newDocument);
              } catch(IOException ex) {
                  ex.printStackTrace();
              }
          }
      }
  }
  </code></pre>
  
  <p>Then, <code>addDocument()</code> is called:</p>
  
  <pre><code>public void addDocument(DocumentModel document) {
      menuBar_file_close.setEnabled(true);
  
      DocumentView newDocumentView = new DocumentView(document.getTitle(), documentsTabbedPaneCloseButtonListener);
  
      documentViews.add(newDocumentView); // add newDocumentView to ArrayList&lt;DocumentView&gt;
      newDocumentView.setDocument(document);
      documentsTabbedPane.add(newDocumentView.getCanvasPanelView());
  
      int newDocumentIndex = documentsTabbedPane.indexOfComponent(newDocumentView.getCanvasPanelView());
  
      documentsTabbedPane.setTabComponentAt(newDocumentIndex, newDocumentView.getTabPanel());
      documentsTabbedPane.setSelectedIndex(newDocumentIndex);
      newDocumentView.setBounds(document.getImageWidth(), document.getImageHeight());
  }
  
  public DocumentView(String title, ActionListener listener) {
      canvas = new CanvasPanelView();
      // more code...
  }
  </code></pre>
  
  <p><code>setBounds()</code> is called:</p>
  
  <pre><code>public void setBounds(int imageWidth, int imageHeight) {
      sourceX1 = 0;
      sourceY1 = 0;
      sourceX2 = imageWidth;
      sourceY2 = imageHeight;
  
      // some math...
  
      destinationX1 = 0 + xMargin;
      destinationY1 = 0 + yMargin;
      destinationX2 = drawWidth - xMargin;
      destinationY2 = drawHeight - yMargin;
  }
  </code></pre>
  
  <p><code>DocumentView</code> is a wrapper class for <code>CanvasPanel</code> and a few other things - it just groups together things that go with each open document.</p>
  
  <p>Everything seems to be instantiated and used or added to the <code>JTabbedPane</code>, so I don't know why <code>this.getWidth()</code> and <code>this.getHeight()</code> return <code>0</code>. Maybe something is happening between the end of <code>setBounds()</code> and <code>paintComponent()</code>.</p>
  
  <p>Why do <code>this.getWidth()</code> and <code>this.getHeight()</code> return <code>0</code>?</p>