0

0

如何在按钮点击时正确显示自定义窗口(JFrame)

霞舞

霞舞

发布时间:2026-02-13 12:16:46

|

109人浏览过

|

来源于php中文网

原创

如何在按钮点击时正确显示自定义窗口(JFrame)

本文详解 java swing 中通过按钮事件打开指定窗口的实现方法,重点解决因窗口引用错误导致“空窗体”问题,并提供结构清晰、可复用的代码范式与最佳实践建议。

在 Java Swing 开发中,通过按钮触发新窗口显示是常见需求。但初学者常因混淆 JFrame 实例与内部窗口引用,导致点击后弹出空白窗口——正如您在 manga 类中遇到的问题:调用 new manga().setVisible(true) 无效,是因为 manga 类虽继承 JFrame,但实际 UI 组件全部添加到了其内部字段 frmAcheterDesLivres 上,而非 this(即 manga 实例本身)。因此,直接对 mangaWindow 调用 setVisible(true) 并不会显示任何内容。

✅ 正确做法:操作真实承载组件的 JFrame 引用

您已在 manga 的 main 方法中写对了关键逻辑:

mangaWindow.frmAcheterDesLivres.setVisible(true);

这说明 frmAcheterDesLivres 才是真正包含所有按钮、标签和表格的容器。因此,在事件监听器中必须显式访问该字段:

btnManga.addActionListener(e -> {
    manga mangaWindow = new manga();
    mangaWindow.frmAcheterDesLivres.setVisible(true); // ✅ 正确:显示实际构建好的窗口
});
? 提示:使用 Lambda 表达式替代匿名内部类,使代码更简洁(Java 8+ 推荐)。

⚠️ 重要重构建议:避免继承 JFrame(推荐方案)

当前设计存在两个典型隐患:

腾讯云AI代码助手
腾讯云AI代码助手

基于混元代码大模型的AI辅助编码工具

下载
  • 语义混淆:manga extends JFrame 暗示 manga 本身就是一个窗口,但实际布局完全托管给 frmAcheterDesLivres,违背面向对象封装原则;
  • 资源冗余:每个 manga 实例既是一个 JFrame(空壳),又持有一个 JFrame 字段(真窗口),造成内存与逻辑双重浪费。

推荐重构为组合模式(Composition over Inheritance)

// manga.java —— 移除 'extends JFrame',改为普通工具类
package biblio;

import javax.swing.*;
import java.awt.*;

public class MangaWindow { // 类名 PascalCase,语义更清晰
    private final JFrame frame; // 明确持有唯一窗口实例

    public MangaWindow() {
        frame = new JFrame("Acheter des Livres");
        frame.setResizable(false);
        frame.getContentPane().setBackground(new Color(66, 66, 66));
        frame.setBounds(100, 100, 758, 601);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // ❗关键:用 DISPOSE_ON_CLOSE 而非 EXIT_ON_CLOSE
        frame.setLayout(null);

        // ...(其余初始化代码保持不变,全部添加到 frame.getContentPane())
        initializeComponents();
    }

    private void initializeComponents() {
        // 将原 initialize() 中所有 add(...) 操作迁移至此
        JButton btn1 = new JButton("");
        btn1.setIcon(new ImageIcon(MangaWindow.class.getResource("/resources/mangas/blackClover.jpg")));
        btn1.setBounds(31, 46, 125, 125);
        frame.getContentPane().add(btn1);

        JLabel lblTitle = new JLabel("Black Clover");
        lblTitle.setForeground(new Color(40, 168, 253));
        lblTitle.setFont(new Font("Yu Gothic Medium", Font.ITALIC, 14));
        lblTitle.setBounds(31, 185, 125, 34);
        frame.getContentPane().add(lblTitle);

        // ... 其他组件同理
    }

    // 对外提供统一的显示入口
    public void show() {
        frame.setVisible(true);
    }

    // 可选:提供获取窗口引用的方法,便于高级控制(如居中、聚焦)
    public JFrame getFrame() {
        return frame;
    }
}

对应主窗口中的调用方式更新为:

btnManga.addActionListener(e -> {
    new MangaWindow().show(); // ✅ 清晰、安全、无歧义
});

? 关键注意事项总结

事项 说明 建议
窗口关闭行为 主窗口用 EXIT_ON_CLOSE 合理;子窗口应使用 DISPOSE_ON_CLOSE,避免意外退出整个应用 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
线程安全 Swing 组件必须在 Event Dispatch Thread (EDT) 中创建和修改 已在 main() 中通过 EventQueue.invokeLater() 保障,无需额外处理
资源管理 图片路径使用 getClass().getResource(...) 是正确的,确保资源在 classpath 中 确保 /resources/mangas/ 目录位于 src/main/resources(Maven 结构)或输出目录下
UI 可维护性 避免 null 布局(setLayout(null))——虽可快速定位,但难以响应式适配 后续可逐步迁移到 GridBagLayout 或 GroupLayout(WindowBuilder 默认支持)

✅ 最终验证步骤

  1. 重构 manga.java 为 MangaWindow(移除 extends JFrame,封装 JFrame 字段);
  2. 在 principal.java 中将监听器更新为 new MangaWindow().show();
  3. 运行程序 → 点击 “MANGA” 按钮 → 应完整显示含图片、标签和表格的窗口;
  4. 关闭该窗口后,主窗口仍保持活跃,且可再次点击打开新实例(DISPOSE_ON_CLOSE 保证资源释放)。

通过以上调整,您不仅解决了当前的空窗体问题,更建立了符合 Swing 设计规范、易于扩展与协作的窗口管理模型。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Java Maven专题
Java Maven专题

本专题聚焦 Java 主流构建工具 Maven 的学习与应用,系统讲解项目结构、依赖管理、插件使用、生命周期与多模块项目配置。通过企业管理系统、Web 应用与微服务项目实战,帮助学员全面掌握 Maven 在 Java 项目构建与团队协作中的核心技能。

0

2025.09.15

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

244

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

705

2024.03.01

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

56

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.11.27

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

211

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

191

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

12

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号