ImageIcon 超出 window,调整大小 window 会扩展所有组件而不是显示更多组件

ImageIcon extends beyond window, resizing window expands all of components instead of showing more

private void setupGUI(){
    // Setup Frame
    f = new JFrame("Shape Image Generator");
    f.setBounds(500, 150, 450, 350);
    f.setLayout(new GridLayout(8,1));
    f.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent windowEvent){
           System.exit(0);
        }
    });
}

我创建了上面的框架,然后是 8 个面板。我创建了各种组件并将它们添加到面板中,一切正常。直到我创建了一个 ImageIcon 并将其添加到标签并将该标签添加到第 8 个面板。使用的图像是 140x129 像素。问题是,只有顶部……可能显示了图像的 1/4。如果我更改代码中的框架尺寸,每个面板之间会创建更多空白 space,但只显示稍微多一点的图像,因此图像仍然在屏幕之外。我会说 window 很容易为它显示的图像每多 1 个像素添加 10 个像素的间距。如果我拖动 window 的角来展开它,同样的事情也会发生。如果 window 最大化,我仍然只能看到我现在非常拉伸的图像的一半多一点。

我尝试过的事情:

  1. None 我的组件设置了首选尺寸,但我尝试为标签设置首选尺寸,然后是包含 ImageIcon 的面板,它只添加了图像和首选尺寸之间的差异图像上方的灰色 space 大小,将其推离屏幕更远。所以,我取消了。

  2. 将包含 ImageIcon 的标签添加到另一个不是第 8 个和最后一个面板的面板,在这种情况下,图像仍然被切断,但在它被切断的地方,它下方面板上的组件出现(在切断图像的背景颜色之上)。

  3. 用大约 30 种不同的措辞方式对这种情况进行了详尽的谷歌搜索,但没有找到解决方案。

(第 1 行 - 第 8 行是 JPanel,我没有包括它们的编码)

    ImageIcon iconStart = createImageIcon("/images/ShapeClipart.png", "Shapes");
    JLabel imgLabel = new JLabel();
    row8.add(imgLabel);

    // Add image to image label
    imgLabel.setIcon(iconStart);

    // Add panels to frame
    f.add(row1);
    f.add(row2);
    f.add(row3);
    f.add(row4);
    f.add(row5);
    f.add(row6);
    f.add(row7);
    f.add(row8);

    f.setVisible(true);

Window at execution

Window when stretched

编辑: 添加 f.pack() 会使 window 变得非常高瘦(windows 高度比我的屏幕高)但是当我手动展开 window (空 space 在面板之间,图像部分在屏幕外),即使我取出 f.setBounds 并且只使用 f.setLocation.

您正在使用 GridLayout。这为所有封闭的面板提供了相同数量的 space。在这种情况下,它是一个垂直网格。

您可能应该使用一些不同的东西。我可能会尝试在 JFrame 中使用 BorderLayout,并将包含前七个面板的面板(在 GridLayout 中)放入 CENTER,然后将 JLabel 放入 JFrame 的 SOUTH 部分。

还有其他布局方式,但这是我第一个想到的。

GridLayout makes each cell in the grid the same size and the size of each cell is determined by the largest Component 包含在网格中。

在您的代码中,图标是最大的组件,并且您的网格中也只有一列,因此每一行的高度都与您的图标相同。

由于您还通过调用方法 setBounds() 限制了 JFrame 的大小,因此 Swing 基础结构切断了图标,以便所有组件都适合进入您指定的范围。

一种替代方法(但不是唯一的替代方法)是使用 BoxLayout,因为它使用其包含的每个组件的首选大小。

这是一个与您发布的屏幕截图相匹配的示例 GUI,并使用 BoxLayout

import static javax.swing.WindowConstants.EXIT_ON_CLOSE;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import java.net.URL;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

public class Shapes23 implements Runnable {
    private JFrame  frame;

    @Override // java.lang.Runnable
    public void run() {
        showGui();
    }

    private JPanel createEighthRow() {
        JPanel eighthRow = new JPanel();
        URL url = getClass().getResource("paint-bursht.jpg");
        Icon ico = new ImageIcon(url);
        JLabel label = new JLabel(ico);
        eighthRow.add(label);
        return eighthRow;
    }

    private JPanel createFifthRow() {
        JPanel fifthRow = new JPanel();
        JTextField textField = new JTextField(20);
        fifthRow.add(textField);
        return fifthRow;
    }

    private JPanel createFirstRow() {
        JPanel firstRow = new JPanel();
        JLabel label = new JLabel("2D Shapes");
        firstRow.add(label);
        return firstRow;
    }

    private JPanel createFourthRow() {
        JPanel fourthRow = new JPanel();
        fourthRow.add(createRadioButton("Sphere"));
        fourthRow.add(createRadioButton("Cube"));
        fourthRow.add(createRadioButton("Cone"));
        fourthRow.add(createRadioButton("Cylinder"));
        fourthRow.add(createRadioButton("Torus"));
        return fourthRow;
    }

    private JPanel createMainPanel() {
        JPanel mainPanel = new JPanel();
        BoxLayout layout = new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS);
        mainPanel.setLayout(layout);
        mainPanel.add(createFirstRow());
        mainPanel.add(createSecondRow());
        mainPanel.add(createThirdRow());
        mainPanel.add(createFourthRow());
        mainPanel.add(createFifthRow());
        mainPanel.add(createSixthRow());
        mainPanel.add(createSeventhRow());
        mainPanel.add(createEighthRow());
        return mainPanel;
    }

    private JRadioButton createRadioButton(String text) {
        JRadioButton radioButton = new JRadioButton(text);
        return radioButton;
    }

    private JPanel createSecondRow() {
        JPanel secondRow = new JPanel();
        secondRow.add(createRadioButton("Circle"));
        secondRow.add(createRadioButton("Rectangle"));
        secondRow.add(createRadioButton("Square"));
        secondRow.add(createRadioButton("Triangle"));
        return secondRow;
    }

    private JPanel createSeventhRow() {
        JPanel seventhRow = new JPanel();
        JButton button = new JButton("Enter");
        seventhRow.add(button);
        return seventhRow;
    }

    private JPanel createSixthRow() {
        JPanel sixthRow = new JPanel();
        JTextField textField = new JTextField(20);
        sixthRow.add(textField);
        return sixthRow;
    }

    private JPanel createThirdRow() {
        JPanel thirdRow = new JPanel();
        JLabel label = new JLabel("3D Shapes");
        thirdRow.add(label);
        return thirdRow;
    }

    private void showGui() {
        frame = new JFrame("Shape Image Generator");
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.add(createMainPanel(), BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Shapes23());
    }
}

这是其外观的屏幕截图。请注意,我找不到与您的屏幕截图中相同的图标,所以我使用了不同的图标。