java/swing: JSlider.setValue is blocking
my call to JSlider.setValue is sometimes blocking the thread which results ins a deadlock of the whole application.
here is the stacktrace of the blocking thread.
Thread [RenderThread] (Suspended)
JSlider(Component).getMousePosition() line: not available [local variables unavailable]
SynthSliderUI.calculateThumbLocation() line: not available [local variables unavailable]
BasicSliderUI$Handler.stateChanged(ChangeEvent) line: not available
DefaultBoundedRangeModel.fireStateChanged() line: not available [local variables unavailable]
DefaultBoundedRangeModel.setRangeProperties(int, int, int, int, boolean) line: not available
DefaultBoundedRangeModel.setValue(int) line: not available
JSlider.setValue(int) line: not available
TimeLine.setTime(double) line: 422
GLFrame.display() line: 302
GLFrame$2.renderCallback() line: 188
LWJGLBinding$1.paintGL() line: 49
LWJGLBinding$1(AWTGLCanvas).paint(Graphics) line: 314
LWJGLBinding$1(AWTGLCanvas).update(Graphics) line: 343
GLFrame$2(LWJGLBinding).startRendering() line: 78
GLFrame$3.run() line: 267
this seems to be linked to the nimbus look and feel, cause i doesnt happen in the default look and feel.
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch (Exception e)
{
e.printStackTrace();
}
edit: with invokeLater i do get this exception:
at javax.swing.plaf.synth.SynthTreeUI.pai开发者_StackOverflow中文版nt(Unknown Source)
at javax.swing.plaf.synth.SynthTreeUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Swing components are not thread-safe. Anything, that modifies Swing component after it is already shown, must be executed in the so-called Event Dispatch Thread (EDT). To achieve this, Swing grants you thee functions:
Two of them serves for code execution:
SwingUtilities.invokeLater(Runnable)
SwingUtilities.invokeAndWait(Runnable)
Their purpose comes from their name. Third is
SwingUtilities.isEventDispatchThread()
If this returns true
, then you're already in the EDT and may execute code directly.
Note, that invokeAndWait
will throw an exception, if it is called directly from EDT (invokeLater
will not, but it is still not recomended to do so), so the code, that may be called from both EDT and side thread, should be written as follows:
if (SwingUtilities.isEventDispatchThread()) {
// code
} else {
SwingUtilities.invokeLater(new Runnable () {
public void run () {
// code
}
});
}
For the purpose of simplicity and readability, you may extract inner code to a method.
精彩评论