我正在创建一个游戏,其背景图像显示在上方。我想放置背景图像和卡片,使它们始终垂直和水平居中,即使在调整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);
答案 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);