论坛首页 Java企业应用论坛

开源项目Visual Swing for Eclipse

浏览 125011 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-08-14  
VE项目已经基本上停止了。而且他们的设计理念和我的不一样,我也不认同他们的做法。他们是启动另外一个Java虚拟机来渲染界面,非常消耗内存和性能。有几个界面设计器就得启动几个虚拟机,这不太现实。
1 请登录后投票
   发表时间:2008-08-25  
“设置鼠标为等待状态后,如何使得鼠标和键盘无效?”
http://www.iteye.com/post/641385

发到论坛,但是无回复。只有请Willam Chen亲自出山了。但又不知道怎么提交给Willam Chen,所以占用此帖子中的位置啦。


Willam Chen可否给个建议??谢谢:)
0 请登录后投票
   发表时间:2008-08-25  
找到该组件的顶层容器,假设该顶层容器是个JFrame,只要简单将它禁止就行了:
frame.setEnabled(false);
如果知道顶层容器是谁,简单的调用其setEnabled(false),如果不知道,调用SwingUtilities.getWindowAncestor获得其顶层窗口,然后调用setEnabled(false):
Window win = SwingUtilities.getWindowAncestor(c);
win.setEnabled(false);

这样能阻止所有的事件包括键盘事件到达当前窗口内的任何组件。
0 请登录后投票
   发表时间:2008-08-25  
rehte 写道
找到该组件的顶层容器,假设该顶层容器是个JFrame,只要简单将它禁止就行了:
frame.setEnabled(false);
如果知道顶层容器是谁,简单的调用其setEnabled(false),如果不知道,调用SwingUtilities.getWindowAncestor获得其顶层窗口,然后调用setEnabled(false):
Window win = SwingUtilities.getWindowAncestor(c);
win.setEnabled(false);

这样能阻止所有的事件包括键盘事件到达当前窗口内的任何组件。


非常非常感谢 William Chen 的回复。谢谢,呵呵

不过问题还没有全部解决,如果有时间,麻烦再给指点下
这么作会阻止所有事件到达当前窗口内的任何组件。但我仅仅想阻止事件到达其中一部分的组件。比方说,我的JFrame的contentPanel的内容是:

northPanel
centerPanel
southPanel

我只想阻止事件到达southPanel中的所有组件(对于northPanel,和centerPanel事件仍然可以到达),对于这种要求,咋实现呢?
我试着southPanel.setEnable(false),但是没有效果。。

我有个思路是这样实现:对于southPanel的任何一个子孙组件都添加 鼠标键盘监听器 。监听器中这么处理:如果当前状态是禁止southPanel的所有事件,则在监听器中不作任何事情就直接返回;如果不需要禁止,则正常处理。

但是这样实现时,每次在southPanel中加入组件时,都要注册这种特殊的监听器。
是否有其他方式,比方说在事件从OS传递给Swing后,在事件从Top-level组件向下传递的某个环节中直接把事件拦截掉。我觉得应该是有这种方法的,但是不知道在啥地方拦截,看了下Swing的源码找了半天也没找到。

谢谢:)
0 请登录后投票
   发表时间:2008-08-26  
你的思路无法实现
除非你自己实现一个事件派发 然后push到systemEventQueue 然后自己处理 相当麻烦
建议你还是在blocking dialog 或者 glasspanel上做文章
0 请登录后投票
   发表时间:2008-08-26  
insiku 写道
你的思路无法实现
除非你自己实现一个事件派发 然后push到systemEventQueue 然后自己处理 相当麻烦
建议你还是在blocking dialog 或者 glasspanel上做文章


1、在blocking dialog 上实现,会阻止事件到达dialog上所有的组件(而不是阻止事件到达部分组件)。

2、在glasspanel可以阻止鼠标事件,但是却不能阻止键盘事件。而这也正是我最疑惑的地方,为什么glasspanel可以阻止鼠标事件却不能阻止键盘事件呢?看Swing本身的事件分发代码,但是也没看出来咋回事??
0 请登录后投票
   发表时间:2008-08-26  
这种情况没有什么捷径,唯一的办法就是遍历容器内所有组件设置他们的enable状态:
void disableContainer(Container container){
    int count = container.getComponentCount();
    for(int i=0;i<count;i++){
       Component component = container.getComponent(i);
       component.setEnabled(false);
    }
    container.setEnabled(false);
}

enable方法类似。
0 请登录后投票
   发表时间:2008-08-27  
我收回我昨天说的话

不管是在glasspane上 还是 在JLayeredPane.POPUP_LAYER 上做文章 都可以实现 blocking

键盘事件无法阻止 可能是blocking pane 无法获得焦点导致
另外要注意的是 tab切换焦点 blocking pane 要加上InputVerifier 保持焦点

不过这种方式 会把这个顶层窗体都blocking掉  如果想block单独的组件 那可能需要组件继承JRootPane

不过swing的设计太强大了  应该还有其他办法
比如说blocking pane中添加鼠标和键盘的监听 根据鼠标位置判断是否需要consume事件
不过这种方式会使用户迷糊 鼠标的变化不够明显 用户会迷惑为什么不能输入
0 请登录后投票
   发表时间:2008-08-27  
glasspane无法阻止键盘事件,是因为键盘事件是直接发送到当前焦点组件上的。glasspane一般是jpanel或者其他非focusable的容器,因此它们无法获得焦点。但是你可以通过设置glasspane为focusable,然后通过调用requestfocus来获得焦点,然后应该就可以屏蔽键盘事件了。
JComponent glass = ...;
glass.setVisible(true);
glass.addMouseLis...;
glass.addKeyLi...;
glass.setFocusable(true);
glass.requestFocus();

需要注意的是上面的代码中glass的setVisible(true)必须在glass.setFocusable和glass.requestFocus之前,否则glass无法获得焦点,也就无法拦截键盘事件。
1 请登录后投票
   发表时间:2008-08-27  
rehte 写道
glasspane无法阻止键盘事件,是因为键盘事件是直接发送到当前焦点组件上的。glasspane一般是jpanel或者其他非focusable的容器,因此它们无法获得焦点。但是你可以通过设置glasspane为focusable,然后通过调用requestfocus来获得焦点,然后应该就可以屏蔽键盘事件了。
JComponent glass = ...;
glass.setVisible(true);
glass.addMouseLis...;
glass.addKeyLi...;
glass.setFocusable(true);
glass.requestFocus();

需要注意的是上面的代码中glass的setVisible(true)必须在glass.setFocusable和glass.requestFocus之前,否则glass无法获得焦点,也就无法拦截键盘事件。


键盘事件直接发送到当前焦点组件上
如果不在事件派发上做动作 那只能使被阻止的组件获得焦点

glasspane获得焦点以后 要设置InputVerifier  避免使用tab切换焦点
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics