同事。
我正在尝试在Java中构建简单的GUI,其中JFrame具有Border Layout。我想将带有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);
答案 0 :(得分:4)
您必须使用LayoutManager
。完全不鼓励不使用layoutManager,但如果你想要这个,你也必须将panel.setBounds(..)
设置到面板上。
默认JPanel
有FlowLayout
,所以如果你放
JPanel panelN = new JPanel(); // FlowLayout used
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);
所以你的框架看起来像这样。
布局管理器确定容器内组件的大小和位置。虽然组件可以提供大小和对齐提示,但容器的布局管理器对容器中组件的大小和位置有最终决定权。
强烈建议例如,如果您必须调整组件大小或以不同的分辨率显示您将此工作委托给布局管理器
答案 1 :(得分:3)
我不知道null布局的预期行为,但是如果没有进一步的要求,您也可以使用zero-arg构造函数进行实例化:
new JPanel();
答案 2 :(得分:3)
如果没有为面板设置任何布局,则在添加组件时面板不知道放置组件的位置,因此在您设置特定组件之前,组件不会显示component.setBounds(x,y,width,hieght)
方法逐个组件的位置。
请注意,由于平台不同,删除布局管理器并不是一个好习惯,假设您的程序在Window和MacOS以及Linux上工作,您最好使用布局管理器。
同时查看this post并查看@Andrew Thompson对我的回答的评论:
Java GUI可能必须在不同的平台上工作 屏幕分辨率&使用不同的PLAF。因此他们不是 有助于准确放置组件。相反,对于强大的GUI 使用布局管理器或它们的组合以及布局 填充&白色空间的边框,用于组织组件。
毕竟: 如果您有要求或作业告诉您必须使用绝对布局,请使用它,否则请避免使用它。
答案 3 :(得分: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()设置的位置看到按钮。