2012-12-15 4 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 - 여유 공간이 없어 질 때까지 행의 각 픽셀에 1 픽셀을 추가 할 것으로 예상됩니다. 그것은 정말 아주 기본적인 것 같아 전혀 그것의 모양에 영향을주지 않습니다. 25 픽셀의 자유 픽셀을 가지고 있다고 가정 해 봅시다. 왜 그 행에 25 개의 타일에 1 픽셀의 픽셀을 추가 할 수 없습니까? – 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()); 
     } 
} 
관련 문제