【问题标题】:Why do getWidth() and getHeight() return 0 before paintComponent() is called?为什么 getWidth() 和 getHeight() 在调用 paintComponent() 之前返回 0?
【发布时间】:2013-05-11 14:21:54
【问题描述】:

编辑: 我已经解决了根本问题。我使用SwingUtilities.invokeLater() 解决了这个问题。我的other question 为有兴趣的人提供更多信息。

我有一个 GUI,可以在 paintComponent()g.drawImage() 中的 JPanel 上显示图像。我编写了一个名为CanvasPanelViewJPanel 子类来覆盖paintComponent() 并做一些其他事情,比如设置图像绘制位置的边界。问题是我需要获取 JPanel 的宽度和高度,当我在扩展 JPanel 的类中调用 this.getWidth()this.getHeight() 时,它们都返回 0

流程从动作监听器内部类开始:

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();
            }
        }
    }
}

然后,addDocument() 被调用:

public void addDocument(DocumentModel document) {
    menuBar_file_close.setEnabled(true);

    DocumentView newDocumentView = new DocumentView(document.getTitle(), documentsTabbedPaneCloseButtonListener);

    documentViews.add(newDocumentView); // add newDocumentView to ArrayList<DocumentView>
    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...
}

setBounds() 被调用:

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;
}

DocumentViewCanvasPanel 和其他一些东西的包装类 - 它只是将每个打开的文档附带的东西组合在一起。

一切似乎都被实例化并使用或添加到JTabbedPane,所以我不知道为什么this.getWidth()this.getHeight()返回0。也许在setBounds()paintComponent() 之间发生了一些事情。

为什么this.getWidth()this.getHeight() 返回0

【问题讨论】:

  • getWith() 返回 0,因为当时的组件 大小为零,但为什么,我不确定。我认为您还没有提出一个可以回答的问题,因为您可能遗漏了太多对于了解您为什么会看到错误所必需的内容,并且还留下了许多与问题无关的代码。如果您没有很快得到很好的答案,请考虑创建并发布sscce
  • 与您的 sscce 一起提及和显示的相关内容包括包含图像显示组件的容器的布局以及如何将组件添加到容器中。
  • 同意,对,那么答案可能很简单
  • 我必须假设您收到的两个答案已经充分回答了您的问题。祝你好运。
  • 在您的sscce 中,通过URL 访问发布的图像,如here 所示,或使用合成图像,如here 所示。

标签: java swing jpanel paintcomponent


【解决方案1】:

你为什么不把你的documentView放在一个Panel(BorderLayout)中,而不是做一个'setBounds',在一个位置,比如BorderLayout.CENTER?

或者,您可以根据图像尺寸设置 documentview 的最小和首选尺寸。

【讨论】:

    【解决方案2】:

    你写了一个类,CanvasPanelView。这个类扩展了JPanel。看来,在您对setBounds 的实现中,您没有提及getHeight()getWidth() 所指的JPanel 的成员。因此,底层对象的高度为 0,宽度为 0。

    如果您希望使用JPanel 值作为高度和宽度,那么您只需确保为它们分配值。

    【讨论】:

      猜你喜欢
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2012-12-11
      • 2014-05-23
      • 1970-01-01
      相关资源
      最近更新 更多