如何使用Swing中的控件填充GridbagLayout的单元格?

时间:2016-03-02 19:51:45

标签: java swing jpanel layout-manager gridbaglayout

我需要设计一个摆动GUI,其顶部有一个带有菜单的JFrame,另一个主面板中间有三个面板,面板底部有一个单独的面板。用户界面所需的设计如下enter image description here 但是当我运行我的swing应用程序时,我得到这样的输出(所有面板都打包在窗口的中心)

enter image description here

以下是我的代码

import java.awt.*;
import javax.swing.*;

public class FrontEndView {
    private JFrame mainFrame;
    private JPanel mainPanel,subPanelUp,subPanelDown,panelLeft,panelRight,panelCenter,panelDown;
    private JScrollPane scrollPane;
    private JList logViewList;
    private JPanel panel1;

    public FrontEndView(){
        this.prepareGUI();
    }

    public void prepareGUI(){
        mainFrame=new JFrame("GUI");
        Toolkit tk = Toolkit.getDefaultToolkit();
        int xSize = ((int) tk.getScreenSize().getWidth());
        int ySize = ((int) tk.getScreenSize().getHeight());
        mainFrame.setSize(xSize,ySize);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setResizable(true);
        mainFrame.setLayout(new BorderLayout());

        mainPanel=new JPanel();
        mainPanel.setLayout(new GridBagLayout());
        mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

        GridBagConstraints gridbagConstMain = new GridBagConstraints();
        GridBagConstraints gridbagConstSub = new GridBagConstraints();

        subPanelUp=new JPanel();
        subPanelUp.setLayout(new GridBagLayout());
        subPanelUp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

        panelLeft=new JPanel();
        panelLeft.setBorder(BorderFactory.createTitledBorder("Message Defs"));
        gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
        gridbagConstSub.weightx = 0.5;
        gridbagConstSub.gridx = 0;
        gridbagConstSub.gridy = 0;
        subPanelUp.add(panelLeft, gridbagConstSub);

        panelCenter=new JPanel();
        panelCenter.setBorder(BorderFactory.createTitledBorder("Main Workspace"));
        gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
        gridbagConstSub.weightx = 0.5;
        gridbagConstSub.gridx = 1;
        gridbagConstSub.gridy = 0;
        subPanelUp.add(panelCenter, gridbagConstSub);

        panelRight=new JPanel();
        panelRight.setBorder(BorderFactory.createTitledBorder("Script Viewer"));
        gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
        gridbagConstSub.weightx = 0.5;
        gridbagConstSub.gridx = 2;
        gridbagConstSub.gridy = 0;
        subPanelUp.add(panelRight, gridbagConstSub);

        mainPanel.add(subPanelUp,gridbagConstMain);

        subPanelDown=new JPanel();
        subPanelDown.setLayout(new BorderLayout());
        panelDown=new JPanel();
        panelDown.setBorder(BorderFactory.createTitledBorder("Log View"));
        logViewList= new JList();
        panelDown.add(logViewList);
        gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
        //gridbagConst.ipady=20;
        //gridbagConst.weightx = 0.0;
        gridbagConstSub.gridwidth = 5;
        gridbagConstSub.gridx = 0;
        gridbagConstSub.gridy = 0;
        subPanelDown.add(panelDown,BorderLayout.PAGE_END);
        mainPanel.add(subPanelDown, gridbagConstSub);

        scrollPane=new JScrollPane(mainPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        mainFrame.add(scrollPane);
        mainFrame.setVisible(true);
    }

    public static void main(String[] args){
        FrontEndView  frontEnd = new FrontEndView();
    }
}

我想用设计中显示的相关面板/控件来填充GridBagLayout的单元格,并且每个面板都应该在其中填充控件(我需要在panelDown中添加一个JList,其大小应该是是panelDown JPanel的大小。。我不需要在我的JFrame中看到任何额外的空间。请指导我的代码中缺少的内容。

2 个答案:

答案 0 :(得分:2)

我建议您使用具有不同布局管理器的嵌套面板来解决问题。

框架的默认布局是BorderLayout。

因此,您可以创建一个面板并将其添加到PAGE_END,以便在底部显示整个宽度。

然后您可以创建另一个使用GridLayout的面板。然后,您可以向此面板添加3个子面板,每个面板可以使用自己的布局。然后将此面板添加到框架的中心。随着帧大小的改变,额外的空间将被分配给CENTER,因此面板将动态增长。

编辑:

太多的面板让我花时间了解正在发生的事情

我建议这样的结构:

frame (which by default uses a BorderLayout)
--- CENTER
    panel using GrigBagLayout
        childPanel1
        childPanel2
        childPanel3
---- PAGE_END
    JScrollPane containing the JList

创建JList时,基本代码为:

JList list = new JList(...);
list.setVisibleRowCount(5); 
JScrollPane scrollPane = new JScrollPane( list );

无需创建面板只是为了将列表添加到另一个面板。设置可见行数的关键是给JList一个固定的高度。然后,滚动窗格将根据需要显示在滚动窗格中。

现在PAGE_END有一个固定的高度组件,所有空间的重置将转到你添加到帧的CENTER的组件。

  

所有面板都打包在窗口的中央)

使用GridBagLayout时,面板将以其首选大小显示。如果所有面板的总尺寸小于滚动窗格的尺寸,那么它们将位于中心。如果您希望面板填充可用空间,那么我相信您需要使用weightx / y约束。阅读How to Use GridBagLayout上的Swing教程中描述所有约束的部分。

这就是我建议使用GridLayout的原因。它将使所有面板具有相同的大小,并且将填充滚动窗格的视口而不会使用约束。

mainFrame.add(menubar,BorderLayout.NORTH);

这不是你如何在框架中添加菜单栏。

您应该使用:

mainFrame.setJMenuBar(menuBar);

你在上一个问题中被告知了这一点。你为什么不听建议?当你不注意所建议的内容时,我们为什么要花时间去帮助。

答案 1 :(得分:0)

根据您的说明,我改变了我的设计方式,所有外部面板都与边框布局一起使用,而内部最多的控件则根据要求与Grid,GridBag和FlowLayouts一起使用。通过这种方式,整个设计可以很好地完成。

此外,如果需要扩展布局单元格中的特定面板,我会在需要时使用setPreferredSize(new Dimension(int,int))。