Java 为什么上传照片时我的gui布局会改变?

Java 为什么上传照片时我的gui布局会改变?,java,image,swing,layout-manager,gridbaglayout,Java,Image,Swing,Layout Manager,Gridbaglayout,我的程序用户界面目前使用网格袋布局,我希望它是一个固定的大小,但是当我上传一张图片到标签时,整个界面的尺寸会发生变化 下面是我的布局管理器的代码 public SearchService() throws Exception { setSize(600, 600); setResizable(false); JPanel mainPanel = new JPanel(); JPanel templatePanel = new J

我的程序用户界面目前使用网格袋布局,我希望它是一个固定的大小,但是当我上传一张图片到标签时,整个界面的尺寸会发生变化

下面是我的布局管理器的代码

public SearchService() throws Exception {

        setSize(600, 600);
        setResizable(false);

        JPanel mainPanel = new JPanel();
        JPanel templatePanel = new JPanel();
        JPanel toolPanel = new JPanel();

        JLabel picLabel = new JLabel();
        JLabel tools = new JLabel("Tools");
        JLabel templates = new JLabel("Templates");

        JButton upload = new JButton("Upload");
        JButton search = new JButton("Search");
        JButton save = new JButton("Save");

        //Main panel
        GridBagLayout GBPanel = new GridBagLayout();
        GridBagConstraints GBC = new GridBagConstraints();
        mainPanel.setLayout( GBPanel );

        //Template panel
        GBC.gridx = 0;
        GBC.gridy = 0;
        GBC.gridwidth = 1; 
        GBC.gridheight = 3; 
        GBC.fill = GridBagConstraints.BOTH; 
        GBC.weightx = 1; 
        GBC.weighty = 0;
        GBC.anchor = GridBagConstraints.WEST;
        GBPanel.setConstraints( leftPanel, GBC );
        leftPanel.add(templates); 
        mainPanel.add( leftPanel ); 

        //Picture label
        GBC.gridx = 1;
        GBC.gridy = 0;
        GBC.gridwidth = 2;
        GBC.gridheight = 1;
        GBC.fill = GridBagConstraints.BOTH;
        GBC.weightx = 0;
        GBC.weighty = 1;
        GBC.anchor = GridBagConstraints.CENTER;
        GBPanel.setConstraints( picLabel, GBC );
        mainPanel.add( picLabel );

        //Tool panel
        GBC.gridx = 4;
        GBC.gridy = 0;
        GBC.gridwidth = 1;
        GBC.gridheight = 3;
        GBC.fill = GridBagConstraints.BOTH;
        GBC.weightx = 1;
        GBC.weighty = 0;
        GBC.anchor = GridBagConstraints.EAST;
        GBPanel.setConstraints( rightPanel, GBC );
        rightPanel.add(tools);
        mainPanel.add( rightPanel );

        //Upload button
        GBC.gridx = 1;
        GBC.gridy = 1;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.fill = GridBagConstraints.BOTH;
        GBC.weightx = 1;
        GBC.weighty = 0;
        GBC.anchor = GridBagConstraints.PAGE_START;
        GBPanel.setConstraints( upload, GBC );
        mainPanel.add( upload );

        //Save button
        GBC.gridx = 2;
        GBC.gridy = 1;
        GBC.gridwidth = 1;
        GBC.gridheight = 1;
        GBC.fill = GridBagConstraints.BOTH;
        GBC.weightx = 1;
        GBC.weighty = 0;
        GBC.anchor = GridBagConstraints.PAGE_START;
        GBPanel.setConstraints( save, GBC );
        mainPanel.add( save );

        //Search button
        GBC.gridx = 1;
        GBC.gridy = 2;
        GBC.gridwidth = 2;
        GBC.gridheight = 1;
        GBC.fill = GridBagConstraints.BOTH;
        GBC.weightx = 1;
        GBC.weighty = 0;
        GBC.anchor = GridBagConstraints.PAGE_START;
        GBPanel.setConstraints( search, GBC );
        mainPanel.add( search );

        add(mainPanel);
下面是添加图片的代码

upload.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser("C:\\Users); 
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Image", "jpg", "png", "bmp");
                chooser.setFileFilter(filter);
                int result = chooser.showOpenDialog(null);

                if (result == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = chooser.getSelectedFile();
                    BufferedImage bi;
                    userPhoto = chooser.getSelectedFile().getPath();

                    try {
                        bi = ImageIO.read(selectedFile);
                        Image dimg = bi.getScaledInstance(picLabel.getWidth(), picLabel.getHeight(), Image.SCALE_SMOOTH);
                        picLabel.setIcon(new ImageIcon(dimg));
                    }
                    catch(IOException IOe) {
                        IOe.printStackTrace();
                    }
                    System.out.println(userPhoto);
                }
            }
        });
我已经添加了两张照片来显示我的程序的结果。这是我第一次跑步时的样子,也是我希望布局保持不变的方式

这就是上传图像后布局的外观

正如您所看到的,左右面板缩小了,图片甚至没有占据整个图片标签

我还添加了这行System.out.println(picLabel.getWidth());在action listener中,我看到当第一次点击按钮时,大小设置为299,但如果我再次点击按钮,它会改变,并且每次都会改变。我想知道是否有可能使图像保持在299的宽度

    GBC.gridwidth = 5; 
    GBC.gridheight = 20
不能只是将gridwith/height随机分配给组件。如果要使构件跨越与其他构件相同的高度,实际上需要20个其他构件

正如您所看到的,左右面板缩小了,图片甚至没有占据整个图片标签

如果不希望更改布局,请使用不同的布局管理器或具有不同布局管理器的嵌套面板

例如,从
边框布局开始

然后,您可以将面板添加到
行\u开始
行\u结束

然后,您需要在
中心的另一个面板
。同样,您可以使用
边框布局
。您可以将图片添加到
中心
,然后在
页面末尾添加另一个带有按钮的面板

现在,除了图像之外,所有组件的大小都是固定的。图像的可用空间将根据帧的大小而变化

因此,基本准则是:

JPanel buttonPanel = new JPanel(...);
JLabel image = new JLabel(...);

JPanel center = new JPanel( new BorderLayout() );
center.add(image, BorderrLayout.CENTER);
center.add(buttonPanel, BorderLayout.PAGE_END);

JPanel leftPanel = new JPanel(...);
JPanel rightPanel = new JPanel(...);

frame.add(leftPanel, BorderLayout.LINE_START);
frame.add(center, BorderLayout.CENTER);
frame.add(rightPanel, BorderLayout.LINE_END);
与尝试使用GridBagLayout的所有约束相比,它更容易混淆


现在,子面板(左、右、按钮)可以使用适当的布局管理器。

感谢您提供的解决方案,但如果可能,我想保留使用的布局管理器,但我已经修复了它。关于您的第一点,我编辑了文章,以显示我如何将网格宽度和高度更改为适当的数字“我真的很想用叉子喝汤,但你要我用勺子。”。如何使用叉子?”有时你需要为正确的工作使用正确的工具。网格包布局用于动态布局,而不是固定布局。此用例类似于BorderLayout的海报子级。1)为了更快地获得更好的帮助,请添加或。2)获取图像的一种方法例如,热链接到中看到的图像。例如,热链接到中嵌入的图像。