簡體   English   中英

GridBagLayout 錨點精確度

[英]GridBagLayout anchor preciseness

我可以消除容器周圍的隨機紅線還是這是 JDK 中的錯誤?

在此處輸入圖像描述

重現問題的完整源代碼

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;
    }
}

這是JDK中的錯誤嗎?

好吧,您正在嘗試以一種並非旨在使用的方式使用 GridBagLayout。 您正在嘗試使用每行/列中的 3 個組件創建一個 5 個組件網格。

每個單元格的大小為 500 / 3 = 166.666。

當您嘗試設置每個組件的位置時,您會遇到一些舍入問題。 有時它向上取整,有時向下取整。

要檢查這一點,您可以去掉 setBorder(...) 語句,然后在 setVisible() 語句之后添加:

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

你會看到 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]

要解決此問題,您可以創建一個 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;
    }
}

之所以可行,請參閱: 使用 JLayeredPane 創建棋盤游戲布局

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM