2013-12-06 7 views
0

Я испытываю странную ситуацию. При некотором условии (тайм-аут бездействия) я должен заблокировать мое окно поворота (и любые подокна) и после разблокировки с помощью действительных учетных данных мне нужно разблокировать их все.Свинг переходит в состояние ожидания после блокировки разблокировки через стеклянную панель

Я использую glasspane противника, что и мои две функции, как показано ниже

Основной модуль блокировки

public void lock(boolean minimize) { 
    if (!locked) { 
     locked = true; 
     lockMinimized = minimize; 
     logger.debug(context + "Locking Target..."); 
     // Lock all frames using the AWT event dispatching thread. 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       Frame[] frames = Frame.getFrames(); 
       Window[] subwindows; 
       for (Frame frame : frames) { 
        // Lock the frame itself 
        lockWindow(frame); 

        // Lock subwindows owned by the frame 
        subwindows = frame.getOwnedWindows(); 
        for (Window subwindow : subwindows) { 
         if (subwindow instanceof RootPaneContainer) { 
          lockWindow(subwindow); 
         } 
        } 
       } 
       //do additional stuff - lock out of process windows 
       if (lockUnlockInterface != null) { 
        logger.info("calling locking for out of jvm process "); 
        lockUnlockInterface.lock(); 
       } 
      } 
     }); 
     logger.debug(context + "Target locked."); 
    } 
} 

Sub замок метод

private void lockWindow(final Window window) { 
    logger.debug(context + "Locking window: " + window.getClass().toString()); 
    Vector exemptWindowClassNames = getExemptList(); 
    if (window instanceof RootPaneContainer 
      && ((RootPaneContainer) window).getRootPane() != null 
      && !lockedWindows.containsKey(window) 
      && !(exemptWindowClassNames.contains(window.getClass().toString()))) { 
     logger.debug(context + "Locking window..."); 
     try { 
      // Create an object to store original details for the locked window. 
      LockedWindow lockedWindow = new LockedWindow(); 
      lockedWindows.put((RootPaneContainer) window, lockedWindow); 

      // Remember the original glass pane and visibility before locking. 
      lockedWindow.originalGlassPane = ((RootPaneContainer) window).getGlassPane(); 
      lockedWindow.wasVisible = ((RootPaneContainer) window).getContentPane().isVisible(); 

      // Add a LockedGlassPane to the window. 
      LockedGlassPane lgp = new LockedGlassPane(); 
      lgp.setVisible(true); //hide the contents of the window 
      ((RootPaneContainer) window).setGlassPane(lgp); 
      ((RootPaneContainer) window).getContentPane().setVisible(false); 
      lgp.setVisible(true); //redisplays the lock message after set as glassPane. 
      ((RootPaneContainer) window).getContentPane().invalidate(); 

      // Minimize the window (if requested), while keeping a record of 
      // which windows have been minimized so that they can be restored 
      // later when the TimeoutTarget is unlocked. 
      if (window instanceof Frame) { 
       Frame frame = (Frame) window; 
       // Remember the original minimized state of the window. 
       lockedWindow.minimized = (frame.getExtendedState() & Frame.ICONIFIED) != 0; 
       if (lockMinimized) { 
        frame.setExtendedState(Frame.ICONIFIED); 
       } 
      } 

      // 
      //Note required now, but keeping in case the requirement changes again. 
      // 
      // Prevent the window from being closed while this target is 
      // locked. 
      // lockedWindow.windowListeners = window.getWindowListeners(); 
      // for (WindowListener wl : lockedWindow.windowListeners) { 
      //  window.removeWindowListener(wl); 
      // } 
      //if (window instanceof JFrame) { 
      // JFrame jframe = (JFrame) window; 
      // lockedWindow.originalDefaultCloseOperation = jframe.getDefaultCloseOperation(); 
      // jframe.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
      //} else if (window instanceof JDialog) { 
      // JDialog jdialog = (JDialog) window; 
      // lockedWindow.originalDefaultCloseOperation = jdialog.getDefaultCloseOperation(); 
      // jdialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
      //} 
     } catch (Exception e) { 
      logger.error(context + "Failed to lock window.", e); 
     } 
    } 
    if (exemptWindowClassNames.contains(window.getClass().toString())) { 
     window.toFront(); 
    } 
} 

разблокировать основной метод

