在书上看到,swing是线程不安全的,对swing组件的操作最好用SwingUtilities.invokeLater()或SwingUtilities.invokeAndWait()
public class TestSwing {
private List<JLabel> jls;
private GridBagConstraints gbc;
public TestSwing() {
this.setLayout(new GridBagLayout());
} public void initGUI() {
/*
*这里是gbc的设定等
*/
for (JLabel jl: jls) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestSwing.this.add(jl);//eclipse一直提示这里的jl是非final的,编译错误
}
});
}
} public static void main(String arg[]) {
TestSwing ts = new TestSwing();
ts.setVisible(true);
}
}
如果initGUI()改为如下:........public void initGUI() {
SwingUtilities.invokeLater(new Runnable() {
/*
*这里是gbc的设定等
*/
for (JLabel jl: jls) {
TestSwing.this.add(jls);
}
});
}........
请问:
1、在run()里只放入TestSwing.this.add(jl)的话,eclipse一直报错(jl不是final);而如果改把所有gbc、foreach等都放入run()里面,我觉得是否有点过度使用SwingUtilities的线程分派了?改怎样写这个线程安全的initGUI()啊?2、在initGUI()里使用SwingUtilities.invokeLater()时,是否仍需要使用ReentrantLock来锁定initGUI()里的所有资源?
谢谢
public class TestSwing {
private List<JLabel> jls;
private GridBagConstraints gbc;
public TestSwing() {
this.setLayout(new GridBagLayout());
} public void initGUI() {
/*
*这里是gbc的设定等
*/
for (JLabel jl: jls) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestSwing.this.add(jl);//eclipse一直提示这里的jl是非final的,编译错误
}
});
}
} public static void main(String arg[]) {
TestSwing ts = new TestSwing();
ts.setVisible(true);
}
}
如果initGUI()改为如下:........public void initGUI() {
SwingUtilities.invokeLater(new Runnable() {
/*
*这里是gbc的设定等
*/
for (JLabel jl: jls) {
TestSwing.this.add(jls);
}
});
}........
请问:
1、在run()里只放入TestSwing.this.add(jl)的话,eclipse一直报错(jl不是final);而如果改把所有gbc、foreach等都放入run()里面,我觉得是否有点过度使用SwingUtilities的线程分派了?改怎样写这个线程安全的initGUI()啊?2、在initGUI()里使用SwingUtilities.invokeLater()时,是否仍需要使用ReentrantLock来锁定initGUI()里的所有资源?
谢谢
public void run() {
new TestSwing();
}
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
new Gui();
}
嗯谢了。如果TestSwing是个静态不变的界面,也许这样就行。而如果TestSwing里面有很多复杂的GUI组件并且有listener改变GUI的状态,那么那些改变GUI状态的代码也应该写入invokeLater(),这样的话看起来线程安全问题不是上面这样写能够解决的吧?