如何在Java中禁用JFrame的最小化窗口控制按钮?
需求与解决方案
需求说明
业务分析师(BA)要求窗口满足:
- 保留关闭按钮
- 保留最大化按钮
- 禁用最小化按钮
需匹配C语言开发者已实现的效果,且只能使用JFrame,若纯Java方案不可行,可采用Windows原生方法(应用仅部署在Windows)。
现有代码仅能在窗口最小化后恢复状态,但最小化按钮仍可点击,代码如下:
import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class NonMinimizableFrameDemo { public NonMinimizableFrameDemo() { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 300); frame.setLocationRelativeTo(null); frame.addWindowListener(getWindowAdapter()); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(NonMinimizableFrameDemo::new); } private final JFrame frame = new JFrame(); private WindowAdapter getWindowAdapter() { return new WindowAdapter() { @Override public void windowIconified(WindowEvent we) { frame.setState(JFrame.NORMAL); JOptionPane.showMessageDialog(frame, "Cant Minimize"); } }; } }
方案一:纯Java改进方案(拦截事件+限制窗口尺寸)
Swing本身没有直接禁用最小化按钮的API,但可以通过拦截最小化事件+限制窗口最小尺寸的方式,阻止窗口被最小化,同时给用户明确提示:
import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class NonMinimizableFrameDemo { private final JFrame frame = new JFrame(); public NonMinimizableFrameDemo() { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 300); frame.setLocationRelativeTo(null); // 设置窗口最小尺寸与当前尺寸一致,避免手动缩小窗口 frame.setMinimumSize(frame.getSize()); frame.addWindowListener(new WindowAdapter() { @Override public void windowIconified(WindowEvent we) { frame.setState(JFrame.NORMAL); JOptionPane.showMessageDialog(frame, "此窗口不允许最小化", "提示", JOptionPane.INFORMATION_MESSAGE); } }); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(NonMinimizableFrameDemo::new); } }
该方案无法灰化最小化按钮,但能有效阻止窗口被最小化,且无需依赖外部库。
方案二:Windows原生方法(真正禁用最小化按钮)
如果需要彻底灰化/移除最小化按钮,可通过调用Windows API实现,这里使用JNA简化原生调用(无需编写C代码):
1. 添加JNA依赖(Maven)
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
2. 实现代码
import javax.swing.*; import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinUser; public class WinNonMinimizableFrame { private static final User32 USER32 = User32.INSTANCE; public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("无最小化按钮窗口"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 300); frame.setLocationRelativeTo(null); frame.setVisible(true); // 获取JFrame对应的Windows窗口句柄 WinDef.HWND hwnd = new WinDef.HWND(); hwnd.setPointer(frame.getPeer().getPointer()); // 获取当前窗口样式 long currentStyle = USER32.GetWindowLongPtr(hwnd, WinUser.GWL_STYLE).longValue(); // 移除最小化按钮样式位,保留最大化和关闭按钮 long newStyle = currentStyle & ~WinUser.WS_MINIMIZEBOX; // 应用新的窗口样式 USER32.SetWindowLongPtr(hwnd, WinUser.GWL_STYLE, new WinDef.LONG(newStyle)); // 刷新窗口以更新外观 USER32.SetWindowPos(hwnd, null, 0, 0, 0, 0, WinUser.SWP_NOMOVE | WinUser.SWP_NOSIZE | WinUser.SWP_FRAMECHANGED); }); } }
该方案直接修改Windows窗口样式,会彻底移除最小化按钮(或灰化,取决于系统主题),完全符合需求,但仅适用于Windows环境。
内容的提问来源于stack exchange,提问作者Powet
相关产品推荐
相关产品推荐