общественный вакуум unlock() { locked = false; lockMinimized = false;

EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      Window[] subwindows; 
      for (RootPaneContainer window : lockedWindows.keySet()) { 
       // Unlock the frame itself. 
       unlockWindow(window); 

       // Unlock subwindows owned by the frame. 
       if (window instanceof Frame) { 
        subwindows = ((Frame) window).getOwnedWindows(); 
        for (Window subwindow : subwindows) { 
         if (subwindow instanceof RootPaneContainer) { 
          unlockWindow((RootPaneContainer) subwindow); 
         } 
        } 
       } 
      } 

      lockedWindows.clear(); 

      //do additional stuff - lock out of process windows 
      if (lockUnlockInterface != null) { 
       logger.info("calling unlocking for out of jvm process "); 
       lockUnlockInterface.unlock(); 
      } 
     } 
    }); 
} 

суб метод разблокировки

private void unlockWindow(RootPaneContainer window) { 
    try { 
     LockedWindow lockedWindow = lockedWindows.get(window); 
     logger.debug(context + "Unlocking window: " + window); 
     if (lockedWindow != null) { 
      logger.debug(context + "Unlocking..."); 
      // Restore the original glasspane for the window 
      if (lockedWindow.originalGlassPane != null) { 
       logger.debug(context + "Reset original glass pane."); 
       window.setGlassPane(lockedWindow.originalGlassPane); 
      } 
      //make content pane visible again. 
      (window).getContentPane().setVisible(lockedWindow.wasVisible); 
      (window).getRootPane().invalidate(); 

      // Restore (un-minimize) the window if it wasn't minimized before 
      // the lock. 
      if (!lockedWindow.minimized && window instanceof Frame) { 
       ((Frame) window).setExtendedState(((Frame) window).getExtendedState() 
         & ~Frame.ICONIFIED); 
      } 
      // Restore the original default close operation from before the 
      // lock, which will normally allow the window to be closed. 
      if (window instanceof Window) { 
       if (lockedWindow.windowListeners != null) { 
        for (WindowListener wl : lockedWindow.windowListeners) { 
         ((Window) window).addWindowListener(wl); 
        } 
       } 
       if (window instanceof JFrame) { 
        ((JFrame) window) 
          .setDefaultCloseOperation(lockedWindow.originalDefaultCloseOperation); 
       } else if (window instanceof JDialog) { 
        ((JDialog) window) 
          .setDefaultCloseOperation(lockedWindow.originalDefaultCloseOperation); 
       } 
      } 
      logger.debug(context + "Window has been unlocked"); 
     } 
    } catch (Exception e) { 
     logger.error(context + "Failed to unlock window.", e); 
    } 

} 

Просто повторить еще раз Мой замок и разблокировать случается успешно. Хорошо разблокировать не удается, потому что после разблокировки остается загруженный курсор над моим разблокированным окном. Это так же хорошо, как и прошло. Бесполезный.

Я видел из журналов, я получаю успешный выход из разблокировки. Тогда я не знаю, что шляпа заставляет этот загруженный курсор появляться и блокировать что-либо в моем окне.

У меня эти журналов тоже, и они довольно тонкие

Я не уверен, что является причиной этого тогда?

Возможные виновники и вещи, которые я пытался

  1. не делает недействительной блокировки разблокировки
  2. установка glasspane обнулить явно
  3. не делает никакого слушателя материал

Все это в нет ситуация остается спокойной.

Кто-нибудь испытал то же самое, может дать мне указатели, пожалуйста?

Единственное ограничение, которое у меня есть, я не могу оставить метод стекла, чтобы поддерживать однородность между приложениями, я должен использовать это. Поэтому я должен заставить это работать, никаких альтернатив.

UPDATE

@trashgod Я взял дамп нить К сожалению, не в силах, чтобы прикрепить ее. Что мне нужно для этого? Последние три строки "VM темы" PRIO = 10 TID = 0x28688000 нидь = 0x5e58 Runnable

"VM Периодическая задач темы" PRIO = 10 TID = 0x28721c00 нидь = 0x2bc0 ждущие при условии

JNI глобальные ссылки: 19887

Любая помощь по этому вопросу?На что я должен смотреть? «Периодическая задача задачи VM»? некоторые конкретные состояния, какие?

Как я могу получить помощь в дампе потока. Я не пролетел через SO, пересекая границу лимита.

+0

loop in Window [] wins = Window.getWindows() ;, если не null, isDisplayable, забыли для ZOO с суб-окнами, удалите, заблокируйте выполнение этого кода, виртуальный -100 на вопрос такого характера – mKorbel

+0

