JPanel 的宽度和高度为 0(特定情况)

SDs*_*ver 1 java layout swing jpanel

如果这很难理解,请原谅我,但我有一个特定的问题需要帮助解决。我做了大量的研究,我尝试了很多解决方案,但没有一个有效。

我的问题是我有一个ImagePanel正在扩展的类JPanel(下面的代码),这个类需要使用宽度和高度来缩放图像(我正在制作一个程序,用户可以在其中创建自定义教程,包括图像)。当我实例化它时,我收到一条错误消息,指出宽度和高度必须非零。我知道这是因为布局管理器尚未通过ImagePanel首选大小,但是我不知道如何将该大小传递给面板。的ImagePanel是内部的JPanel,其是一个内部JSplitPane一个内部JScrollPane一个内部JPanel一个的内部JTabbedPane一个的内部JSplitPane的一个内JFrame。容器递减顺序的图形表示如下:

  1. JFrame(网格布局)
  2. JSplitPane(默认 SplitPane 布局)
  3. JTabbedPane(默认 JTabbedPane 布局)
  4. JPanel(网格布局)
  5. JScrollPane(默认 ScrollPane 布局)
  6. JSplitPane(默认 SplitPane 布局)
  7. JPanel (GridLayout);
  8. 图像面板

ImagePanel 的代码如下:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class ImagePanel extends JPanel{

    private BufferedImage i;
    private ImageIcon miniature;
    private Image paint = null;

    public void createImage(String path){
        try {                
            i = ImageIO.read(new File(path));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        if(i != null){
            int width = (int)((double)i.getWidth() * ((double)getWidth()/i.getWidth()));
            int height = (int)((double)i.getHeight()*i.getHeight()/i.getWidth()*((double)this.getHeight()/i.getHeight()));
            miniature = new ImageIcon(i.getScaledInstance(width, height, Image.SCALE_SMOOTH));
            paint = miniature.getImage();
        }

    }


    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        if (paint!=null){
            g.drawImage(paint, 0, 0, null);}     
    }

}
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到合适的大小ImagePanel。我希望图像的大小随 的大小而变化JFrame,这就是为什么我不只使用setPreferedSize();.

cam*_*ckr 5

我希望图像随着 JFrame 的大小改变大小

您可以使用 Darryl 的Stretch Icon ,而不是在您自己的组件中进行自定义绘画。图标将根据可用空间自动调整大小。

这就是为什么我不只是使用“setPreferedSize();”。

如果您确实使用自定义绘画,则不应使用 setPreferredSize()。您应该覆盖该getPreferredSize()方法以返回图像的大小。请记住,首选大小只是对布局管理器的建议。布局管理器可以使用或忽略大小。

如果你想在你的paintComponent()方法中自动缩放图像,那么代码应该是:

Dimension d = getSize();
g.drawImage(paint, 0, 0, d.width, d.height, this);
Run Code Online (Sandbox Code Playgroud)

因此,您代码中的真正挑战(无论您选择哪种解决方案)是确保您使用的布局管理器将为您的组件提供所有可用空间,以便可以自动缩放图像。