我有一个JFrame,它包含一个可能任意大的“标题”集,可以点击它来展示面板,每个标题一个(概念上类似于垂直排列的工具栏,标题是暴露各种各样的标签)工具面板)。我希望标题具有分配给它们的固定数量的垂直空间,但是要水平增长以填充框架的宽度。我希望标题暴露的面板消耗框架中所有多余的垂直空间 - 但前提是它们是可见的;当看不见时,它们应占用零空间。
不幸的是,无论我如何尝试调整布局,我都无法防止它为标题和隐形面板分配额外的空间。在演示应用程序中,只需将窗口放大。期望的行为是蓝色的“Hello 0”面板应该变得更高,而所有其他组件保持“紧凑”;在实践中,我看到两个“紧凑标签”标签周围的空白区域和两个较低的“Click me”标题下方。
谢谢你的时间!
public class Demo {
public static void main(String[] args) {
final JFrame frame = new JFrame("Inspector");
frame.setLayout(new MigLayout("debug, fill, flowy, insets 0, gap 0"));
frame.add(new JLabel("Compact label 1"));
frame.add(new JLabel("Compact label 2"));
for (int i = 0; i < 3; ++i) {
JPanel wrapper = new JPanel(
new MigLayout("debug, fill, flowy, insets 0, gap 0",
"", "0[]0[grow]0"));
// Fixed-height header should grow horizontally only
JPanel header = new JPanel(
new MigLayout("flowx, fillx, insets 0, gap 0"));
header.add(new JLabel("Click me!"), "growx, height 40!");
header.setBackground(Color.RED);
// Variably-sized body should fill any extra space.
final JPanel body = new JPanel(new MigLayout("fill"));
body.add(new JLabel("Hello, " + i), "grow");
body.setBackground(Color.BLUE);
body.setVisible(i == 0);
wrapper.add(header, "growx");
wrapper.add(body, "growy, hidemode 2");
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
boolean shouldShow = !body.isVisible();
body.setVisible(shouldShow);
frame.pack();
}
});
frame.add(wrapper, "grow");
}
frame.pack();
frame.setVisible(true);
}
}
答案 0 :(得分:1)
最好使用JTabbedPane来获得所需内容。
否则,您可以在组件上放置百分比宽度和高度限制。 因此,对于您的标题,您可以告诉他们使用100%的宽度:
wrapper.add(header, "growx , w 100%");
对于身体,你可以放置&#34; h 100%&#34; (你可以使用h或高度)
wrapper.add(body, "growy, hidemode 2, h 100%");
它并不完美,但希望这会有所帮助。
答案 1 :(得分:0)
最终,我不得不使用不同的约束来移除和重新添加组件到布局管理器,具体取决于给定的主体是否可见。这并不理想,但它确实会导致所需的行为。 MigLayout
确实有一个setComponentConstraints()
方法,你认为这种方法可以用于此,但是,就像Matt Hubbard的建议一样,当显示/隐藏实体时,它不会重新计算大小,导致分布不均匀空间到可见的身体。
这是更新的演示程序:
public class Demo {
public static void main(String[] args) {
final JFrame frame = new JFrame("Inspector");
final JPanel contents = new JPanel(
new MigLayout("debug, fill, flowy, insets 0, gap 0"));
contents.setBackground(Color.GRAY);
frame.add(contents);
final ArrayList<Component> components = new ArrayList<Component>();
components.add(new JLabel("I should not grow"));
components.add(new JLabel("I shouldn't grow either"));
for (int i = 0; i < 3; ++i) {
// Fixed-height header should grow horizontally only
final JPanel header = new JPanel(
new MigLayout("flowx, fillx, insets 0, gap 0"));
header.add(new JLabel("Click me!"), "growx, height 40!");
header.setBackground(Color.RED);
components.add(header);
// Variably-sized body should fill any extra space.
final JPanel body = new JPanel(new MigLayout("fill"));
body.add(new JLabel("Hello, " + i), "grow");
body.setBackground(Color.BLUE);
body.setVisible(i == 0);
components.add(body);
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
boolean shouldShow = !body.isVisible();
body.setVisible(shouldShow);
refill(frame, contents, components);
}
});
}
refill(frame, contents, components);
frame.setVisible(true);
}
private static void refill(JFrame frame, JPanel contents,
ArrayList<Component> components) {
contents.removeAll();
for (int i = 0; i < components.size(); ++i) {
Component component = components.get(i);
// First two components don't grow at all.
if (i < 2) {
contents.add(component, "gap 0, grow 0, pushy 0");
}
// Even-numbered components are headers.
else if (i % 2 == 0) {
contents.add(component, "gap 0, growx, growy 0, pushy 0");
}
// Odd-numbered components are bodies, only if visible.
else if (component.isVisible()) {
contents.add(component, "gap 0, grow, pushy 100");
}
}
Dimension curSize = frame.getSize();
frame.pack();
frame.setSize(curSize);
}
}