使用玻璃板从摆动组件中移除鼠标事件/控件

时间:2010-02-17 12:57:38

标签: swing cursor glasspane

我有一个客户端 - 服务器应用程序,我在客户端使用swing。我的swing客户端有一个主窗口(jframe)和许多面板,工具栏和菜单栏。 当客户端通过glasssPane等待来自服务器的响应时,我想删除所有客户端操作/鼠标事件(或者只是抓取并且什么都不做)。 这是我写的代码:

private final static MouseAdapter mouseAdapter = new MouseAdapter() 
{
  public void mouseClicked(MouseEvent e) 
  {
   System.out.println("MouseClicked..!");
  }
 };

private static Cursor WAIT_CURSOR = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
private static Cursor DEFAULT_CURSOR = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);

public static void startWaitCursor(JComponent comp)
{
  MainWindow root = ((MainWindow) comp.getTopLevelAncestor());

  root.getGlassPane().setCursor(WAIT_CURSOR);
  root.getGlassPane().addMouseListener(mouseAdapter);
  root.getGlassPane().setVisible(true);
}

public static void stopWaitCursor(JComponent comp)
{    
  MainWindow root = ((MainWindow) comp.getTopLevelAncestor()); 

  root.getGlassPane().setCursor(DEFAULT_CURSOR);
  root.getGlassPane().setVisible(false);
}

但我无法管理抓取鼠标事件。更改glassPane上的游标工作正常,但要么我无法添加mouseAdapter,要么无法使glasssPane成为顶级组件。

有什么想法吗?

感谢。

2 个答案:

答案 0 :(得分:1)

我意识到我的代码正在运行但我的问题与线程相关。我的代码类似于:

startWaitCursor(); 
work(); // server request that takes time 
stopWaitCursor();

并将其更改为:

startWaitCursor(); 
SwingUtilities.invokeLater(new Runnable() {
poblic void run() { 
try 
{ 
work(); // server request 
} 
finally 
{ 
stopWaitCursor(); 
}

通过执行此修改,我可以看到我在startWaitCursor()方法中进行的设置,而客户端正在等待来自服务器的响应。

但是有一个小问题。在startWaitCursor()方法中,我为玻璃窗格设置了密钥,鼠标和焦点事件,但是主框架仍会捕获事件,甚至会显示glassPane。

addMouseListener(new MouseAdapter() {});
addMouseMotionListener(new MouseMotionAdapter() {});
addKeyListener(this);
setFocusTraversalKeysEnabled(false);

服务器响应到达客户端后,调用stopWaitCursor()方法在主框架中处理事件。

如果我在客户端等待时禁用我的应用程序的主框架而不是光标没有被更改为wait_cursor,如果我没有禁用主框架,则光标正在被更改,但事件已排队。

...欢呼声

答案 1 :(得分:1)

在挖掘线程问题几天之后,我终于找到了真正的答案:SwingWorker

现在我的最终代码就是,

startWaitCursor();
SwingWorker worker = new SwingWorker() {
   public Object doInBackground() 
   {
      doWork(); // time consuming server request
      return null;
   }
   public void done() 
   {
      stopWaitCursor();
   }
};
worker.execute();

在startWaitCursor()方法中,我将glasspane设置为可见(带有alpha值的背景),显示一条消息,警告用户耗时的工作,将光标设置为wait_cursor(沙漏)并使用所有键,鼠标事件。这就对了。

通过使用SwingWorker,我的客户端实际上是响应式的(它的工作方式就像没有服务器请求一样)但是因为我显示了glasspane并且消耗了所有键和鼠标事件,所以感觉就像是反应迟钝。

真是一种解脱...... SwingWorker摇滚......

欢呼声..