防止将JInternalFrame移出JDesktopPane(Preventing JInternalFrame from being moved out of a JDesktopPane)
当我在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_O_CLOSE); frame.setMinimumSize(new Dimension(400, 00)); frame.setVisible(true); }是否可以设置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_O_CLOSE); frame.setMinimumSize(new Dimension(400, 00)); frame.setVisible(true); }Is it possible to set either the JInternalFrame or JDesktopPane so that they won't allow this?
最满意答案
负责进行移动/调整大小的协作者是DesktopPaneManager。 所以我会尝试限制移动到窗格内。 这是一个快速和肮脏的概念证明:
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);有一些问题需要解决,显然:-) Fi
根据LAF的适用情况使用管理器,可以通过实施封装程序DesktopManager来完成,该封装程序将其他所有内容委托给安装的LAF 检查是否有副作用(在撞墙后拖动显示为无响应,可能还需要其他东西)编辑
只是为了澄清:“无响应”我的意思是用户必须释放并再次按下/拖动(一旦内部框架已达到桌面边界),以进一步移动。 这并不令人意外,因为BorderListener(即BasicInternalFrame安装的mouseListener)会保留一些与初始印刷机相关的状态,然后请求相对于该初始位置进行重新定位。 将框架卡住的地方拖动鼠标混淆内部状态。
有趣的是,从代码的角度来看,似乎有意图将运动限制在不推向外部的位置,
// Make sure we stay in-bounds if(newX + i.left <= -__x) newX = -__x - i.left + 1; if(newY + <= -__y) newY = -__y - + 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;虽然这与当前鼠标位置有关。
The collaborator which is respible 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);There are some issues to solve, obviously :-) F.i.
use the manager as appropriate for the LAF, which could be done by implementing a wrapper DesktopManager which delegates everything else to the LAF installed check for side-effects (the drag appears a unrespive after having hit a wall, there might be other things needed)Edit
just to clarify: with "unrespive" 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 intenti 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 + <= -__y) newY = -__y - + 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.
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 6 条评论) |
本站网友 龙腾四海论坛 | 19分钟前 发表 |
该封装程序将其他所有内容委托给安装的LAF 检查是否有副作用(在撞墙后拖动显示为无响应 | |
本站网友 婴儿大便颜色 | 6分钟前 发表 |
newHeight)) return; f.setBounds(newX | |
本站网友 阳狮锐奇集团 | 11分钟前 发表 |
with "unrespive" 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 | |
本站网友 273 | 13分钟前 发表 |
以便它们不会允许这样做? When I have a JInternalFrame in a JDesktopPane | |
本站网友 图书查询 | 12分钟前 发表 |
JDesktopPane.POPUP_LAYER); frame.setContentPane(tableDisplay); frame.setDefaultCloseOperation(JFrame.EXIT_O_CLOSE); frame.setMinimumSize(new Dimension(400 |