如何在Java(Swing)中使用GridBayLayout在我的框架中生成此特定图像?

期望的主GUI

基本上,我该如何生成这个? 我很确定这是GridBagLayout的工作,但是我无法理解如何正确调整’Action Pane’和’Menubar’的大小。 红色和黑色线条表示我认为您将在这种情况下使用的网格(3×3),但我可能完全错误,并且可能有一种方法可以在不同的配置中执行此操作。 我试图弄乱GridBagConstraints gridheightgridwidthgridheightgridwidth值,但我无法实现我的目标。

请注意,第二条红线应该恰好是框架下半部分高度的三分之一。

这是我最近的尝试,尝试使用3×6网格(c是GridBagConstraints对象,characterPortraits包含所有肖像,currentScreen是’Action Pane’):

 c.fill = GridBagConstraints.BOTH; c.weightx = 0.25; c.weighty = (1/6); c.gridx = 0; c.gridy = 0; c.gridheight = 3; pane.add(characterPortraits.get(0), c); c.gridx = 2; pane.add(characterPortraits.get(1), c); c.gridx = 0; c.gridy = 3; c.gridheight = 3; pane.add(characterPortraits.get(2), c); c.gridx = 2; pane.add(characterPortraits.get(3), c); //c.fill = GridBagConstraints.NONE; c.weightx = 1.0; c.weighty = 1.0; c.gridx = 1; c.gridy = 0; c.gridheight = 3; pane.add(currentScreen, c); 

相反,这会在其象限的底部三分之一处产生每个肖像,而动作窗格占据中心列的5/6而不是4/6,就像我想要的那样。 任何想法都会有所帮助 谢谢! -B。

编辑:我正在设计此应用程序以具有固定的窗口大小; 人们可能会说这是糟糕的设计,但我真的只是想要了解Swing组件,并确保它们至少按照我希望的方式在固定窗口中运行。 我想我可以允许最大限度地适当resize,但这就是它。

虽然,在我最奇怪的位置添加你的JMenuBar对我来说似乎很奇怪。 虽然你能做什么,但要克服你在这一行中提到的困难

 Instead, this produces each portrait in the bottom third of its quadrant, and the Action Pane taking 5/6 of the center column instead of 4/6, like I want it to. 

是在这个位置添加一个JPanel并将ActionPaneJmenuBar放到这个添加的JPanel ,以实现所需的结果。 所以我在这个位置添加了centerPanel来演示如何实现这一目标。

我希望这个输出是你想要的:

OUTPUT

以下是负责此输出的代码:

 import java.awt.*; import javax.swing.*; public class GridBagPanelLayout { private JPanel portrait1; private JPanel portrait2; private JPanel portrait3; private JPanel portrait4; private JPanel centerPanel; private JPanel actionPane; private void createAndDisplayGUI() { JFrame frame = new JFrame("GridBag JPanel Layout Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /* * This JPanel will serve as the * Content Pane, for the JFrame. */ JPanel contentPane = new JPanel(); contentPane.setOpaque(true); contentPane.setBackground(Color.WHITE); contentPane.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.FIRST_LINE_START; gbc.fill = GridBagConstraints.BOTH; gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.33; gbc.weighty = 0.5; gbc.gridheight = 2; portrait1 = new JPanel(); portrait1.setOpaque(true); portrait1.setBackground(Color.BLUE); portrait1.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.WHITE)); contentPane.add(portrait1, gbc); gbc.gridx = 1; gbc.gridy = 0; gbc.weighty = 1.0; gbc.gridheight = 4; centerPanel = new JPanel(); centerPanel.setOpaque(true); centerPanel.setBackground(Color.WHITE); centerPanel.setLayout(new GridBagLayout()); GridBagConstraints constCenter = new GridBagConstraints(); constCenter.anchor = GridBagConstraints.FIRST_LINE_START; constCenter.fill = GridBagConstraints.BOTH; constCenter.gridx = 0; constCenter.gridy = 0; constCenter.weightx = 1.0; constCenter.weighty = 0.975; actionPane = new JPanel(); actionPane.setOpaque(true); actionPane.setBackground(Color.MAGENTA); actionPane.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.WHITE)); centerPanel.add(actionPane, constCenter); constCenter.gridx = 0; constCenter.gridy = 1; constCenter.weighty = 0.025; centerPanel.add(getMenuBar(), constCenter); contentPane.add(centerPanel, gbc); gbc.gridx = 2; gbc.gridy = 0; gbc.weighty = 0.5; gbc.gridheight = 2; portrait3 = new JPanel(); portrait3.setOpaque(true); portrait3.setBackground(Color.BLUE); portrait3.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.WHITE)); contentPane.add(portrait3, gbc); gbc.gridx = 0; gbc.gridy = 2; //gbc.weighty = 0.5; //gbc.gridheight = 2; portrait2 = new JPanel(); portrait2.setOpaque(true); portrait2.setBackground(Color.BLUE); portrait2.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.WHITE)); contentPane.add(portrait2, gbc); gbc.gridx = 2; gbc.gridy = 2; gbc.weighty = 0.5; gbc.gridheight = 2; portrait4 = new JPanel(); portrait4.setOpaque(true); portrait4.setBackground(Color.BLUE); portrait4.setBorder( BorderFactory.createMatteBorder( 2, 2, 2, 2, Color.WHITE)); contentPane.add(portrait4, gbc); frame.setContentPane(contentPane); frame.setSize(500, 300); frame.setLocationByPlatform(true); frame.setVisible(true); } private JMenuBar getMenuBar() { JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu("File"); fileMenu.setOpaque(true); fileMenu.setBackground(Color.BLACK); fileMenu.setForeground(Color.WHITE); JMenuItem newItem = new JMenuItem("NEW"); JMenuItem openItem = new JMenuItem("OPEN"); fileMenu.add(newItem); fileMenu.add(openItem); JMenu editMenu = new JMenu("Edit"); editMenu.setOpaque(true); editMenu.setBackground(Color.BLACK); editMenu.setForeground(Color.WHITE); JMenuItem redoItem = new JMenuItem("Redo"); JMenuItem undoItem = new JMenuItem("Undo"); editMenu.add(redoItem); editMenu.add(undoItem); JMenu viewMenu = new JMenu("View"); viewMenu.setOpaque(true); viewMenu.setBackground(Color.BLACK); viewMenu.setForeground(Color.WHITE); JMenuItem zInItem = new JMenuItem("Zoom In"); JMenuItem zOutItem = new JMenuItem("Zoom Out"); viewMenu.add(zInItem); viewMenu.add(zOutItem); menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(viewMenu); menuBar.setOpaque(true); menuBar.setBackground(Color.BLACK); return menuBar; } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new GridBagPanelLayout().createAndDisplayGUI(); } }); } } 

我从来都不是GridBagLayout的忠实粉丝。 很难做到正确 – 每个组件最多可以有11个约束 – 它很难维护,重用相同的约束对象会导致意想不到的后果。

相反,我更喜欢嵌套各种类型的布局。 对我来说,你显然有:

  1. BorderLayout ,包含WestCenterEast面板
  2. West面板中,你有一个GridLayout – 2行,1列(Portraits 1和2)。
  3. East面板中,你有一个GridLayout – 2行,1列(Portraits 3和4)。
  4. Center面板中,您有另一个BorderLayout ,具有Center组件(Action Pane)和South组件(Menubar)。

唯一的限制是West面板和East面板没有逻辑连接。 如果肖像1,2,3和4都具有相同的尺寸,那不是问题。 如果它们的尺寸不同,您可能会发现西部和东部面板的形状会有所不同。