如何使Java Swing中的JInternalFrame不可移动?
Hey there! I get that you want to lock down a JInternalFrame placed in a JPanel so it can't be dragged around, and you're looking for an event-driven approach instead of the listener-removal code you found online. Let's work through this together.
First, a quick note: Swing doesn't have a built-in "disable frame movement" event or toggle setting. The default dragging behavior of JInternalFrame is handled by its UI delegate—specifically, mouse motion listeners attached to the frame's north title pane. To block movement, we need to intercept those drag events.
Here's a clean, event-focused way to achieve this without removing existing listeners:
Option 1: Consume Drag Events on the Title Pane
Instead of deleting the default listeners, we can add our own listener to the title pane that "consumes" the drag event before the default handlers process it. This keeps the original UI intact but stops the frame from moving.
// Create your JInternalFrame as normal JInternalFrame myFrame = new JInternalFrame("Unmovable Frame", true, true, true, true); myFrame.setSize(300, 200); myFrame.setVisible(true); // Access the title pane via the UI delegate BasicInternalFrameUI ui = (BasicInternalFrameUI) myFrame.getUI(); Component titlePane = ui.getNorthPane(); // Add a listener to eat drag events titlePane.addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { // Consume the event so the default move logic never runs e.consume(); } }); // Add the frame to your target JPanel yourPanel.add(myFrame);
Option 2: Reusable Custom Unmovable Frame
If you need this functionality across multiple frames, create a subclass of JInternalFrame that handles the event interception internally:
public class UnmovableInternalFrame extends JInternalFrame { public UnmovableInternalFrame(String title) { super(title, true, true, true, true); lockTitlePaneDrag(); } private void lockTitlePaneDrag() { BasicInternalFrameUI ui = (BasicInternalFrameUI) getUI(); Component titlePane = ui.getNorthPane(); titlePane.addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { e.consume(); } }); } } // Usage example UnmovableInternalFrame lockedFrame = new UnmovableInternalFrame("Locked in Place"); yourPanel.add(lockedFrame);
Why This Works
The default JInternalFrame movement is triggered by drag events on its title pane. By calling e.consume(), we stop the event from being passed to the default UI listeners that handle frame movement. This is more maintainable than removing listeners because it doesn't depend on knowing how many default listeners exist or their internal implementation.
内容的提问来源于stack exchange,提问作者shaun Tait

