您的位置首页百科知识

怎么解决substance运行时的一个报错问题

怎么解决substance运行时的一个报错问题

的有关信息介绍如下:

怎么解决substance运行时的一个报错问题

Substance是swing的一个开源外观皮肤,在UI美化方面挺好用

在使用这款皮肤的时候不可避免会出现报错

本文分享使用Substance出现“Component creation must be done on Event Dispatch Thread”异常的解决办法

先来看看出现报错的代码:

package chapter4;

import com.sun.java.swing.plaf.windows.WindowsProgressBarUI;

import org.jvnet.substance.skin.SubstanceBusinessBlackSteelLookAndFeel;

import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.concurrent.TimeUnit;

/**

* Created by MyWorld on 2016/3/24.

*/

public class SwingJProgressBarDemo {

public static void main(String[] args) throws UnsupportedLookAndFeelException {

UIManager.setLookAndFeel(new SubstanceBusinessBlackSteelLookAndFeel());

常陕 JFrame.setDefaultLookAndFeelDecorated(true);

JFrame frame = new JFrame("JProgressBarDemo");

frame.setSize(400, 200);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new FlowLayout());

final JProgressBar progressBar = new JProgressBar();

progressBar.setOrientation(JProgressBar.HORIZONTAL);

progressBar.setSize(200, 100);

progressBar.setMinimum(0);

progressBar.setMaximum(100);

progressBar.setStringPainted(true);

progressBar.setUI(new WindowsProgressBarUI());

frame.add(progressBar);

JButton btn = new JButton("Start ProgressBar");

btn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

for (int i = 0; i <= 10; i++) {

progressBar.setValue(i * 10);

板国 try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

}

}

孝亲温});

}

}); frame.add(btn);

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

}

执行上面的代码报错了:

org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread

at org.jvnet.substance.utils.SubstanceCoreUtilities.testComponentCreationThreadingViolation(SubstanceCoreUtilities.java:2368)

at org.jvnet.substance.SubstancePanelUI.createUI(SubstancePanelUI.java:57)

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:57)

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.MethodUtil.invoke(MethodUtil.java:260)

at javax.swing.UIDefaults.getUI(UIDefaults.java:754)

at javax.swing.UIManager.getUI(UIManager.java:989)

at javax.swing.JPanel.updateUI(JPanel.java:109)

at javax.swing.JPanel.(JPanel.java:69)

从报错上看是因为直接在UI线程中初始化控件导致的:

org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread

把初始化Swing组件的代码都写到SwingUtilities.invokeLater后面的Runnable实例中

更改后的代码如下:

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

final JFrame frame = new JFrame("JProgressBarDemo");

frame.setSize(400, 200);

frame.setLocationRelativeTo(null);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new FlowLayout());

final JProgressBar progressBar = new JProgressBar();

progressBar.setOrientation(JProgressBar.HORIZONTAL);

progressBar.setSize(200, 100);

progressBar.setMinimum(0);

progressBar.setMaximum(100);

progressBar.setStringPainted(true);

progressBar.setUI(new WindowsProgressBarUI());

frame.add(progressBar);

JButton btn = new JButton("Start ProgressBar");

btn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

new Thread((new Runnable() {

@Override

public void run() {

for (int i = 0; i <= 10; i++) {

progressBar.setValue(i * 10);

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e1) {

e1.printStackTrace();

}

}

}

})).start();

}

});

frame.add(btn);

frame.setVisible(true);

}

});

运行下看看

换个皮肤

执行下看看效果

不错O

Code:

UIManager.setLookAndFeel(new SubstanceAutumnLookAndFeel());