2013-11-25 114 views
0

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

目前,我正在创建卡片(每个JPanel)并将它们添加到容器JPanel(无布局管理器)中,然后将该Jpanel添加到JFrame中。之后,我将背景图像放入JPanel中,然后将JPanel添加到JFrame中。结果是:背景图像隐藏在卡片后面,并在根据需要移除每张卡片时显示。背景图片始终居中,但卡片的JPanel在调整大小时不会移动。无论我尝试什么,我都很难让卡片始终处于中心位置。我还需要将另一个JPanel添加到南边界的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); 
+1

1)Java GUI可能需要在多种平台上工作,使用不同的屏幕分辨率并使用不同的PLAF。因此,它们不利于组件的准确放置。为了组织强大的图形用户界面,请使用布局管理器或[它们的组合](http://stackoverflow.com/a/5630271/418556)以及[空格]的布局填充和边框(http: //stackoverflow.com/q/17874717/418556)。 2)为了更快地获得更好的帮助,请发布[SSCCE](http://sscce.org/)。 –

回答

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

-1,硬编码值不支持您对动态调整大小的要求。 “他们都没有为我工作。” - 我发布了一个工作示例。图像是否在框架中居中?红色面板不在图像上居中吗?它怎么不适合你?我给你的代码适用于使用空布局的瓦片面板。这不能满足你的要求?花点时间了解解决方案。如果我发布的示例没有反映出您的框架结构,那么反映您的结构的代码在哪里。这就是'SSCCE'的用途。 – camickr

+0

它绝对是动态调整大小。我告诉过你我的确切要求:固定中间面板始终保持居中,而框架动态调整大小。我无法改变我的要求,所以-1对我来说是荒谬的。不幸的是,我解决了这个问题,但不幸的是,因为我花了几个小时尝试每一个,但最终却没有奏效。 – Joey

+0

我给你的代码按原样工作。一切都以中心。您只需将一些组件添加到“tiles”面板并调整首选大小即可。 “最终没有奏效” - 这并没有描述问题。什么不行?你做了修改并打破了代码。当你不描述问题时,你如何期待帮助?使用BoxLayout并不是一个不好的解决方案。这是将组件集中到第二个最常见的方式。使用GridBagLayout更容易,因为你不需要担心粘合剂。如果BoxLayout有效,那么GridBagLayout也应该如此。 – camickr

3

我想放置背景图片和卡片,使得他们总是垂直和水平居中,即使在调整JFrame中。

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

如何将两个JPanels添加到中心的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(); 
      } 
     }); 
    } 
} 

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

+0

谢谢camickr。没有布局管理员将为我的cardPanel工作,所以我手动设置每个卡的位置。我尝试了Grid Bag的叠加,它几乎可以正常工作。卡片位于图形的顶部,它们都在调整大小时移动,但它们在右侧和底部被切断,并且不完全在框架中居中。我试着用setSize玩,但这没什么用。感谢您的建议。 – Joey

+0

'没有布局管理器会为我的工作CardPanel都' - 你为什么这么说?您可以轻松嵌套面板以获得您想要的效果。 “我试着用setSize玩,但这没什么用。”布局管理员希望设置首选大小,而不是大小。 – camickr

+0

我可以嵌套面板,但该卡板需要有没有布局管理器,因为它会是非常困难的用我的设计以其它方式实施。如果我用setPreferredSize替换setSize,它只会呈现标题栏。 – Joey