Код ссылки в форме SSCCE [Удалить контейнер верхнего уровня во время выполнения] (http://stackoverflow.com/questions/6309407/remove-top-level-container-on-runtime) – mKorbel

+0

[следует этой теме] (http: // stackoverflow. com/questions/20395528/uncatchable-error-with-jviewport-setview) – mKorbel

ответ

0

У меня проблема решена.

Этот ответ мне очень помог. java swing clear the event queue Infact ключ концепция такая же.

Так что для части кода я изменил модули с

lockWindow

private void lockWindow(final Window window) { 
    if (window instanceof RootPaneContainer 
      && ((RootPaneContainer) window).getRootPane() != null 
      && !lockedWindows.containsKey(window)) { 
     java.util.Timer timer = null; 
     try { 

      //don't do invalidate, invalidate as the first step 
      //((RootPaneContainer) window).getContentPane().invalidate(); 

      // Create an object to store original details for the locked window. 
      LockedWindow lockedWindow = new LockedWindow(); 
      lockedWindows.put((RootPaneContainer) window, lockedWindow); 

      lockedWindow.originalGlassPane = ((RootPaneContainer) window).getGlassPane(); 


      //okk may be glasspane only in integrated scenario is causing the issue 
      //comment it and check, we are still putting it in the map above but its doing nothing 
      /* 
      // Remember the original glass pane and visibility before locking. 

      //okk is this the only issue? What should be the originalGlassPane first time? null? 
      lockedWindow.originalGlassPane = ((RootPaneContainer) window).getGlassPane(); 
      System.err.println("Original galss pane : " + ((RootPaneContainer) window).getGlassPane()); 

      lockedWindow.wasVisible = ((RootPaneContainer) window).getContentPane().isVisible(); 

      // Add a LockedGlassPane to the window. 
      LockedGlassPane lgp = new LockedGlassPane(); 
      lgp.setVisible(true); //hide the contents of the window 
      ((RootPaneContainer) window).setGlassPane(lgp); 

      //don't do this stuff too 
      ((RootPaneContainer) window).getContentPane().setVisible(false); 

      lgp.setVisible(true); //redisplays the lock message after set as glassPane. 
      */ 
      LockedGlassPane lgp = new LockedGlassPane(); 
      ((RootPaneContainer) window).setGlassPane(lgp); 
      timer = switchToBusyCursor(window); 

      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
       //do nothing 
       System.err.println("Am I interrupted?"); 
      } 
      //okk the above thing worked, it doesnt lock naturlly, now try if setting visible code is an issue? 
      //great this thing works so this also is not an issue, only galsspane in SiteManager is 
      lockedWindow.wasVisible = ((RootPaneContainer) window).getContentPane().isVisible(); 

      ((RootPaneContainer) window).getContentPane().repaint(); 

      // Minimize the window (if requested), while keeping a record of 
      // which windows have been minimized so that they can be restored 
      // later when the TimeoutTarget is unlocked. 

      //don't do this stuff too - as unlock is not working investigating that 
      if (window instanceof Frame) { 
       Frame frame = (Frame) window; 
       // Remember the original minimized state of the window. 
       lockedWindow.minimized = (frame.getExtendedState() & Frame.ICONIFIED) != 0; 
       if (lockMinimized) { 
        frame.setExtendedState(Frame.ICONIFIED); 
       } 
      } 

      // 
      //Note required now, but keeping in case the requirement changes again. 
      // 
      // Prevent the window from being closed while this target is 
      // locked. 
      // lockedWindow.windowListeners = window.getWindowListeners(); 
      // for (WindowListener wl : lockedWindow.windowListeners) { 
      //  window.removeWindowListener(wl); 
      // } 
      //if (window instanceof JFrame) { 
      // JFrame jframe = (JFrame) window; 
      // lockedWindow.originalDefaultCloseOperation = jframe.getDefaultCloseOperation(); 
      // jframe.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
      //} else if (window instanceof JDialog) { 
      // JDialog jdialog = (JDialog) window; 
      // lockedWindow.originalDefaultCloseOperation = jdialog.getDefaultCloseOperation(); 
      // jdialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
      //} 
     } catch (Exception e) { 
      System.err.println(getThreadPrefix() + " Failed to lock window." + e.getLocalizedMessage()); 
     } finally { 
      switchToNormalCursorEventThread(window, timer); 
     } 
    }   
} 

unlockWindow

private void unlockWindow(RootPaneContainer window) { 
    try { 
     LockedWindow lockedWindow = lockedWindows.get(window); 
     //System.err.println(getThreadPrefix() + " Unlocking window::: " + lockeWindow.isDisplayable()); 
     if (lockedWindow != null && ((Frame) window).isDisplayable()) { 
      System.err.println(getThreadPrefix() + "Unlocking..." + lockedWindow); 
      // Restore the original glasspane for the window 

      //okk may be glasspane only in integrated scenario is causing the issue 
      //comment it and check, we are still putting it in the map above but its doing nothing 


      //okk is this the only issue? What should be the originalGlassPane first time? null? 
      if (lockedWindow.originalGlassPane != null) { 
       System.err.println(getThreadPrefix() + "Reset original glass pane."); 
       window.setGlassPane(lockedWindow.originalGlassPane); 
       //lockedWindow.originalGlassPane.setVisible(true); 
      } 


      //make content pane visible again. 
      //(window).getContentPane().setVisible(lockedWindow.wasVisible); 

      //okk try this 
      //(window).getContentPane().setVisible(true); 
      //(window).getRootPane().invalidate(); 

      //okk the above thing worked, it doesnt lock naturlly, now try if setting visible code is an issue? 
      //great this thing works so this also is not an issue 
      (window).getContentPane().setVisible(lockedWindow.wasVisible); 

      (window).getRootPane().repaint(); 

      // Restore (un-minimize) the window if it wasn't minimized before 
      // the lock. 
      //do this tuff anyways 
      if (!lockedWindow.minimized && window instanceof Frame) { 
       ((Frame) window).setExtendedState(((Frame) window).getExtendedState() 
         & ~Frame.ICONIFIED); 
      } 


      // Restore the original default close operation from before the 
      // lock, which will normally allow the window to be closed. 

      //dont do listeneres?? 
      if (window instanceof Window) { 
       if (lockedWindow.windowListeners != null) { 
        for (WindowListener wl : lockedWindow.windowListeners) { 
         System.err.print("windowlistener is not null " + wl); 
         ((Window) window).addWindowListener(wl); 
        } 
       } 
       if (window instanceof JFrame) { 
        ((JFrame) window) 
          .setDefaultCloseOperation(lockedWindow.originalDefaultCloseOperation); 
       } else if (window instanceof JDialog) { 
        ((JDialog) window) 
          .setDefaultCloseOperation(lockedWindow.originalDefaultCloseOperation); 
       } 
      } 

      //try this too 
      //((RootPaneContainer)window).setGlassPane(null); 

      //lockedWindows.remove(window); 
      //stopEventTrap 
      stopEventTrap((Frame)window); 
      System.err.println(getThreadPrefix() + " Window has been unlocked"); 
     } 
    } catch (Exception e) { 
     System.err.println(getThreadPrefix() + " Failed to unlock window. " + e.getLocalizedMessage()); 
    } 

} 

Добавлена ​​этих новых методов, взятых из выше ответа с модификациями, р [эр мой использование

public static java.util.Timer switchToBusyCursor(final Window frame) { 
    startEventTrap(frame); 
    java.util.TimerTask timerTask = new java.util.TimerTask() { 

     public void run() { 
      startWaitCursor(frame); 
     } 

    }; 
    final java.util.Timer timer = new java.util.Timer(); 
    timer.schedule(timerTask, DELAY_MS); 
    return timer; 
} 

public static void switchToNormalCursorEventThread(final Window window, final java.util.Timer timer) { 

    Runnable r = new Runnable() { 

     public void run() { 
      switchToNormalCursor(window, timer); 
     } 

    }; 

    javax.swing.SwingUtilities.invokeLater(r); 

} 

public static void switchToNormalCursor(final Window window, final java.util.Timer timer) { 
    timer.cancel(); 
    stopWaitCursor(window); 
    //stopEventTrap(window); 
} 

private static void startWaitCursor(Window window) { 
    ((RootPaneContainer) window).getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR)); 
    ((RootPaneContainer) window).getGlassPane().addMouseListener(mouseAdapter); 
    ((RootPaneContainer) window).getGlassPane().setVisible(true); 
} 

private static void stopWaitCursor(Window window) { 
    ((RootPaneContainer) window).getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR)); 
    //((RootPaneContainer) window).getGlassPane().removeMouseListener(mouseAdapter); 
    //((RootPaneContainer) window).getGlassPane().setVisible(false); 
} 

private static void startEventTrap(Window window) { 
    ((RootPaneContainer) window).getGlassPane().addMouseListener(mouseAdapter); 
    ((RootPaneContainer) window).getGlassPane().setVisible(true); 
} 

private static void stopEventTrap(Window window) { 
    java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue(); 
    ((RootPaneContainer) window).getGlassPane().removeMouseListener(mouseAdapter); 
    ((RootPaneContainer) window).getGlassPane().setVisible(false); 
} 

private static final java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter() { 
}; 

Я также взял threaddumps и проанализировал их, как сказал @trashgod. Я обнаружил, что это тоже правильно, ИМХО, там ничего не блокируется/нет. Хотя да, AWTEventQueue-0 всегда был в одной и той же кодовой точке.