具有空布局的 JPanel Class 不显示组件
JPanel Class with null layout not showing components
因此,我创建了一个 class "CustomPanel" 的对象,它创建了一个带有 GridLayout 和其中标签的 JPanel,然后我将它添加到我的 JFrame 中。显示标签 "HELLO" 时效果很好,但是当我将 jpanel 的布局管理器更改为 (null) 时,它没有显示任何内容。我知道,我知道使用 null 布局是一种非常糟糕的做法,但我只想知道为什么它不显示组件。
主要class:
import javax.swing.JFrame;
public class MainMenu extends javax.swing.JFrame{
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Size the window.
frame.setSize(500, 500);
CustomPanel panel = new CustomPanel();
frame.getContentPane().add(panel);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
带有 GridLayout 的 CustomPanel class(效果很好):
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(new GridLayout());
// create the labels
JLabel myLabel = new JLabel("HELLO");
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
具有空布局的自定义面板 class(这不起作用):
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(null);
// create the labels
JLabel myLabel = new JLabel("HELLO");
myLabel.setBounds(10, 10, myLabel.getPreferredSize().width, myLabel.getPreferredSize().height);
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
jlabel 已在 jpanel 中正确设置,因此它应该显示在 jframe 的左上角,但实际上没有。
是什么原因造成的?我错过了什么?
问题是当您没有使用适当的布局管理器时,主 JPanel 的首选大小为 0,0,并且不会显示在它所在的容器中。持有主要 JPanel 的 CustomPanel 使用 FlowLayout 并将使用其包含的组件的首选大小来帮助调整和定位这些组件,但由于 main 没有布局,将 JLabel 添加到 main 不会增加首选大小,因为它应该 - 另一个使用布局的原因,CustomPanel 将主要显示为一个无大小的点。您当然可以通过 main.setPreferredSize(...)
给 main 一个首选大小来解决这个问题,但是这样您就会用一个 kludge 解决一个 kludge —— 不好。另一种可能的解决方案是将 CustomPanel 的布局更改为可能扩展它所包含的主 JPanel 的其他内容,可能为 CustomPanel 提供 BorderLayout。在这种情况下,以默认方式将 main 添加到 CustomPanel 会将主 JPanel 置于 BorderLayout.CENTER 位置,将其展开以填充 CustomPanel,并且可能会看到 JLabel。
当然,正确的解决方案是尽可能避免使用空布局。
因此,我创建了一个 class "CustomPanel" 的对象,它创建了一个带有 GridLayout 和其中标签的 JPanel,然后我将它添加到我的 JFrame 中。显示标签 "HELLO" 时效果很好,但是当我将 jpanel 的布局管理器更改为 (null) 时,它没有显示任何内容。我知道,我知道使用 null 布局是一种非常糟糕的做法,但我只想知道为什么它不显示组件。
主要class:
import javax.swing.JFrame;
public class MainMenu extends javax.swing.JFrame{
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Size the window.
frame.setSize(500, 500);
CustomPanel panel = new CustomPanel();
frame.getContentPane().add(panel);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
带有 GridLayout 的 CustomPanel class(效果很好):
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(new GridLayout());
// create the labels
JLabel myLabel = new JLabel("HELLO");
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
具有空布局的自定义面板 class(这不起作用):
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(null);
// create the labels
JLabel myLabel = new JLabel("HELLO");
myLabel.setBounds(10, 10, myLabel.getPreferredSize().width, myLabel.getPreferredSize().height);
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
jlabel 已在 jpanel 中正确设置,因此它应该显示在 jframe 的左上角,但实际上没有。 是什么原因造成的?我错过了什么?
问题是当您没有使用适当的布局管理器时,主 JPanel 的首选大小为 0,0,并且不会显示在它所在的容器中。持有主要 JPanel 的 CustomPanel 使用 FlowLayout 并将使用其包含的组件的首选大小来帮助调整和定位这些组件,但由于 main 没有布局,将 JLabel 添加到 main 不会增加首选大小,因为它应该 - 另一个使用布局的原因,CustomPanel 将主要显示为一个无大小的点。您当然可以通过 main.setPreferredSize(...)
给 main 一个首选大小来解决这个问题,但是这样您就会用一个 kludge 解决一个 kludge —— 不好。另一种可能的解决方案是将 CustomPanel 的布局更改为可能扩展它所包含的主 JPanel 的其他内容,可能为 CustomPanel 提供 BorderLayout。在这种情况下,以默认方式将 main 添加到 CustomPanel 会将主 JPanel 置于 BorderLayout.CENTER 位置,将其展开以填充 CustomPanel,并且可能会看到 JLabel。
当然,正确的解决方案是尽可能避免使用空布局。