Java 如果swing view由控制器中的新线程设置,是否需要同步方法
实际上有不止一个问题 给定模型视图和控制器。(我的很多东西都是耦合的——视图知道它的控制器,控制器知道视图。) 控制器中的新线程是否可以以基本的方式启动?使用Java 如果swing view由控制器中的新线程设置,是否需要同步方法,java,swing,model-view-controller,concurrency,Java,Swing,Model View Controller,Concurrency,实际上有不止一个问题 给定模型视图和控制器。(我的很多东西都是耦合的——视图知道它的控制器,控制器知道视图。) 控制器中的新线程是否可以以基本的方式启动?使用newrunnable(){(…)run(){}还是需要以某种“摆动方式”启动才能正常运行?可能是使用计时器或调用器() 第二件事是——假设新线程已经启动——当它直接在视图上运行时,设置一些JTextFields(等等)——像setThatTextFieldWithNewValue(msg)这样的方法是否需要作为从需要线程调用的结果而同步?
newrunnable(){(…)run(){}
还是需要以某种“摆动方式”启动才能正常运行?可能是使用计时器
或调用器()
第二件事是——假设新线程已经启动——当它直接在视图上运行时,设置一些
JTextField
s(等等)——像setThatTextFieldWithNewValue(msg)
这样的方法是否需要作为从需要线程调用的结果而同步?如果是的话-有没有更好的方法可以减少耦合,减少思考所需同步的时间?Swing不是线程安全的
1。UI线程是负责Gui工作的事件调度程序线程
2.尝试在Ui线程之外使用非Ui线程
3。当然可以,您可以从UI线程中触发线程,但建议不要将其触发
UI线程,否则GUI可能看起来没有响应
(即负责UI工作的UI线程之外的非UI线程上的非UI工作)
4.嗯,还有一种挥杆方式。。。使用SwingWorker,这将处理UI和非UI线程之间的同步。
编辑部分:
//请注意,直接在FRAME/JFRAME上添加组件并不好,但我这样做只是为了说明我的意思
public class MyClass extends JFrame{
private final JButton b;
public MyClass(){
this.setSize(300,300);
this.setComponent();
this.setHandler();
}
public void setComponent(){
b = new JButton("Click");
this.add(b);
}
public void setHandler(){
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// Do whatever you want...
}
});
}
public static void main (String[] args) {
EventQueue.invokeLater(new Runnable(){ // UI THREAD
public void run(){
MyClass s = new MyClass();
s.setVisible(true);
}
});
}
}
Main方法在Swing中是短期的,Main方法()将GUI的构造调度到事件调度程序线程(EDT),然后退出。因此,EDT负责处理GUI。因此,始终建议将非UI线程上的非UI工作远离EDT。Swing不是线程安全的 1。UI线程是负责Gui工作的事件调度程序线程 2.尝试在Ui线程之外使用非Ui线程 3。当然可以,您可以从UI线程中触发线程,但建议不要将其触发 UI线程,否则GUI可能看起来没有响应 (即负责UI工作的UI线程之外的非UI线程上的非UI工作) 4.嗯,还有一种挥杆方式。。。使用SwingWorker,这将处理UI和非UI线程之间的同步。 编辑部分: //请注意,直接在FRAME/JFRAME上添加组件并不好,但我这样做只是为了说明我的意思
public class MyClass extends JFrame{
private final JButton b;
public MyClass(){
this.setSize(300,300);
this.setComponent();
this.setHandler();
}
public void setComponent(){
b = new JButton("Click");
this.add(b);
}
public void setHandler(){
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// Do whatever you want...
}
});
}
public static void main (String[] args) {
EventQueue.invokeLater(new Runnable(){ // UI THREAD
public void run(){
MyClass s = new MyClass();
s.setVisible(true);
}
});
}
}
Main方法在Swing中是短期的,Main方法()将GUI的构造调度到事件调度程序线程(EDT),然后退出。因此,EDT负责处理GUI。因此,始终建议将非UI线程上的非UI工作远离EDT
Runnable#Thread
是一种非常舒适、稳定和清晰的方式,但我建议将Swing GUI的所有输出打包到invokeLater
,包括线程安全方法,例如setText
,append
SwingWorke
r,但需要对Java基本类
有深入的了解,在异常回收方面存在一些问题
Runnable#Thread
是一种非常舒适、稳定和清晰的方式,但我建议将Swing GUI的所有输出打包到invokeLater
,包括线程安全方法,例如setText
,append
SwingWorke
r,但需要对Java基本类
有深入的了解,在异常回收方面存在一些问题
最简单的方法是:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Run your code here.
}
});
对于更复杂的任务(将进程块发送到ui线程,响应jobFinished):
newswingworker(){
@凌驾
受保护的void done(){
}
@凌驾
受保护的无效进程(列表arg0){
}
@凌驾
受保护的字符串doInBackground()引发异常{
}
}.execute();
最简单的方法是:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Run your code here.
}
});
对于更复杂的任务(将进程块发送到ui线程,响应jobFinished):
newswingworker(){
@凌驾
受保护的void done(){
}
@凌驾
受保护的无效进程(列表arg0){
}
@凌驾
受保护的字符串doInBackground()引发异常{
}
}.execute();
swing中的任何内容都可以在事件队列上运行。如果您有一个从swing调用的方法,它将已经在那里运行了(就像在动作侦听器中一样)。如果您不知道自己是否在事件队列中,EventQueue.isDispatchThread()
会告诉您。当您知道自己不是时,如果需要查看结果,请使用EventQueue.invokeLater()
或invokeAndWait
引用swing类或方法。(这必须通过main
方法完成。)
对此要非常小心;你必须检查你的代码。如果不是的话,我的经验是swing UI将只是有点片状,带有