如何在ScrollPane中创建流畅的2列GridLayout?

在过去的两个小时中,我已经进行了大量的搜索工作,但我已经放弃了。下图显示了我要实现的目标(请不要判断我的绘图是否太迟了,我很快就将其绘制在了绘画中):

如何在ScrollPane中创建流畅的2列GridLayout?

基本上,我希望JScrollPane具有一个带有2列GridLayout的JPanel,并且当我添加元素时,我希望GridLayout向下扩展。我希望元素使用其“首选大小”而不在GridLayout中扩展。

目前我有一个JScrollPane和一个JPanel的一个GridLayout,以及一个包含JPanel的网格的FlowLayout。作为测试,我向网格添加了10个按钮。这是我当前的代码:

// Setup main panel
JPanel pnlUsers = new JPanel(new GridLayout(0,2));
pnlUsers.setOpaque(true);
pnlUsers.setBackground(Color.GREEN);

// Setup GridLayout Container
JPanel pnl2 = new JPanel();
pnl2.setOpaque(false);
pnl2.add(pnlusers);

// Setup scrollpane
JScrollPane scrUsers = new JScrollPane(pnl2);
scrUsers.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrUsers.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrUsers.setOpaque(false);
scrUsers.getViewport().setOpaque(false);
scrUsers.setBorder(null);

// Add users
for (int i = 0; i < 10; i++) {
    pnlUsers.add(new JButton("Button " + (i + 1));
}

如下图所示,按钮使用了它们的首选大小,因此效果很好:

如何在ScrollPane中创建流畅的2列GridLayout?

不幸的是,按钮仍然没有填充水平空间。因此,我尝试将pnl2改为BoxLayout并添加一些垂直胶水。

// Setup GridLayout Container
JPanel pnl2 = new JPanel();
pnl2.setLayout(new BoxLayout(pnl2,BoxLayout.Y_AXIS));
pnl2.setOpaque(false);
pnl2.add(pnlusers);
pnl2.add(Box.createVerticalGlue());

我还创建了自己的临时按钮类,该类将首选大小设置为使用最小大小:

public class TempButton extends JButton {

    public PLTempButton(String msg) {
        super(msg);
        this.setPreferredSize(this.getMinimumSize());
    }

}

导致以下结果:

如何在ScrollPane中创建流畅的2列GridLayout?

这要好得多,但是仍然存在问题。如果没有足够的按钮导致JScrollPane滚动,则按钮的高度不一致,并且在垂直调整窗口大小时会调整大小。为什么?

很明显,当我添加100个按钮时,它们将使用其首选大小:

如何在ScrollPane中创建流畅的2列GridLayout?

也许我只是不了解最小,首选和最大大小之间的区别?但是我希望这些按钮使用设置的高度,即使它们不足以导致滚动窗格滚动也是如此。我该怎么做才能解决此问题?

lijiayanmy 回答:如何在ScrollPane中创建流畅的2列GridLayout?

  

1)如何在ScrollPane中获得GridLayout?

  1. 创建一个JPanel
  2. GridLayout应用于JPanel
  3. JPanel包裹在JScrollPane

例如

JPanel panel = new JPanel(new GridLayout(0,2));
JScrollPane scrollPane = new JScrollPane(panel);
// Add the scroll pane to what ever parent container you're using
  

2)我如何说GridLayout可以水平扩展,包括添加的组件?

对于问题的前面所有部分,这都是没有意义的,您说“然后让它随着我添加的内容的增加而逐渐向下扩展”。

话虽如此,“基本”答案是配置GridLayout并使其完成工作。上面的示例配置为2列和n个子帧

  

3)如何为组件添加“保证金”?

这是一个广泛的答案,您可以:

  • 利用GridLayout的水平和垂直间隙属性
  • 使用复合布局并调整适当的布局管理器(例如GridBagLayout)的插入

建议

我建议您通读Laying Out Components Within a Container,以更好地了解布局管理器。

请记住,您并没有坚持使用它。

在您询问有关API的基本问题时,我也建议您通读How to Use Scroll Panes

,

以下内容演示了如何创建一个JPanel并经过GridLayout扭曲的JScrollPane并设置其水平和垂直间距。
Jpanel使用BorderLayoutJFrame内容窗格的默认布局管理器)添加,它可以扩展:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class SwingMain {

    private String text ="Growing ";
    private JPanel grid;
    private JFrame f;

    SwingMain() {
        creategui();
    }

    void creategui(){

        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        JButton addComponentBtn = new JButton("Add Component");
        addComponentBtn.addActionListener(e-> addComponent());
        f.add(addComponentBtn,BorderLayout.PAGE_START);
        grid = new JPanel(new GridLayout(0,2,10,10)); //any number of rows,2 columns,H and V gap
        f.add(new JScrollPane(grid),BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);
    }

    void addComponent() {
        grid.add(new JLabel(text) );
        text +="."; //make text longer so JLable grows
        f.pack();
    }

    public static void main(String[] args) {
        new SwingMain();
    }
}
本文链接:https://www.f2er.com/3046914.html

大家都在问