简体   繁体   English

GridBagLayout 锚点精确度

[英]GridBagLayout anchor preciseness

Can I eliminate random red line around the container or this is a bug in JDK?我可以消除容器周围的随机红线还是这是 JDK 中的错误?

在此处输入图像描述

Full source code to reproduce the problem重现问题的完整源代码

import static java.awt.Color.red;
import static java.awt.Color.white;
import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.FIRST_LINE_END;
import static java.awt.GridBagConstraints.FIRST_LINE_START;
import static java.awt.GridBagConstraints.LAST_LINE_END;
import static java.awt.GridBagConstraints.LAST_LINE_START;
import static java.awt.GridBagConstraints.LINE_END;
import static java.awt.GridBagConstraints.LINE_START;
import static java.awt.GridBagConstraints.PAGE_END;
import static java.awt.GridBagConstraints.PAGE_START;
import static javax.swing.BorderFactory.createLineBorder;
import static javax.swing.JFrame.EXIT_ON_CLOSE;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

public class GridBagLayoutTest {
    
    public static void main(String[] args) {
        JPanel pane = new JPanel(new GridBagLayout());
        pane.setBackground(red);
        pane.setPreferredSize(new Dimension(500, 500));
        // pane.setBorder(createEmptyBorder());
        // pane.setBorder(createLineBorder(white, 1));
        pane.setBorder(createLineBorder(white, 2));
        // pane.setBorder(createLineBorder(white, 3));
        
        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.weighty = 1;
        c.gridx = 0;
        c.gridy = 0;
        c.anchor = FIRST_LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 1;
        c.gridy = 0;
        c.anchor = PAGE_START;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 0;
        c.anchor = FIRST_LINE_END;
        pane.add(rectangle(), c);
        c.gridx = 0;
        c.gridy = 1;
        c.anchor = LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 1;
        c.gridy = 1;
        c.anchor = CENTER;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 1;
        c.anchor = LINE_END;
        pane.add(rectangle(), c);
        c.gridx = 0;
        c.gridy = 2;
        c.anchor = LAST_LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 1;
        c.gridy = 2;
        c.anchor = PAGE_END;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 2;
        c.anchor = LAST_LINE_END;
        pane.add(rectangle(), c);
        
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 600));
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.getContentPane().setBackground(white);
        frame.getContentPane().add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    public static JPanel rectangle() {
        JPanel rect = new JPanel();
        rect.setBackground(white);
        rect.setPreferredSize(new Dimension(100, 100));
        return rect;
    }
}

this is a bug in JDK?这是JDK中的错误吗?

Well you are trying to use the GridBagLayout in a way it wasn't designed to be used.好吧,您正在尝试以一种并非旨在使用的方式使用 GridBagLayout。 You are trying to make a 5 component grid using 3 components in each row/column.您正在尝试使用每行/列中的 3 个组件创建一个 5 个组件网格。

The size of each cell is 500 / 3 = 166.666.每个单元格的大小为 500 / 3 = 166.666。

When you try to set the location of each component you are getting some rounding issues.当您尝试设置每个组件的位置时,您会遇到一些舍入问题。 Sometimes it rounds up and sometimes down.有时它向上取整,有时向下取整。

To check this you can get rid of the setBorder(...) statement and then after the setVisible() statement add:要检查这一点,您可以去掉 setBorder(...) 语句,然后在 setVisible() 语句之后添加:

for (Component panel: pane.getComponents())
    System.out.println(panel.getBounds());

and you will see output like:你会看到 output 像:

java.awt.Rectangle[x=1,y=1,width=100,height=100]
java.awt.Rectangle[x=200,y=1,width=100,height=100]
java.awt.Rectangle[x=399,y=1,width=100,height=100]
java.awt.Rectangle[x=1,y=200,width=100,height=100]
java.awt.Rectangle[x=200,y=200,width=100,height=100]
java.awt.Rectangle[x=399,y=200,width=100,height=100]
java.awt.Rectangle[x=1,y=399,width=100,height=100]
java.awt.Rectangle[x=200,y=399,width=100,height=100]
java.awt.Rectangle[x=399,y=399,width=100,height=100]

To fix the problem you can create a 5x5 grid and add each component to the appropriate cell in the grid:要解决此问题,您可以创建一个 5x5 网格并将每个组件添加到网格中的相应单元格:

import static java.awt.Color.red;
import static java.awt.Color.white;
import static java.awt.GridBagConstraints.CENTER;
import static java.awt.GridBagConstraints.FIRST_LINE_END;
import static java.awt.GridBagConstraints.FIRST_LINE_START;
import static java.awt.GridBagConstraints.LAST_LINE_END;
import static java.awt.GridBagConstraints.LAST_LINE_START;
import static java.awt.GridBagConstraints.LINE_END;
import static java.awt.GridBagConstraints.LINE_START;
import static java.awt.GridBagConstraints.PAGE_END;
import static java.awt.GridBagConstraints.PAGE_START;
import static javax.swing.BorderFactory.createLineBorder;
import static javax.swing.JFrame.EXIT_ON_CLOSE;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

import java.util.Arrays;

public class GridBagLayoutTest2 {

    public static void main(String[] args) {
        GridBagLayout gbl = new GridBagLayout();
        JPanel pane = new JPanel(gbl);
        pane.setBackground(red);
//        pane.setPreferredSize(new Dimension(500, 500));
        // pane.setBorder(createEmptyBorder());
        // pane.setBorder(createLineBorder(white, 1));
        pane.setBorder(createLineBorder(white, 2));
        // pane.setBorder(createLineBorder(white, 3));


        //  The minimimum width of a column is 100 pixels
        //  and the minimum height of a row is 100 pixels.

        int[] columns = new int[5];
        Arrays.fill(columns, 100);
        gbl.columnWidths = columns;

        int[] rows = new int[5];
        Arrays.fill(rows, 100);
        gbl.rowHeights = rows;

        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.weighty = 1;
        c.gridx = 0;
        c.gridy = 0;
//        c.anchor = FIRST_LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 0;
//        c.anchor = PAGE_START;
        pane.add(rectangle(), c);
        c.gridx = 4;
        c.gridy = 0;
//        c.anchor = FIRST_LINE_END;
        pane.add(rectangle(), c);
        c.gridx = 0;
        c.gridy = 2;
//        c.anchor = LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 2;
//        c.anchor = CENTER;
        pane.add(rectangle(), c);
        c.gridx = 4;
        c.gridy = 2;
//        c.anchor = LINE_END;
        pane.add(rectangle(), c);
        c.gridx = 0;
        c.gridy = 4;
//        c.anchor = LAST_LINE_START;
        pane.add(rectangle(), c);
        c.gridx = 2;
        c.gridy = 4;
//        c.anchor = PAGE_END;
        pane.add(rectangle(), c);
        c.gridx = 4;
        c.gridy = 4;
//        c.anchor = LAST_LINE_END;
        pane.add(rectangle(), c);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 600));
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.getContentPane().setBackground(white);
        frame.getContentPane().add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static JPanel rectangle() {
        JPanel rect = new JPanel();
        rect.setBackground(white);
        rect.setPreferredSize(new Dimension(100, 100));
        return rect;
    }
}

For the reason this works see: Creating a board game layout using JLayeredPane之所以可行,请参阅: 使用 JLayeredPane 创建棋盘游戏布局

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM