简体   繁体   English

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

[英]How to add two JPanels to a JFrame in the center?

I am creating a game which has a background image with cards displayed overtop. 我正在创建一个具有背景图像的游戏,其中卡片显示在上方。 I would like to place the background image and cards such that they're always centered vertically and horizontally, even upon resizing the JFrame. 我想放置背景图像和卡片,使它们始终垂直和水平居中,即使在调整JFrame大小时也是如此。

Currently, I am creating the cards (each a JPanel) and adding them into a container JPanel (no layout manager), then I add that Jpanel to the JFrame. 目前,我正在创建卡(每个JPanel)并将它们添加到容器JPanel(没有布局管理器),然后我将Jpanel添加到JFrame。 After that I place the background image in a JPanel, then add that JPanel to the JFrame. 之后,我将背景图像放在JPanel中,然后将该JPanel添加到JFrame。 The result is: The background image is hidden behind the cards and revealed when removing each card as desired. 结果是:背景图像隐藏在卡片后面,并在根据需要移除每张卡片时显示。 The background image is always centered but the card's JPanel does not move around upon resize. 背景图像始终居中,但卡片的JPanel在调整大小时不会移动。 I am having a hard time getting the cards to always be centered, no matter what I try. 无论我尝试什么,我都很难让卡片始终居中。 I also need to add another JPanel to the JFrame in the South border, so that will need to work as well. 我还需要在南边界的JFrame中添加另一个JPanel,因此也需要工作。 I appreciate your assistance! 感谢您的协助!

In the class that extends JFrame: 在扩展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);

I would like to place the background image and cards such that they're always centered vertically and horizontally, even upon resizing the JFrame. 我想放置背景图像和卡片,使它们始终垂直和水平居中,即使在调整JFrame大小时也是如此。

Then you need to use layout managers on your panels. 然后,您需要在面板上使用布局管理器。 The layout manager is responsible for redoing the layout. 布局管理器负责重做布局。

How to add two JPanels to a JFrame in the center? 如何将两个JPanel添加到中心的JFrame?

You could try using the OverlayLayout for this. 您可以尝试使用OverlayLayout。 I think the basic code would be: 我认为基本代码是:

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

I also need to add another JPanel to the JFrame in the South border, 我还需要在南边境的JFrame中添加另一个JPanel,

The default layout manager for a JFrame's content pane is a BorderLayout. JFrame内容窗格的默认布局管理器是BorderLayout。 We already added the game panel to the center, so know you just add your other panel to the SOUTH. 我们已经将游戏面板添加到了中心,所以知道你只需将其他面板添加到南方。

If the OverlayLayout doesn't work the way you want then you will need to nest panels. 如果OverlayLayout无法按您的方式工作,那么您将需要嵌套面板。 Something like: 就像是:

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());

Edit: 编辑:

Using nested panels: 使用嵌套面板:

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();
            }
        });
    }
}

The preferred size of the "tiles" panel should not be hardcoded. “瓷砖”面板的首选尺寸不应该是硬编码的。 The size should be determined by your custom layout manager based on the tiles that you add to the panel. 大小应由您的自定义布局管理器根据您添加到面板的切片确定。 The size should not change as tiles are removed. 尺寸不应随着瓷砖的移除而改变。

I ultimately decided to place the background image in the card panel itself, then put the card panel in a box layout manager so that it's always centered. 我最终决定将背景图像放在卡片面板中,然后将卡片面板放在盒子布局管理器中,使其始终居中。 I renamed cardPanel to gameBoard. 我将cardPanel重命名为gameBoard。 Definitely could be cleaner, but I can only work with my requirements. 绝对可以更清洁,但我只能满足我的要求。

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM