如何用Swing中的控件填充GridbagLayout的Cells?
How to fill Cells of GridbagLayout with the controls in Swing?
我需要设计一个 swing GUI,它有一个 JFrame,顶部有一个菜单,另一个主面板在中央有另外三个面板,面板底部有一个单独的面板。 UI需要的设计如下
但是当我 运行 我的 swing 应用程序时,我得到这样的输出(所有面板都挤在 window 的中心)
下面是我的代码
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();
}
}
我想用设计中显示的相关 panel/control 填充 GridBagLayout 的单元格,并且每个面板都应该在内部填充控件(我需要在 panelDown 中添加一个 JList,其大小应该是 panelDown JPanel 的大小)。简单地说,我不需要在我的 JFrame 中看到任何额外的 space。请指导我的代码中缺少什么。
我建议您可以使用具有不同布局管理器的嵌套面板来解决问题。
框架的默认布局是 BorderLayout。
因此您可以创建一个面板并将其添加到 PAGE_END,以便它在底部显示整个宽度。
然后您可以创建另一个使用 GridLayout 的面板。然后,您可以向该面板添加 3 个子面板,每个面板都可以使用自己的布局。然后将此面板添加到框架的中心。随着框架大小的变化,额外的 spaces 将分配给中心,因此面板将动态增长。
编辑:
面板太多,我无法花时间了解正在发生的事情
我建议的结构是这样的:
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 有一个固定高度的组件,space 的所有重置都将转到您添加到框架中心的组件。
all the panels are packed in the center of the window)
当您使用 GridBagLayout 时,面板以其首选大小显示。如果所有面板的总大小小于滚动窗格的大小,那么它们将位于中心。如果您希望面板填充 space 可用,那么我相信您需要使用 weightx/y 约束。阅读 Swing 教程中关于 How to Use GridBagLayout 的部分,其中描述了所有约束。
这就是我建议改用 GridLayout 的原因。它将使所有面板的大小相同,并在不使用约束的情况下填充滚动窗格的视口。
mainFrame.add(menubar,BorderLayout.NORTH);
这不是向框架添加菜单栏的方式。
您应该使用:
mainFrame.setJMenuBar(menuBar);
你在上一个问题中被告知了这一点。为什么不听劝告???当您不注意建议时,我们为什么要花时间提供帮助。
根据您的说明,我更改了我的设计,所有外部面板都与 Border Layout 一起使用,而带有更多控件的最内部面板根据需要与 Grid、GridBag 和 FlowLayouts 一起使用。这样整个设计就可以很好的完成了。
此外,如果需要扩展布局单元格中的特定面板,我会在需要时使用 setPreferredSize(new Dimension(int,int))。
我需要设计一个 swing GUI,它有一个 JFrame,顶部有一个菜单,另一个主面板在中央有另外三个面板,面板底部有一个单独的面板。 UI需要的设计如下
下面是我的代码
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();
}
}
我想用设计中显示的相关 panel/control 填充 GridBagLayout 的单元格,并且每个面板都应该在内部填充控件(我需要在 panelDown 中添加一个 JList,其大小应该是 panelDown JPanel 的大小)。简单地说,我不需要在我的 JFrame 中看到任何额外的 space。请指导我的代码中缺少什么。
我建议您可以使用具有不同布局管理器的嵌套面板来解决问题。
框架的默认布局是 BorderLayout。
因此您可以创建一个面板并将其添加到 PAGE_END,以便它在底部显示整个宽度。
然后您可以创建另一个使用 GridLayout 的面板。然后,您可以向该面板添加 3 个子面板,每个面板都可以使用自己的布局。然后将此面板添加到框架的中心。随着框架大小的变化,额外的 spaces 将分配给中心,因此面板将动态增长。
编辑:
面板太多,我无法花时间了解正在发生的事情
我建议的结构是这样的:
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 有一个固定高度的组件,space 的所有重置都将转到您添加到框架中心的组件。
all the panels are packed in the center of the window)
当您使用 GridBagLayout 时,面板以其首选大小显示。如果所有面板的总大小小于滚动窗格的大小,那么它们将位于中心。如果您希望面板填充 space 可用,那么我相信您需要使用 weightx/y 约束。阅读 Swing 教程中关于 How to Use GridBagLayout 的部分,其中描述了所有约束。
这就是我建议改用 GridLayout 的原因。它将使所有面板的大小相同,并在不使用约束的情况下填充滚动窗格的视口。
mainFrame.add(menubar,BorderLayout.NORTH);
这不是向框架添加菜单栏的方式。
您应该使用:
mainFrame.setJMenuBar(menuBar);
你在上一个问题中被告知了这一点。为什么不听劝告???当您不注意建议时,我们为什么要花时间提供帮助。
根据您的说明,我更改了我的设计,所有外部面板都与 Border Layout 一起使用,而带有更多控件的最内部面板根据需要与 Grid、GridBag 和 FlowLayouts 一起使用。这样整个设计就可以很好的完成了。
此外,如果需要扩展布局单元格中的特定面板,我会在需要时使用 setPreferredSize(new Dimension(int,int))。