将 WrapLayout 与多个相邻的 JPanel 一起使用会导致面板大小问题

Using WrapLayout with multiple adjacent JPanels is causing Panel sizing issues

我有 3 个相邻的 JPanel,每个都使用 WrapLayout 显示可变数量的 1x16 网格。

它适用于包含最多 1x16 网格的面板,但是,其他两个面板的尺寸似乎由包含最多 1x16 网格的面板决定。例如,如果面板 1 和面板 2 分别只有一个 1x16 网格,但面板 3 有十个 1x16 网格分布在两行中,那么面板 1 和面板 2 在它们的下方都有一个 1x16 grid-sized 空 space各自的 1x16 网格。

我基本上想让每个面板的调整大小独立于其他面板进行操作。我查看了 camickr 的 WrapLayout 源代码,但无法完全弄清楚我应该更改哪些内容才能获得所需的结果。

就代码而言,很难知道如何包含一个简洁且有指导意义的部分,因为代码非常分散,我不确定是哪一部分导致了这个问题。我只是将面板的布局设置为 left-justified WrapLayout。

我在下面添加了一张图片,它可能会提供一些上下文。该图显示了三个 JPanel 中的两个(青色)的一部分,以及其中一个 JPanel 的附带标题 JLabel(绿色)。每个面板上的 1x16 网格使用 camickr 的 WrapLayout 进行管理。所有三个青色 JPanel 都包含在一个更大的显示 JPanel 中,然后将其打包到 JScrollPane 中(因此图像右侧的灰色滚动条)。

非常感谢任何帮助。

这是我创建的另一张图片,可以更清楚地显示问题。图像中的第三个面板换行到一个新行以显示它包含的所有 1x16 网格,这样做会使其他两个面板的高度加倍,尽管它们不需要调整大小。

这是我希望 GUI 显示的方式:

从期望的行为与实际行为图像来看,问题在于 LayoutManager 你用来将 3 个面板布置到它们的父面板 panel/frame 中(我猜这是一个 GridLayout 因为 3 个面板的尺寸分布均匀)。如果是这样,请使用其他一些 LayoutManager,例如垂直 BoxLayout.

示例代码和教程可以在 Oracle's corresponding one (the actual code sample of which, can be found in this link with fancy code coloring, or here 中以纯文本形式找到。

我创建了以下 GUI。

我创建了一个 JFrame。我创建了一个主要 JPanel 放置在 JFrame 中。主要JPanel用一个GridBaglayout分隔三个青色JPanels.

每个青色 JPanel 根据放置在青色 JPanel 中的黑色 JPanels 的数量计算首选尺寸。更改 boxesPerRow 值以获得每行不同数量的框。

每个黑色 JPanel 的首选尺寸为 20 x 80 像素;

这是完整的可运行代码。换句话说,一个最小的可复制示例。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class BoxesGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new BoxesGUI());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Boxes");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBackground(Color.BLACK);
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.weightx = 1.0;
        
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(createCyanPanel(1), gbc);
        
        gbc.gridy++;
        panel.add(createCyanPanel(1), gbc);
        
        gbc.gridy++;
        panel.add(createCyanPanel(20), gbc);
        
        return panel;
    }
    
    private JPanel createCyanPanel(int count) {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
        panel.setBackground(Color.CYAN);
        
        JPanel dummyPanel = createBlackPanel();
        Dimension d = dummyPanel.getPreferredSize();
        
        int boxesPerRow = 8;
        int width = (d.width + 5) * boxesPerRow + 5;
        int height = ((count + boxesPerRow - 1) / boxesPerRow) * (d.height + 5) + 5;
        panel.setPreferredSize(new Dimension(width, height));
        
        for (int i = 0; i < count; i++) {
            panel.add(createBlackPanel());
        }
        
        return panel;
    }
    
    private JPanel createBlackPanel() {
        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);
        panel.setPreferredSize(new Dimension(20, 80));
        return panel;
    }

}