【发布时间】:2012-04-30 23:38:54
【问题描述】:
我创建了一个 JPanel,其中包含任意数量的 JLabel,并使用左对齐的流布局管理器进行布局。让我们称之为 FlowPanel。
每个 FlowPanel 都有一个深度,我想将任意数量的 FlowPanel 堆叠在一起,每一个都缩进一个固定的数量 * 深度。最终的目标是在 JScrollPane 中显示这些堆叠的面板,其中包含垂直滚动条(如果需要)但不包含水平滚动条。
我尝试将 FlowPanel 与 GridBagLayout 堆叠在一起,虽然让它们垂直堆叠并按我想要的方式缩进很容易,但我不知道如何让宽度正确。也就是说,FlowPanel 只是从我的主面板的右侧运行,而不注意显示的宽度。
我尝试过使用 setPreferredSize、setSize,弄乱了 GridBagConstraints……没有运气。
请帮忙! :)
一些示例代码来演示该问题。这段代码有两个问题: 1. 即使只有几行,行的高度也应保持不变。 2.当FlowPanels包含太多元素时,行会从屏幕右侧滚动出来。
public class FlowExample {
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
StackPanel stackPanel = new StackPanel();
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(
new JScrollPane(stackPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
BorderLayout.CENTER);
frame.setLocation(200, 200);
frame.setSize(300, 300);
frame.setVisible(true);
List<FlowPanel> content = new ArrayList<FlowPanel>();
for (int i = 0; i < 20; i++) {
FlowPanel flowPanel = new FlowPanel((int) (4 * Math.random()));
for (int j = 0; j < (int) (20 * Math.random()); j++) {
flowPanel.add(new JLabel("label " + j));
}
content.add(flowPanel);
stackPanel.layoutGUI(content);
Thread.sleep(1000);
}
System.in.read();
System.exit(0);
}
}
class StackPanel extends JPanel {
public StackPanel() {
setLayout(new BorderLayout());
}
public void layoutGUI(final List<FlowPanel> content) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
layoutGUI(content);
}
});
return;
}
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(content.size(), 1));
for (FlowPanel flowPanel : content) {
flowPanel.setBorder(BorderFactory.createEmptyBorder(0, flowPanel.getDepth() * 10, 0, 0));
mainPanel.add(flowPanel);
}
removeAll();
add(mainPanel, BorderLayout.CENTER);
revalidate();
}
}
class FlowPanel extends JPanel {
private int depth;
public FlowPanel(int depth) {
setLayout(new FlowLayout(FlowLayout.LEFT));
this.depth = depth;
}
public int getDepth() {
return depth;
}
}
这里有一些使用 GridBagLayout 来布置主面板的示例代码。这是我得到的最好结果,但正如您所见,FlowPanel 仍然没有换行...
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.anchor = GridBagConstraints.LINE_START;
for (FlowPanel flowPanel : content) {
System.out.println("setting border to " + flowPanel.getDepth());
flowPanel.setBorder(BorderFactory.createEmptyBorder(0, flowPanel.getDepth() * 10, 0, 0));
mainPanel.add(flowPanel, constraints);
}
constraints.weighty = 1;
mainPanel.add(new JPanel(), constraints);
removeAll();
add(mainPanel, BorderLayout.CENTER);
revalidate();
【问题讨论】:
-
您是否尝试过简单地堆叠它们(使用 GridLayout 就足够了),但为每个面板分配了一个仅左侧的空边框?
-
似乎不起作用...现在编写示例代码进行演示。
-
当 FlowPanel 比 StackPanel 宽时你想要什么行为?它应该环绕并增加它的深度吗?或者您想在添加尚未达到最大值的 JLabel 时进行测试。宽度了吗?
-
@John Greenhow:如果 FlowPanel 超过 StackPanel 的宽度,它应该环绕并增加 StackPanel 的高度。
标签: java layout gridbaglayout flowlayout