-->

Lining up components in a grid with grid-based bac

2019-07-12 02:46发布

问题:

I'm working on a college project and I'm having difficulty lining up components with the board grid. The board will always maintain a 1:1 width to height ratio but the size can vary. Here is what I've tried which resulted in this:

Why are the percentages not lining up with what I calculated them to be for the actual image size of 1200x1200?

Here's my layout code:

public class BoardPanel extends ViewComponent {

    public static final int ROWS = 27;
    public static final int COLS = 23;
    private Board board = new Board();

    private BufferedImage background = ResourceLoader.openImage("images/board.jpg");

    public BoardPanel() {
        this.add(board, "pos 4.5% 4.5%, width 76.5%, height 91%");           
    }

    @Override
    public void paintContent(Graphics2D g) {
        g.drawImage(background, 0, 0, getHeight(), getHeight(), null);
    }

    private class Board extends ViewComponent {

        public Board() {
            setLayout(new GridLayout(ROWS, COLS,  1, 1));

            for (int row = 0; row < ROWS; row++)
                for (int col = 0; col < COLS; col++)
                    this.add(new Location(row, col));
        }
    }
}

回答1:

As an alternative, use BufferedImage#getSubimage() to divide the image into congruent pieces, as shown here.



回答2:

I've figured out how to do this, and the answer comes when you look at the difference between GridLayout and MigLayout.

What happened was I had empty space (insets) when I used GridLayout because it forces all cells to be the same size. I noticed this when I added a 1px LineBorder.

The way MigLayout handles extra space is it seems to distribute the extra pixels among the cells, thereby forcing it to fix the container as ideally as possible. For example:

this.setLayout(new MigLayout("ins 0, wrap " + COLS + ", gap 1", "grow", "grow"));


        for (int row = 0; row < ROWS; row++)
            for (int col = 0; col < COLS; col++)
                this.add(new Location(row, col), "grow");

Which uses the exact same container and panel size as the grid layout shown here: (notice the insets)

this.setLayout(new GridLayout(ROWS, COLS, 1, 1));
this.setBorder(new LineBorder(Color.RED));


    for (int row = 0; row < ROWS; row++)
        for (int col = 0; col < COLS; col++)
            this.add(new Location(row, col));