开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