如何在Windows系统中实现JFrame窗口不可拖拽的效果
Windows 10 + Java 11 环境下可以实现 JFrame 不可拖拽的效果,以下是两种常用实现方案:
方案1:禁用原生标题栏(无额外依赖,适配性最优)
原生标题栏的拖拽逻辑由Windows系统直接管理,最简单的实现方式就是关闭默认的系统标题栏,拖拽功能自然失效。你只需要在你的构造方法中setVisible之前添加setUndecorated(true)即可,修改后的代码如下:
import javax.swing.JFrame; public class Test extends JFrame { public Test() { this.setResizable(false); // 禁用原生标题栏和边框 this.setUndecorated(true); this.setExtendedState(JFrame.MAXIMIZED_BOTH); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new Test(); } }
如果需要保留标题栏的显示效果,可以自行绘制自定义标题栏,完全控制交互逻辑。
方案2:保留原生标题栏,通过位置重置禁止拖拽
如果必须保留系统原生标题栏,可以添加组件移动监听器,一旦检测到窗口位置发生变化,立即将窗口位置重置回初始位置即可,无需引入第三方依赖,代码示例如下:
import javax.swing.JFrame; import java.awt.Point; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; public class Test extends JFrame { // 固定窗口的初始位置,最大化场景下为(0,0) private final Point fixedPoint = new Point(0, 0); public Test() { this.setResizable(false); this.setExtendedState(JFrame.MAXIMIZED_BOTH); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 添加组件移动监听器,位置变化时立即重置 this.addComponentListener(new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { setLocation(fixedPoint); } }); this.setVisible(true); } public static void main(String[] args) { new Test(); } }
如果需要更精细的拦截(比如仅拦截标题栏拖拽触发的移动,避免窗口闪烁),可以引入JNA依赖调用Windows原生API,拦截WM_NCLBUTTONDOWN或者WM_MOVE系统消息实现更丝滑的禁用效果。
内容的提问来源于stack exchange,提问作者Bu Saeed
相关产品推荐
相关产品推荐

