我可以消除容器周圍的隨機紅線還是這是 JDK 中的錯誤?3x3 網格使用未按預期作業的約束
添加了 9 個尺寸更小的組件。enchor

重現問題的完整源代碼
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;
}
}
uj5u.com熱心網友回復:
這是JDK中的錯誤嗎?
好吧,您正在嘗試以一種并非旨在使用的方式使用 GridBagLayout。您正在嘗試使用每行/列中的 3 個組件創建一個 5 個組件網格。
每個單元格的大小為 500 / 3 = 166.666。
當您嘗試設定每個組件的位置時,您會遇到一些舍入問題。有時它向上取整,有時向下取整。
要檢查這一點,您可以去掉 setBorder(...) 陳述句,然后在 setVisible() 陳述句之后添加:
for (Component panel: pane.getComponents())
System.out.println(panel.getBounds());
你會看到如下輸出:
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 創建棋盤游戲布局
編輯:
GridLayout 有同樣的問題。如果父面板的寬度/高度不能被 GridLayout 中的組件數整除,那么組件將不會填滿整個空間,并且父面板的背景會透出來。
作為您提供的代碼的破解,您可以使用:
Border line = new LineBorder(Color.WHITE);
Border empty = new EmptyBorder(-1, -1, -1, -1);
Border compound = new CompoundBorder(line, empty);
pane.setBorder(compound);
這將允許繪制 LineBorder 而不會影響面板中組件的位置,因為邊框插入將保持 (0, 0, 0, 0)。
您還應該能夠使用 MatteBorder 并且只繪制底線并相應地調整 EmptyBorder。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/416542.html
標籤:
