JOptionPane gives an error
-
29-06-2021 - |
Question
I want to handle some exceptions using JOptionPane
s. This is the main method:
public class MainRun {
public static void main(String args[]){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(new SubstanceRavenGraphiteGlassLookAndFeel());
}catch (Exception e){
e.printStackTrace();
}
new MainGui().setVisible(true);
new Initialized().start();
new PriorityMessageQueue().start();
}
});
MainGui
is the main window (JFrame
) of the application.
I handled exception inside the PriorityMessageQueue
thread.
public class PriorityMessageQueue extends Thread {
@Override
public void run() {
while (true) {
try {
instantMessages = instant.getMobitelMessagesToBeSent();
} catch (Exception ex) {
JOptionPane.showMessageDialog(
null,
ex.getMessage(),
"Database Error",
JOptionPane.ERROR_MESSAGE);
}
...
after I run this, I'm getting an error
org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread
at org.jvnet.substance.utils.SubstanceCoreUtilities.testComponentCreationThreadingViolation(SubstanceCoreUtilities.java:2312)
at org.jvnet.substance.SubstanceOptionPaneUI.createUI(SubstanceOptionPaneUI.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:37)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:244)
at javax.swing.UIDefaults.getUI(UIDefaults.java:752)
at javax.swing.UIManager.getUI(UIManager.java:989)
at javax.swing.JOptionPane.updateUI(JOptionPane.java:1859)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1822)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1785)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1753)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1731)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1711)
at GUI.MainGui.showOptionPane(MainGui.java:1039)
at SMS.PriorityMessageQueue.run(PriorityMessageQueue.java:86)
UIDefaults.getUI() failed: createUI() failed for
javax.swing.JOptionPane
[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,p
referredSize=,icon=,initialValue=,message=DatabaseConnection class
connect,messageType=ERROR_MESSAGE,optionType=DEFAULT_OPTION,wantsInput=false]
java.lang.reflect.InvocationTargetException
java.lang.Error
at javax.swing.UIDefaults.getUIError(UIDefaults.java:712)
at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:133)
at javax.swing.UIDefaults.getUI(UIDefaults.java:758)
at javax.swing.UIManager.getUI(UIManager.java:989)
at javax.swing.JOptionPane.updateUI(JOptionPane.java:1859)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1822)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1785)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1753)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1731)
at javax.swing.JOptionPane.<init>(JOptionPane.java:1711)
at GUI.MainGui.showOptionPane(MainGui.java:1039)
at SMS.PriorityMessageQueue.run(PriorityMessageQueue.java:86)
And the JOptionPane
will not display properly!
Instead of passing null
to JOptionPane
, how can I get the parentComponent (MainGui
JFrame
)?
La solution
A JOptionPane
is a mini Swing GUI, and like all Swing GUIs, it must be created on the Swing event thread, not on a background thread. This can be done by creating your JOptionPane
in a Runnable
and then queuing the Runnable
on the event thread:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(....);
}
});
For example,
} catch (Exception ex) {
final String exMessage = ex.getMessage();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(
null,
exMessage,
"Database Error",
JOptionPane.ERROR_MESSAGE);
);
}
});
}
}
As for your question,
Instead of passing
null
toJOptionPane
, how can I get the parentComponent (MainGui
JFrame
)?
You'll need a reference to the main GUI. How you get this will depend on how your program is organized.
Autres conseils
Substance
is EDT very sensitive, all updates must be done on EDTotherwise you can see only
toolbar
(came fromNative OS
) fromSwing JComponen
tsor exceptions from
RepaintManager
(I think that fromTrident
package)JOptionPane
must be wrapped intoinvokeLater()
, then yourJOptionPane
coudl be visible,I think your
exception
talking about another issue, something hidden in your code, maybe there isn't something with usedSubstance L&F
, this is secondary issue