如何将两个JPanel添加到中心的JFrame?

时间:2013-11-25 00:21:35

标签: java swing jframe jpanel center

我正在创建一个游戏,其背景图像显示在上方。我想放置背景图像和卡片,使它们始终垂直和水平居中,即使在调整JFrame大小时也是如此。

目前,我正在创建卡片(每个都是JPanel)并将它们添加到容器JPanel(没有布局管理器)中,然后我将Jpanel添加到JFrame。之后,我将背景图像放在JPanel中,然后将该JPanel添加到JFrame。结果是:背景图像隐藏在卡片后面,并在根据需要移除每张卡片时显示。背景图像始终居中,但卡片的JPanel在调整大小时不会移动。无论我尝试什么,我都很难让卡片始终居中。我还需要在南边界的JFrame中添加另一个JPanel,因此也需要工作。感谢您的协助!

在扩展JFrame的类中:

setSize(1060,700);

cardPanel = new JPanel();
cardPanel.setSize(1060,700);
cardPanel.setOpaque(false);
cardPanel.setLayout(null);
...card.setLocation(x, y); //loop through cards
...cardPanel.add(card); //and add each one
add(cardPanel, BorderLayout.CENTER); //add cardPanel to JFrame

//Add background image
bgPanel = new JPanel();
URL url = getClass().getResource("images/dragon_bg.png"); 
imgIcon = new ImageIcon(url);
JLabel background = new JLabel(imgIcon);
bgPanel.setLayout(new BorderLayout());
bgPanel.add(background);
add(bgPanel, BorderLayout.CENTER);

setVisible(true);

2 个答案:

答案 0 :(得分:3)

  

我想放置背景图片和卡片,使它们始终垂直和水平居中,即使在调整JFrame大小时也是如此。

然后您需要在面板上使用布局管理器。布局管理器负责重做布局。

  

如何将两个JPanel添加到中心的JFrame中?

您可以尝试使用OverlayLayout。我认为基本代码是:

JPanel contentPane = new JPanel( new GrigBagLayo9ut() );
frame.add(contentPane, BorderLayout.CENTER);

JPanel overlay = new JPanel()
overlay.setLayout( new OverlayLayout(overlay) );
contentPane.add(overlay, new GridBagConstraints()); // this should center the overlay panel

overlay.add(yourCardPanel); // you care panel must use a suitable layout
overlay.add(new JLabel() ); // use a JLabel for the background not a custom panel
  

我还需要将另一个JPanel添加到南边界的JFrame中,

JFrame内容窗格的默认布局管理器是BorderLayout。我们已经将游戏面板添加到了中心,所以知道你只需将其他面板添加到南方。

如果OverlayLayout无法按您的方式工作,那么您将需要嵌套面板。类似的东西:

JPanel center = new JPanel( new GridBagLayout() );
frame.add(center, BorderLayout.CENTER);

JLabel background = new JLabel(...);
background.setLayoutManager( new GridBagLayout() );
center.add(background, new GridBagConstraints());

background.add(yourCardPanel, new GridBagConstraints());

编辑:

使用嵌套面板:

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

public class GridBagLayoutCenter extends JPanel
{
    public GridBagLayoutCenter()
    {
        setLayout( new BorderLayout() );

        JLabel background = new JLabel( new ImageIcon("mong.jpg") );
        background.setLayout( new GridBagLayout() );

        add(background, BorderLayout.CENTER);

        JPanel tiles = new JPanel();
        tiles.setPreferredSize( new Dimension(200, 200) );
        tiles.setBackground( Color.RED );
        background.add(tiles, new GridBagConstraints());

        add(new JLabel("SOUTH"), BorderLayout.SOUTH);
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("GridBagLayoutCenter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new GridBagLayoutCenter() );
        frame.setSize(400, 400);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

“瓷砖”面板的首选尺寸不应该是硬编码的。大小应由您的自定义布局管理器根据您添加到面板的切片确定。当瓷砖被移除时,尺寸不应该改变。

答案 1 :(得分:-1)

我最终决定将背景图片放在卡片面板中,然后将卡片面板放在盒子布局管理器中,以便它始终居中。我将cardPanel重命名为gameBoard。绝对可以更清洁,但我只能满足我的要求。

setSize(new Dimension(1000, 600));
gameBoard = new JPanel();
gameBoard.setLayout(null);
gameBoard.setOpaque(false);
Dimension expectedDimension = new Dimension(920, 500);
gameBoard.setPreferredSize(expectedDimension);
gameBoard.setMaximumSize(expectedDimension);
gameBoard.setMinimumSize(expectedDimension);
//add cards to gameBoard here

JLabel background = new JLabel( new ImageIcon( getClass().getResource("images/graphic.png") ) );
background.setLocation(79,0); //manually center graphic
background.setBounds(new Rectangle(0, 0, 920, 500));
gameBoard.add(background);

Box centerBox = new Box(BoxLayout.Y_AXIS);
centerBox.setOpaque(true); 
centerBox.setBackground(Color.WHATEVER);
centerBox.add(Box.createVerticalGlue());
centerBox.add(gameBoard);
centerBox.add(Box.createVerticalGlue());
add(centerBox);
setVisible(true);