本文介绍了防止JInternalFrame移出JDesktopPane的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I have a JInternalFrame in a JDesktopPane, the JInternalFrame is movable (which is good). However, it's possible to move it outside of the visible scope of the JDesktopPane (which I'm not so fond of)

为了亲眼看看,这里有一些示例代码:

To see for yourself, here's some sample code:

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以便它们不会允许这个?

Is it possible to set either the JInternalFrame or JDesktopPane so that they won't allow this?

推荐答案

负责进行移动/调整大小的协作者是DesktopPaneManager。所以我会尝试将移动限制在窗格内。这是一个快速的&脏概念证明:

The collaborator which is responsible for doing the move/resize is the DesktopPaneManager. So I would try to limit the movement to within the pane. Here's a quick & dirty proof of concept:

    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。

There are some issues to solve, obviously :-) F.i.


  • 使用适用于LAF的管理器,这可以通过实现一个包装器DesktopManager来完成,该程序将其他所有内容委托给安装的LAF

  • 检查副作用(在撞墙后阻力似乎没有响应,可能还需要其他东西)

编辑

只是为了澄清:无响应我的意思是用户必须释放并再次按下/拖动(一旦内部框架已经击中桌面边界)进一步移动。这并不奇怪,因为BorderListener(由BasicInternalFrame安装的mouseListener)保持与初始按下相关的某些状态,然后请求相对于该初始位置重新定位。拖动鼠标框架卡在某处会混淆内部状态。

just to clarify: with "unresponsive" I mean that the user has to release and press/drag again (once the internal frame has hit the desktop bounds) to further move the. That's not overly surprising, as the BorderListener (that's the mouseListener installed by BasicInternalFrame) keeps some state related to the initial press and then requests re-locates relative to that initial location. Dragging the mouse with the frame stuck somewhere confuses that internal state.

有趣的是,看看代码,似乎有意将游戏限制在不推向外面,

Interestingly, looking at the code, it seems like there had been intentions to limit the movement to not push it to the outside,

    // 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;

相对于当前鼠标位置。

that's relative to the current mouse location, though.

这篇关于防止JInternalFrame移出JDesktopPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 22:32