当我在JDesktopPane中有一个JInternalFrame时,该JInternalFrame是可移动的(很好)。但是,可以将其移到JDesktopPane的可见范围之外(我不太喜欢)

亲自看一下,下面是一些示例代码:

public static void main(String[] args) {

  JFrame frame = new JFrame("JDesktopPane");
  JDesktopPane tableDisplay = new JDesktopPane();

  JInternalFrame internalFrame = new JInternalFrame("JInternalFrame",true,true,true,true);
  internalFrame.setContentPane(new JLabel("Content"));
  internalFrame.pack();
  internalFrame.setVisible(true);
  tableDisplay.add(internalFrame, JDesktopPane.POPUP_LAYER);

  frame.setContentPane(tableDisplay);
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setMinimumSize(new Dimension(400, 300));
  frame.setVisible(true);
}

是否可以设置JInternalFrame或JDesktopPane以使它们不允许这样做?

最佳答案

负责执行移动/调整大小的协作者是DesktopPaneManager。因此,我将尝试将移动限制在 Pane 内。这是一个快速而肮脏的概念证明:

    JDesktopPane background = new JDesktopPane();
    JInternalFrame internalFrame = new JInternalFrame("Internal Frame",
            true, true, true, true);
    DesktopManager manager = new DefaultDesktopManager() {
        /** This moves the <code>JComponent</code> and repaints the damaged areas. */
        @Override
        public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
            boolean didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight);
            if (!inBounds((JInternalFrame) f, newX, newY, newWidth, newHeight)) return;
            f.setBounds(newX, newY, newWidth, newHeight);
            if(didResize) {
                f.validate();
            }
        }

        protected boolean inBounds(JInternalFrame f, int newX, int newY, int newWidth, int newHeight) {
            if (newX < 0 || newY < 0) return false;
            if (newX + newWidth > f.getDesktopPane().getWidth()) return false;
            if (newY + newHeight > f.getDesktopPane().getHeight()) return false;
            return true;
        }

    };
    background.setDesktopManager(manager);

很显然,有一些问题需要解决:-) F.i.
  • 使用适合于LAF的管理器,这可以通过实现包装器DesktopManager来完成,该包装器将其他所有内容委托(delegate)给LAF安装的
  • 检查是否有副作用(碰到墙后拖动似乎无响应,可能还需要其他东西)

  • 编辑

    只是要澄清一下:“无响应”是指用户必须释放并再次按下/拖动(一旦内部框架达到桌面界限)才能进一步移动。这并不令人感到意外,因为BorderListener(BasicInternalFrame安装的mouseListener)保持与初始按下有关的某些状态,然后请求相对于该初始位置进行重新定位。在框架卡在某处的情况下拖动鼠标会使该内部状态困惑。

    有趣的是,看着代码,似乎有意图限制运动以免将其推到外面,
        // Make sure we stay in-bounds
        if(newX + i.left <= -__x)
            newX = -__x - i.left + 1;
        if(newY + i.top <= -__y)
            newY = -__y - i.top + 1;
        if(newX + __x + i.right >= pWidth)
            newX = pWidth - __x - i.right - 1;
        if(newY + __y + i.bottom >= pHeight)
            newY =  pHeight - __y - i.bottom - 1;
    

    但是,这是相对于当前鼠标位置的。

    09-26 16:52