Closed mokun closed 5 years ago
This sounds a lot like a usage of Swing component outside of Event Dispatch Thread (EDT). I think it might be the case mostly because you said:
... Sometimes (but not all the time) ...
And also log says:
Exception in thread "pool-2-thread-5"
Which certainly doesn't sound like it's an EDT, although that particular call might not be the only thing causing the issue - usually it is a mix of things being called in parallel, like multiple UI updates or repaints.
If you aren't familiar with EDT - you can read more about it here: Event Dispatch Thread
Generally speaking - any UI-related code must be executed on EDT with no exceptions. While Swing does not enforce that and usually runs without exceptions - it is not guaranteed and usually causes a lot of random exceptions in larger applications or some unique cases.
I couldn't really reproduce the exception you've shown on a standalone example:
public class DesktopTest
{
public static void main ( final String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
@Override
public void run ()
{
try
{
WebLookAndFeel.install ();
final JDesktopPane desktopPane = new JDesktopPane ();
desktopPane.setPreferredSize ( new Dimension ( 600, 600 ) );
final JInternalFrame frame = new JInternalFrame ( "Frame", true, false, true, true );
final JButton update = new JButton ( "Sample" );
update.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
desktopPane.updateUI ();
}
} );
frame.add ( update );
desktopPane.add ( frame );
frame.setClosed ( false );
frame.setIcon ( false );
frame.setLocation ( 25,25 );
frame.pack ();
frame.setVisible ( true );
TestFrame.show ( desktopPane );
}
catch ( final PropertyVetoException ignored )
{
//
}
}
} );
}
}
Note that i do perform all UI operations within EDT in this example, including code in ActionListener
- it just doesn't need to be queued because all Swing component events are already fired within EDT and you can simply perform UI-related operations in the listener directly.
So, what I would suggest first - try enabling this option:
WebLookAndFeel.setForceSingleEventsThread ( true );
Right at the start of your application, before you install L&F or create any UI elements. If you have any Swing code running outside of EDT - it will throw exceptions and halt further execution of the Swing-related code.
If you want to simply receive exceptions but allow UI to continue running - you can also setup a different handler for those exceptions, for instance this one:
WebLookAndFeel.setNonEventThreadHandler ( new NonEventThreadHandler ()
{
@Override
public void handle ( final RuntimeException e )
{
LoggerFactory.getLogger ( DesktopTest.class ).error ( e.getMessage (), e );
}
} );
You can also read more about this option here: Forced EDT usage
Once it's set - try running your application, if there is anything wrong with UI code usage - you would usually get a handful of exceptions pointing at exact locations of the non-EDT calls that must be invoked within EDT. Once you find them - you'll need to move their execution to EDT, sometimes it's simple, sometimes it's complicated - all depends on how your application code is written and structured so I can't really give any specific advice here.
Once you have everything running smooth and without any exceptions thrown - WebLaF exception you've shown should go as well. But if the exception is still there - then it might have something to do with your application code in particular. Some tricky component use case or some additional code that interferes with component or it's UI logic. Or maybe a faulty style. There could be quite a few issues and I can't really tell what it is exactly without a standalone example that would reproduce the issue.
Just a side not about EDT - it's usage necessity is not dictated by WebLaF, but by Swing itself. You can read the official Oracle guide about Event Dispatch Thread usage it here: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
Yes as soon as I wrap around my setLookAndFeel()
inside SwingUtilities.invokeLater()
, the problem is gone. setLookAndFeel()
is where I declare the use of weblaf.
Thanks !
Glad that helped :)
Swing can be unpredictable when used outside of EDT, so I do strongly recommend following the practice of running all UI-related code in EDT - that should save you a lot of time in the future.
Hi,
I use a JDesktopPane for an app.
Sometimes (but not all the time) when I start the app in Eclipse, it complains about the StyleException as follows :
In my MainDesktopPane, I already initializes weblaf with
However, it's when I call
super.updateUI()
inside an overriding method that it creates this Exception.What's the workaround on this ?
Thanks !