1

同事。

我正在尝试用 Java 构建简单的 GUI,其中 JFrame 具有边框布局。我想把带有 JTable 的 JScrollPane 放到 CENTER,把没有布局的 JPanel 放到 NORTH。

问题是 JPanel 不可见。有一个简单的问题示例:

JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton button = new JButton("Test button");
button.setBounds(10, 10, 40, 20);

JPanel panelN = new JPanel(null); // layout = null, panelN without layout
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);

JTable table = new JTable(new DefaultTableModel(4, 4));
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);

frame.setSize(400, 400);
frame.setVisible(true);
4

4 回答 4

5

你必须使用一个LayoutManager. 完全不鼓励不使用 layoutManager,但如果你想要这个,你也必须设置panel.setBounds(..)到面板。

默认情况下JPanelFlowLayout如果你把

JPanel panelN = new JPanel(); // FlowLayout used 
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);

所以你的框架看起来像这样。

例子

布局管理器确定容器内组件的大小和位置。尽管组件可以提供大小和对齐提示,但容器的布局管理器对容器内组件的大小和位置拥有最终决定权。

强烈建议您例如,如果您必须调整组件大小或以不同的分辨率显示,则将此工作委托给布局管理器

于 2013-06-18T18:55:45.503 回答
3

如果您没有为面板设置任何布局,则添加组件时面板不知道将组件放置在哪里,所以基本上在您通过component.setBounds(x,y,width,hieght)方法为组件设置特定位置之前,组件不会显示。

请注意,由于平台不同,删除布局管理器不是一个好习惯,假设您的程序在 Window 和 MacOS 和 Linux 上运行,您最好使用布局管理器。

也看看这篇文章,看看@Andrew Thompson 对我的回答的评论:

Java GUI 可能必须在多个平台、不同的屏幕分辨率和使用不同的 PLAF 上工作。因此,它们不利于组件的精确放置。对于强大的 GUI,请改为使用布局管理器或它们的组合,以及用于空白空间的布局填充和边框来组织组件。

毕竟: 如果您有要求或任务告诉您必须使用 absolute layout,请使用它,否则请避免使用它。

于 2013-06-18T18:49:51.183 回答
3

我不知道 null 布局的预期行为,但如果没有进一步的要求,您不妨使用零参数构造函数进行实例化:

new JPanel();
于 2013-06-18T18:49:28.703 回答
0

使用没有布局管理器的容器是可以的,因为您实际上可以将容器的布局设置为 NULL。使用 setBounds() 定位组件是一个好主意。但在这种情况下,您只需要考虑您的容器。它需要多大?布局管理器会为您计算这一点,如果您没有,您必须根据添加到其中的组件自行设置面板的大小。

正如其他人在这里指出的那样,框架的边框布局管理器需要您的 NORTH 面板的首选大小(实际上是首选高度)。你必须设置它,否则值将为零,容器将变得不可见。请注意,对于 CENTER 面板,这不是必需的,因为它可以获得所有可能的空间。

我之前遇到过像您这样的问题,并且编写了一个快速函数来根据给定组件的边界调整容器的大小。它将与显示该组件所需的一样大,因此考虑了尺寸 (w,h) 和位置 (x,y)。添加所有组件后,可以使用一次“自动调整大小”版本。

public static void updatePreferredSize(Container cont, Component comp) {

    int w = cont.getPreferredSize().width;
    int h = cont.getPreferredSize().height;

    int W = comp.getBounds().x + comp.getBounds().width;
    int H = comp.getBounds().y + comp.getBounds().height;

    if (W>w||H>h) cont.setPreferredSize(new Dimension(W>w?W:w, H>h?H:h));
}

public static void autoPreferredSize(Container cont) {

    for (Component comp : cont.getComponents())
        updatePreferredSize(cont, comp);
}

您可以在将每个组件添加到面板后使用 updatePreferredSize(),或者在所有添加后使用 autoPreferredSize() 一次。

// [...]
panelN.add(button);
updatePreferredSize(panelN, button);
// [...]

// or...

// [...]
autoPreferredSize(panelN);
// [...]
frame.setVisible(true);

这样,如果您没有将北面板高度设置为固定值,则借助这些函数,您可以期望您的按钮将根据您使用 setBounds() 设置的位置可见。

于 2016-11-03T14:57:49.973 回答