我遇到了一个奇怪的情况。在某些情况下(非活动超时),我必须锁定我的swing窗口(以及任何子窗口),在通过有效凭据再次解锁后,我需要重新解锁它们。
我正在使用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方法,为了保持应用程序之间的一致性,我必须使用它。所以我只能让它工作,别无选择。
更新
@垃圾上帝,我已经把线程转储了,不幸的是无法连接它。我需要调查什么?最后三行是“VM线程”prio=10 tid=0x28688000 nid=0x5e58 runnable
"VM定期任务线程"prio=10 tid=0x28721c00 nid=0x2bc0等待条件
JNI全球参考文献:19887
有什么帮助吗?我应该看什么?“VM定期任务线程”??一些具体的州哪一个?
我如何在线程转储上接受帮助。我没有通过SO,在这里超过了char限制。
我解决了这个问题。
这个答案对我帮助很大。java swing清除事件队列实际上关键概念是相同的。
对于代码部分,我用
锁窗口
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);
}
}
}
解锁窗口
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,并按照@trashgood的说法对其进行了分析。我发现这也是正确的,嗯,没有什么阻碍/错误。虽然是的,但AWTEventQueue-0始终处于同一个代码点。
问题内容: 我正在使用Hibernate,试图模拟2个并发更新到数据库中的同一行。 编辑:我将em1.getTransaction()。commit移到em1.flush()之后;我没有收到任何StaleObjectException,两个事务已成功提交。 我在上遇到以下异常。为什么? 问题答案: 好吧,您正试图陷入僵局,并且成功了:-) Transaction1开始,与您的实体更新(和锁定)行。
问题内容: 以下代码取自的JavaDoc: 想象一下, 消费者 和 生产者这 两个线程,一个正在使用,一个在单个实例上。 假设 消费者 先运行,然后锁定,然后循环运行。 现在, 生产者 如何才能通过锁定已由 消费者 持有的来进入方法? 我在这里想念什么?是线程正在等待其条件之一时“临时释放”吗?锁的重新 进入 到底意味着什么? 问题答案: 双方并允许一个线程等待的时候,另一个线程可以获得锁放弃锁。
我使用一个restendpoint来启动一个java进程,使用executeWithLock,它接收一个LockingTaskExecutor。TaskWithResult(TaskWithResult的调用方法调用java进程/方法)。这很好,它只允许在任何时间点执行java进程,我可以从TaskResult获得执行状态。在某些情况下,java进程长时间运行,而rest调用在进程仍在执行时暂停,
在我的Rails 4应用程序中,我有一个对Postgres 9.4数据库的查询: 很受这个相关回答的启发dba.SE. 我只想让我的查询找到并更新第一行(随机地,用< code>LIMIT),其中< code>available = true并将其更新为< code>available = false,我需要在执行此操作的同时锁定该行,但不需要发出新的请求来等待前一个锁的释放,因为有许多并发调用将
问题内容: 在我的Rails 4应用程序中,我将查询查询到Postgres 9.4 数据库: dba.SE上的相关答案极大地启发了我们。 我只希望查询在其中找到并更新第一行(并将其随机更新为),然后将其更新为,而我需要在执行此操作时锁定该行,但无需发出新的请求来等待释放先前的锁,因为许多将使用此查询的 并发调用 。 但我也看到了选择。我不确定我是否理解使用和选项之间的区别,在我看来它们似乎可以实现
我正在编写一个应用程序来管理或自定义Android设备的解锁屏幕。它的工作原理如下: 用户使用电源按钮锁定屏幕。 用户尝试解锁屏幕,从而再次按下电源按钮 我的活动弹出--屏幕仍然锁定 用户回答问题,如果答案正确,屏幕解锁 我已经为第三步创建了一个活动,并将以下代码添加到其方法中: 这工作正常,完全符合我的期望。我的问题是第四步。我已经搜索并找到了许多解决方案,但没有一个适合我。 如何以编程方式锁定