个人博客:狐狸半面添的客栈
我们先看一段非常简单的代码来展示我们的问题:
import javax.swing.*;
/**
* @author 狐狸半面添
* @create 2023-09-19 1:26
*/
public class MyFrame extends JFrame {
/**
* 启动项目,创建容器
*/
public static void main(String[] args) {
new MyFrame();
}
public MyFrame() {
// 初始化界面
initJFrame();
// 初始化图片
initImage();
// 设置窗体可见
this.setVisible(true);
}
/**
* 初始化界面/容器
*/
private void initJFrame() {
// 设置窗体宽高
this.setSize(600, 600);
// 设置标题
this.setTitle("Demo");
// 设置窗体居中
this.setLocationRelativeTo(null);
// 设置窗体关闭方式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
/**
* 初始化图片组件
*/
private void initImage() {
// 展示两张图片 0.jpg 和 1.jpg ,两张图片的宽高都是 105
for (int i = 0; i < 2; i++) {
// 创建一个管理容器
JLabel jLabel = new JLabel(new ImageIcon("D:\\image\\" + i + ".jpg"));
// 指定照片位置
jLabel.setBounds(105 * i, 0, 105, 105);
// 把管理容器加到界面当中
this.getContentPane().add(jLabel);
}
}
}
我们运行期待的结果是两张图片在第一行依次排列,但是实际上的效果是:
默认情况下,JFrame 使用 BorderLayout
作为其内容面板的布局管理器。
JFrame 使用 BorderLayout 作为布局管理器的底层逻辑:
因此,这就解释了为什么我们最后一张图片没有按照设置的 setBounds 摆放,而是一直处于界面的正中央。因为 BorderLayout 布局是生效的,换句话说,BorderLayout 布局设置优先级高于 setBounds。
因此,如果我们想让我们的所有组件位置布局生效,或者说是最后一个组件的位置布局生效,就需要移除默认的 BorderLayout 布局管理器
通过设置 setLayout(null),我们将 JFrame 的布局管理器设置为空,这意味着我们需要手动控制组件的位置和大小,而不是依赖于自动布局。这对于我们在 setBounds() 方法中直接设置组件的位置和大小非常有用。
我们修改“问题描述”中提供的代码的 initJFrame() 方法,只需要在方法中加一段移除布局管理器的设置即可:
// 移除默认的 BorderLayout 布局管理器
this.getContentPane().setLayout(null);