我正在经历一个奇怪的情况。在某些情况下(不活动超时),我必须锁定我的摆动窗口(和任何子窗口),并且在通过有效凭据再次解锁后,我需要将它们全部解锁。
我正在使用 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.");
}
}
分锁方式
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();
}
}
解锁主要方法
公共无效解锁(){锁定=假;锁定最小化 = 假;
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);
}
}
只是再次重复我的锁定和解锁确实成功发生。解锁不成功,因为解锁后我的解锁窗口上仍然有一个忙碌的光标。它和消失一样好。无用。
我从日志中看到我成功地从解锁呼叫中退出。然后我不知道帽子会导致那个忙碌的光标出现并阻止我窗口上的任何东西。
我也有这些日志,它们很好
我不确定是什么原因造成的呢?
可能的罪魁祸首和我尝试过的事情
- 在锁定解锁时不做无效
- 将 glasspane 显式设置为 null
- 不做任何听众的事情
所有这些都无济于事,形势依然惨淡。
有谁有过同样的经历,可以指点一下吗?
我的一个限制是我不能离开玻璃板方法,为了保持应用程序之间的同质性,我必须使用它。所以我必须让这个工作,没有其他选择。
更新
@trashgod 我已经采取了线程转储不幸的是无法附加它。我需要调查什么?最后三行是“VM Thread”prio=10 tid=0x28688000 nid=0x5e58 runnable
“VM 周期性任务线程”prio=10 tid=0x28721c00 nid=0x2bc0 等待条件
JNI 全球参考:19887
对此有什么帮助吗?我应该看什么?“VM 周期性任务线程” ?? 一些具体的州是哪一个?
我如何获得有关线程转储的帮助。我没有通过 SO,在这里超过了字符限制。