Swing:GridLayout 中的级联 JPanel 在调整大小时导致意外间隙
Swing: Cascaded JPanels in GridLayout causes unexpected gap on Resize
我遇到了级联 JPanel
s 和 GridLayout
s 的奇怪行为。
下面的演示展示了我的问题:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JPanelGridLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("JPanel GridLayout Demo");
int cols = 5, rows = 5;
int innerCols = 15, innerRows = 15;
frame.setLayout(new GridLayout(cols, rows, 0, 0));
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
JPanel panel = new JPanel();
panel.setBackground(new Color((int)(Math.random() * 0x1000000)));
// panel.setLayout(new GridLayout(cols, rows, 0, 0));
// fixed it as FastSnail suggested
panel.setLayout(new GridLayout(innerCols, innerRows, 0, 0));
frame.add(panel);
for (int innerCol = 0; innerCol < innerCols; innerCol++) {
for (int innerRow = 0; innerRow < innerRows; innerRow++) {
JPanel innerPanel = new JPanel();
innerPanel.setBackground(new Color((int)(Math.random() * 0x1000000)));
panel.add(innerPanel);
}
}
}
}
frame.setSize(new Dimension(400, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
这将显示以下面板:
我通常不会期望看到外面板的背景颜色。 GridLayout
通常表现为填充父容器。因此,当我将面板水平调整为特定的框架宽度时。然后按预期显示:
我再调整一下,差距又出现了。 frameSize % x == 0
似乎一切都很好,如果这有助于理解问题。
如何解决这个问题,使内部面板始终填满整个父容器?我必须覆盖 GridLayout
吗?
对我来说,这似乎是 GridLayout
的实施问题,例如舍入问题或其他问题。
我按照FastSnail的建议修复了内部GridLayouts
,缝隙没有变小但仍然可见:
背景information/Side问题:
我想渲染一个类似于此的可视化效果,首先想到的是像素级渲染。但我想提供悬停、突出显示、点击事件和动态调整大小,因此我在这种情况下使用面板。您认为其中有什么问题吗(性能问题除外)?
我发现 here(FastSnail 建议)GridLayout
由于其内部组件的大小计算而产生间隙。
因此,如果您有一个 100px
宽面板,它包含 15 个面板,其大小将达到 6px
(100/15 = 6.67
)。结果 10px
(100 - 6 * 15
) 导致间隙。
因此我将 GridLayout
更改为 MigLayout
,现在它按预期工作了:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class JPanelGridLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("JPanel GridLayout Demo");
int cols = 5, rows = 5;
int innerCols = 15, innerRows = 15;
// fill, remove margin, remove grid gaps
frame.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
JPanel panel = new JPanel();
panel.setBackground(new Color((int) (Math.random() * 0x1000000)));
panel.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));
// cell position, fill, min-width 1, min-height 1
frame.add(panel, String.format("cell %d %d, grow, w 1::, h 1::", col, row));
for (int innerCol = 0; innerCol < innerCols; innerCol++) {
for (int innerRow = 0; innerRow < innerRows; innerRow++) {
JPanel innerPanel = new JPanel();
innerPanel.setBackground(new Color((int) (Math.random() * 0x1000000)));
panel.add(innerPanel, String.format("cell %d %d, grow, w 1::, h 1::", innerCol, innerRow));
}
}
}
}
frame.setSize(new Dimension(400, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
我遇到了级联 JPanel
s 和 GridLayout
s 的奇怪行为。
下面的演示展示了我的问题:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JPanelGridLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("JPanel GridLayout Demo");
int cols = 5, rows = 5;
int innerCols = 15, innerRows = 15;
frame.setLayout(new GridLayout(cols, rows, 0, 0));
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
JPanel panel = new JPanel();
panel.setBackground(new Color((int)(Math.random() * 0x1000000)));
// panel.setLayout(new GridLayout(cols, rows, 0, 0));
// fixed it as FastSnail suggested
panel.setLayout(new GridLayout(innerCols, innerRows, 0, 0));
frame.add(panel);
for (int innerCol = 0; innerCol < innerCols; innerCol++) {
for (int innerRow = 0; innerRow < innerRows; innerRow++) {
JPanel innerPanel = new JPanel();
innerPanel.setBackground(new Color((int)(Math.random() * 0x1000000)));
panel.add(innerPanel);
}
}
}
}
frame.setSize(new Dimension(400, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
这将显示以下面板:
我通常不会期望看到外面板的背景颜色。 GridLayout
通常表现为填充父容器。因此,当我将面板水平调整为特定的框架宽度时。然后按预期显示:
我再调整一下,差距又出现了。 frameSize % x == 0
似乎一切都很好,如果这有助于理解问题。
如何解决这个问题,使内部面板始终填满整个父容器?我必须覆盖 GridLayout
吗?
对我来说,这似乎是 GridLayout
的实施问题,例如舍入问题或其他问题。
我按照FastSnail的建议修复了内部GridLayouts
,缝隙没有变小但仍然可见:
背景information/Side问题:
我想渲染一个类似于此的可视化效果,首先想到的是像素级渲染。但我想提供悬停、突出显示、点击事件和动态调整大小,因此我在这种情况下使用面板。您认为其中有什么问题吗(性能问题除外)?
我发现 here(FastSnail 建议)GridLayout
由于其内部组件的大小计算而产生间隙。
因此,如果您有一个 100px
宽面板,它包含 15 个面板,其大小将达到 6px
(100/15 = 6.67
)。结果 10px
(100 - 6 * 15
) 导致间隙。
因此我将 GridLayout
更改为 MigLayout
,现在它按预期工作了:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class JPanelGridLayoutDemo {
public static void main(String[] args) {
JFrame frame = new JFrame("JPanel GridLayout Demo");
int cols = 5, rows = 5;
int innerCols = 15, innerRows = 15;
// fill, remove margin, remove grid gaps
frame.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));
for (int col = 0; col < cols; col++) {
for (int row = 0; row < rows; row++) {
JPanel panel = new JPanel();
panel.setBackground(new Color((int) (Math.random() * 0x1000000)));
panel.setLayout(new MigLayout("fill, insets 0, gapx 0, gapy 0"));
// cell position, fill, min-width 1, min-height 1
frame.add(panel, String.format("cell %d %d, grow, w 1::, h 1::", col, row));
for (int innerCol = 0; innerCol < innerCols; innerCol++) {
for (int innerRow = 0; innerRow < innerRows; innerRow++) {
JPanel innerPanel = new JPanel();
innerPanel.setBackground(new Color((int) (Math.random() * 0x1000000)));
panel.add(innerPanel, String.format("cell %d %d, grow, w 1::, h 1::", innerCol, innerRow));
}
}
}
}
frame.setSize(new Dimension(400, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}