将 JScrollPane 添加到 JFrame

Adding JScrollPane to a JFrame

我想将 JPanel 个容器添加到 JScrollPane 并将此滚动窗格添加到 JFrame。但是当我将多个面板添加到滚动窗格时,就会发生这种情况。滚动窗格和顶部栏之间的间隙增加。我使用 BoxLayout 作为我使用的所有组件的布局管理器。

这是我对这个 GUI 布局的看法。一些注意事项:

  • 它不是在 JScrollPane 中使用 BoxLayout,而是在 BorderLayoutPAGE_START 中放置 GridLayout。当可以将滚动窗格中的元素拉伸到 GUI 的整个宽度时,这很好。如果有必要将元素保持在首选大小,请坚持使用 BoxLayout(我很少使用)或 GridBagLayout
  • 这种布局策略基本上是 'divide and conquer',因为它从最小的 sub-divisions GUI(例如按钮的 FlowLayout)开始,然后将这些容器添加到更大的具有不同布局和约束的容器(例如,将按钮面板添加到 BorderLayoutLINE_END - 以将 I 推到 GUI 的右侧)以实现整体效果。
  • 我还会考虑在滚动窗格中使用 JList(使用渲染器面板)。有没有意义就看用途了。
  • 请注意,此代码 是 MRE。 MRE 应该拥有其他人编译和 运行 代码所需的一切(包括导入、class 结构和主要方法)。

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.ActionEvent;

// ref: 
public class ScrollPaneTestGUI {

    int elementCount = 1;
    JPanel elementsPanel = new JPanel(new GridLayout(0,1,2,2));

    public ScrollPaneTestGUI() {
        initGUI();
    }

    private void initGUI() {
        // this will become the content pane of the frame
        JPanel gui = new JPanel(new BorderLayout(4,4));
        gui.setBorder(new EmptyBorder(4,4,4,4));

        JPanel pageStartPanel = new JPanel(new BorderLayout(2,2));
        gui.add(pageStartPanel, BorderLayout.PAGE_START);
        pageStartPanel.add(new JLabel("LINE START label"), BorderLayout.LINE_START);
        // default flow layout is good for this one
        JPanel buttonPanel = new JPanel();
        pageStartPanel.add(buttonPanel, BorderLayout.LINE_END);
        buttonPanel.add(new JButton("Does Nothing"));
        Action addToScrollAction = new AbstractAction("Add to scrollPane") {
            @Override
            public void actionPerformed(ActionEvent e) {
                elementsPanel.add(getPanelForScroll());
                elementsPanel.revalidate();
            }
        };
        JButton addToScrollButton = new JButton(addToScrollAction);
        buttonPanel.add(addToScrollButton);

        JPanel scrollPanel = new JPanel(new BorderLayout());
        scrollPanel.add(elementsPanel, BorderLayout.PAGE_START);
        gui.add(new JScrollPane(scrollPanel,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
        );
        for (int ii=0; ii<2; ii++) {
            elementsPanel.add(getPanelForScroll());
        }

        JFrame frame = new JFrame("ScrollPane GUI");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(gui);
        frame.pack(); // sets the GUI to the exact size needed
        frame.setMinimumSize(frame.getSize());
        frame.setVisible(true);
    }

    private JPanel getPanelForScroll() {
        JPanel p = new JPanel();
        p.add(new JLabel("Panel " + elementCount++));
        p.setBorder(new EmptyBorder(10,200,10,200));
        p.setBackground(Color.GREEN);
        return p;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                new ScrollPaneTestGUI();
            }
        };
        SwingUtilities.invokeLater(r);
    }
}