2012-12-15 37 views
2

我对我而言似乎应该是一个非常简单的问题。在我看来,这只是对GridBagLayout ...GridBagLayout不会正确地在组件之间分配尺寸

的人的大规模监督。我正在使用GridBagLayout为我正在制作的游戏显示27x13的网格。我使用这种布局是因为它能够调整组件的大小,并且因为配置有多容易,但这只是一个小问题。如果宽度不是27的倍数,或者如果高度不是13的倍数,则会在边界周围放置空白区域。

为了说明我的意思:

Here是个什么样子,当我调整框架等,以使该JPanel内的大小864x416,27完美的倍数和13

Here是个什么样子就像当我调整框架的大小,使JPanel大小为863x415,只是几乎不是27或13的倍数。

它只是不在瓦片中分配额外的像素。我不知道为什么。当我用他们各自的方法摆弄最小/最大/首选大小,或者甚至使用GridBagLayoutipadxipady限制时,我可以删除空白区 - 但它只是挤压最外面的瓷砖以适应休息。你可以在下面的示例代码中看到它。

下面是一个SSCCE:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.util.Random; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Game extends JPanel { 
    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       start(); 
      } 
     }); 
    } 
    static void start() { 
     JFrame frame = new JFrame("Game"); 
     JPanel newFrame = new MainGameScreen(); 
     frame.getContentPane().add(newFrame); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
class MainGameScreen extends JPanel { 
    public MainGameScreen() { 
     setPreferredSize(new Dimension(864, 551)); 
     setLayout(new GridBagLayout()); 
     setBackground(Color.green); 
     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.fill = GridBagConstraints.BOTH; 
     gbc.weightx = 1; 
     gbc.weighty = 1; 
     gbc.ipadx = 0; //Change to 64 to see undesired effects 
     gbc.ipady = 0; //^ 
     for (int i=0;i<13;i++) { 
      for (int j=0;j<27;j++) { 
       gbc.gridx = j; 
       gbc.gridy = i; 
       add(new ImagePanel(), gbc); 
      } 
     } 
    } 
} 
class ImagePanel extends JComponent { 
    private int r,g,b; 
    public ImagePanel() { 
     Random generator = new Random(); 
     r = generator.nextInt(100)+1; 
     g = generator.nextInt(100)+1; 
     b = generator.nextInt(100)+1; 
    } 
    @Override 
    public void paintComponent(Graphics gr) { 
     super.paintComponent(gr); 
     gr.setColor(new Color(r,g,b)); 
     gr.fillRect(0, 0, getWidth(), getHeight()); 
    } 
} 

我的问题是,如何才能让布局不断看起来像第一个形象呢?我需要不同的布局吗?我很迷茫。

+0

有点偏离主题,但我会建议不要使用'GridBagLayout',除非你绝对必须。这只是市长头痛的IMO - 大部分相同的功能可以通过BoxLayout实现。 –

+0

由于每个瓷砖的重量与其他瓷砖的重量完全相同,并且由于像素不能在亚像素中切割,所以布局应如何平均分配27个部件中的像素? –

+0

@JBNizet - 我希望它会在行中增加一个像素的宽度,直到它没有更多的可用空间。它看起来非常基本,不会影响它的外观。假设它有25个免费像素,它向左推到右边。为什么不能在该行中添加一个像素宽度为25个图块? – Keter

回答

2

我将为具有正方形贴图的面板使用GridLayout,并将其嵌套到另一个布局(GridBagLayout,BorderLayout,BoxLayout或某些布局组合)中。

这就是说,GridLayout和GridBagLayout将在这种情况下均匀分布像素。由于您只能使用整个像素,所以在分割空间后剩余的余数将用作填充。这在很大程度上是不可避免的,虽然有一些可能的解决办法:

  • 执行某些窗口大小
  • 画一个更大的面板比你需要的,但使用一个视口,以便多余的瓷砖在视图中截断
  • 添加接壤的平铺面积,有效地隐瞒事实,有微胖

如果您能够接受的第一个选项等元素,你可以做一个稍微修改到窗口捕捉到兼容的尺寸,使得存在是没有剩余的(注:我也改变了d几个你的硬编码整数常量):

package com.example.game; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 
import java.util.Random; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

    public class Game extends JPanel {  
     public static void main(String[] args) { 
      javax.swing.SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        start(); 
       } 
      }); 
     } 

     static void start() { 
      final JFrame frame = new JFrame("Game"); 
      JPanel newFrame = new MainGameScreen(); 

      frame.addComponentListener(new ComponentAdapter() { 
       @Override 
       public void componentResized(ComponentEvent e) { 
        int h = frame.getContentPane().getHeight() % MainGameScreen.ROWS; 
        int w = frame.getContentPane().getWidth() % MainGameScreen.COLS; 

        // Subtract the remainder pixels from the size. 
        frame.setSize(frame.getWidth() - w, frame.getHeight() - h); 
       } 
      }); 
      frame.getContentPane().add(newFrame); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     } 
    } 
    class MainGameScreen extends JPanel { 
     static final int ROWS = 13; 
     static final int COLS = 27; 

     public MainGameScreen() { 
      setPreferredSize(new Dimension(864, 551)); 
      setLayout(new GridBagLayout()); 
      setBackground(Color.green); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.fill = GridBagConstraints.BOTH; 
      gbc.weightx = 1; 
      gbc.weighty = 1; 
      gbc.ipadx = 0; //Change to 64 to see undesired effects 
      gbc.ipady = 0; //^ 
      for (int i=0;i<ROWS;i++) { 
       for (int j=0;j<COLS;j++) { 
        gbc.gridx = j; 
        gbc.gridy = i; 
        add(new ImagePanel(), gbc); 
       } 
      } 
     } 
    } 

    class ImagePanel extends JComponent { 
     private int r,g,b; 
     public ImagePanel() { 
      Random generator = new Random(); 
      r = generator.nextInt(100)+1; 
      g = generator.nextInt(100)+1; 
      b = generator.nextInt(100)+1; 
     } 
     @Override 
     public void paintComponent(Graphics gr) { 
      super.paintComponent(gr); 
      gr.setColor(new Color(r,g,b)); 
      gr.fillRect(0, 0, getWidth(), getHeight()); 
     } 
}