无论输入什么值,GridBagLayout 都不会移动组件?

问题描述

我目前有一个 jpanel,其布局设置为 GridBagLayout,gbc = new GridBagConstraints();,但是对于 x、y 或 gridwidth、gridheight 的任何值,项目根本不会移动。

我非常感谢专家的眼光来查看我的代码以了解我遗漏了什么,提前致谢。

编辑:添加导入和主要方法

编辑 2:原来我认为 x 和 y 值是像素,这就是它不起作用的原因

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
public class HomeScreenUI {
    
      public void addobjects(Component componente,Container yourcontainer,GridBagLayout layout,GridBagConstraints gbc,int gridx,int gridy,int gridwidth,int gridheight){

            gbc.gridx = gridx;
            gbc.gridy = gridy;

            gbc.gridwidth = gridwidth;
            gbc.gridheight = gridheight;

            layout.setConstraints(componente,gbc);
            yourcontainer.add(componente);
        }
    HomeScreenUI(){
        //frame
        
        JFrame frame = new JFrame("Opisa");

        //panels,one before button click and one after
        JPanel panel = new JPanel();
        JPanel panelAfterButtonClick = new JPanel();
        GridBagLayout ourlayout;
        
        ourlayout = new GridBagLayout();
        panel.setLayout(ourlayout);
        panelAfterButtonClick.setLayout(ourlayout);
        
        GridBagConstraints gbc = new GridBagConstraints();

        //jlabel that isnt displaying + dimensions
        JLabel label = new JLabel("Opisa");
        label.setFont(new Font("Helvetica",Font.PLAIN,70));
        //second jlabel that isn't displaying
        JLabel label2 = new JLabel("Home");
        label2.setFont(new Font("Helvetica",70));
        
        //adding the labels to the panels
        panel.add(label);
        panelAfterButtonClick.add(label2);
        
        //button that is displaying both before and after
        JButton button = new JButton("Click Me..");
        JButton buttonAfterClick = new JButton("Clicked Me..");
        
        //adding the buttons to the jpanel
        this.addobjects(label,panel,ourlayout,gbc,3,1);
        this.addobjects(button,700,100,2,0);

        this.addobjects(label2,panelAfterButtonClick,200,1,1);
        this.addobjects(buttonAfterClick,10,0);
        
        //function that changes the panel after the button is clicked
        button.addActionListener(new ActionListener() {

              public void actionPerformed(ActionEvent event) {
                  frame.setContentPane(panelAfterButtonClick);
                  frame.invalidate();
                  frame.validate();
              }

            });
        //adding the panel to the frame and setting the size
        frame.add(panel);
        frame.setSize(720,1280);
        frame.setVisible(true);
    }
}
public static void main (String args[]) {
        HomeScreenUI hs = new HomeScreenUI();
}

解决方法

看来您使用的 GridBagLayout 与其设计用途完全不同。 请注意,您有一个 GridBagLayout 实例,但想将其用于两个面板。每个面板都需要有自己的 LayoutManager 实例。

然后看看你有多少 GridBagConstraints。每个要添加的组件都需要有自己的实例才能正确管理。

然后有一些奇怪的值传递到 GridBagConstraints 中。我建议您花点时间完成How to Use GridBagLayout

,

我修改了您的代码以创建以下 GUI。

Opisa GUI

这是左键单击按钮后的样子。

Home GUI

您可以在两个面板之间来回切换。

以下是我对您的代码所做的主要更改。

  1. 代码应该像一篇文章一样组织起来。最重要的代码应该放在最前面,然后是不太重要的代码。

  2. 将您的代码分解为方法和类。每种方法都应该做一件事并做好。这称为 separation of concerns,它可以帮助您一次专注于代码的一部分。

  3. 为了启动 Swing 应用程序,我调用了 SwingUtilities invokeLater 方法。此方法可确保在 Event Dispatch Thread 上创建和执行所有 Swing 组件。

  4. JFrame 代码位于类构造函数中。 JFrame 代码必须按特定顺序调用。这是我用于大多数 Swing 应用程序的顺序。不要忘记调用 setDefaultCloseOperation 方法。当您关闭 JFrame.EXIT_ON_CLOSE 时,JFrame 参数会退出应用程序。

  5. 我用一个 CardLayout 来容纳两个下属 JPanels。我用自己的方法创建了 CardLayout

  6. 我用自己的方法创建了每个从属 JPanel。我对两个下属 GridBagLayout 都使用了 JPanels。正如您在代码中看到的,您必须设置相当多的 GridBagConstraints 参数。

  7. 我为每个 ActionListener 创建了一个匿名 JButtonsActionListeners 交换 JPanels 中的两个从属 CardLayout

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class HomeScreenUI {

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new HomeScreenUI();
            }
        });
    }
    
    private CardLayout cardLayout;
    
    private JPanel cardPanel;
    
    public HomeScreenUI() {
        JFrame frame = new JFrame("Opisa");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        this.cardPanel = createCardPanel();
        frame.add(cardPanel,BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createCardPanel() {
        cardLayout = new CardLayout();
        JPanel panel = new JPanel(cardLayout);
        
        panel.add(createOpisaPanel(),"Opisa");
        panel.add(createHomePanel(),"Home");
        
        return panel;
    }
    
    private JPanel createOpisaPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5,5,5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5,5);
        gbc.gridx = 0;
        gbc.gridy = 0;

        // jlabel that isnt displaying + dimensions
        JLabel label = new JLabel("Opisa");
        label.setFont(new Font("Helvetica",Font.PLAIN,72));
        panel.add(label,gbc);
        
        gbc.gridy++;
        JButton button = new JButton("Click Me..");
        // function that changes the panel after the button is clicked
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                cardLayout.show(cardPanel,"Home");
            }
        });
        panel.add(button,gbc);

        return panel;
    }

    private JPanel createHomePanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5,5));
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5,5);
        gbc.gridx = 0;
        gbc.gridy = 0;

        // second jlabel that isn't displaying
        JLabel label2 = new JLabel("Home");
        label2.setFont(new Font("Helvetica",72));
        panel.add(label2,gbc);
        
        gbc.gridy++;
        JButton buttonAfterClick = new JButton("Clicked Me..");
        buttonAfterClick.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                cardLayout.show(cardPanel,"Opisa");
            }
        });
        panel.add(buttonAfterClick,gbc);

        return panel;
    }
    
}