Java Swing中WrapLayout窗口快速调整大小时换行异常问题
Swing组件快速调整窗口大小时换行异常问题
运行以下示例代码需依赖MigLayout(Swing版):
public class TestFrame extends JFrame { public TestFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(800, 500)); JTabbedPane pane = new JTabbedPane(); pane.addTab("TestFrame", new Panel1()); add(pane); pack(); setVisible(true); } /** * level-1 panel, also contains other components * I just add incorrect panel(Panel2) here */ class Panel1 extends JPanel { public Panel1() { MigLayout layout = new MigLayout(); setLayout(layout); add(new Panel2(), new CC().cell(0, 0).growX().pushX()); } } /** * level-2 panel, also contains other components * I just add incorrect panel(CheckBoxesPanel) here */ class Panel2 extends JPanel { public Panel2() { MigLayout layout = new MigLayout(); setLayout(layout); add(new CheckBoxesPanel(), new CC().cell(0, 0).growX().pushX()); } } class CheckBoxesPanel extends JPanel { public CheckBoxesPanel() { WrapLayout layout = new WrapLayout(WrapLayout.LEADING); setLayout(layout); for (int i = 0; i < 20; i++) { add(new JCheckBox("JCB" + i)); } } } public static void main(String[] args) { new TestFrame(); } class WrapLayout extends FlowLayout { public WrapLayout() { super(); } public WrapLayout(int align) { super(align); } public WrapLayout(int align, int hGap, int vGap) { super(align, hGap, vGap); } @Override public Dimension preferredLayoutSize(Container target) { return layoutSize(target, true); } @Override public Dimension minimumLayoutSize(Container target) { Dimension minimum = layoutSize(target, false); minimum.width -= (getHgap() + 1); return minimum; } private Dimension layoutSize(Container target, boolean preferred) { synchronized (target.getTreeLock()) { Container container = target; while (container.getSize().width == 0 && container.getParent() != null) { container = container.getParent(); } int targetWidth = container.getSize().width; if (targetWidth == 0) { return new Dimension(); } int hGap = getHgap(); int vGap = getVgap(); Insets insets = target.getInsets(); int horizontalInsetsAndGap = insets.left + insets.right + (hGap * 2); int maxWidth = targetWidth - horizontalInsetsAndGap; Dimension dim = new Dimension(0, 0); int rowWidth = 0; int rowHeight = 0; int count = target.getComponentCount(); for (int i = 0; i < count; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize(); if (rowWidth + d.width >= maxWidth) { addRow(dim, rowWidth, rowHeight); rowWidth = 0; rowHeight = 0; } if (rowWidth != 0) { rowWidth += hGap; } rowWidth += d.width; rowHeight = Math.max(rowHeight, d.height); } } addRow(dim, rowWidth, rowHeight); dim.width += horizontalInsetsAndGap; dim.height += insets.top + insets.bottom + vGap * 2; Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target); if (scrollPane != null && target.isValid()) { dim.width -= (hGap + 1); } return dim; } } private void addRow(Dimension dim, int rowWidth, int rowHeight) { dim.width = Math.max(dim.width, rowWidth); if (dim.height > 0) { dim.height += getVgap(); } dim.height += rowHeight; } } }
问题现象
- 缓慢拖动窗口调整大小时,复选框组件可正常换行,适配窗口宽度
- 快速拖动窗口时,换行功能异常,复选框无法正确布局,出现错乱
目前推测问题与最小尺寸计算相关,但尚未找到解决办法。
内容的提问来源于stack exchange,提问作者Meltryllis
相关产品推荐
相关产品推荐

