如何在Java Swing中以线程安全的方式初始化gui对象? [英] How to initialize gui objects in a thread safe manner in java swing?

查看:197
本文介绍了如何在Java Swing中以线程安全的方式初始化gui对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Java思维,作者强调主方法不应调用swing方法.作为这种做法的一个示例,他提供了以下代码段(可在他的网页上找到):

I'm reading Thinking in Java and the author stresses that main method shouldn't call swing methods. As an example of that practice he presents the following piece of code (available on his webpage):

//: gui/SubmitSwingProgram.java
import javax.swing.*;
import java.util.concurrent.*;

public class SubmitSwingProgram extends JFrame {
  JLabel label;
  public SubmitSwingProgram() {
    super("Hello Swing");
    label = new JLabel("A Label");
    add(label);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(300, 100);
    setVisible(true);
  }
  static SubmitSwingProgram ssp;
  public static void main(String[] args) throws Exception {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() { ssp = new SubmitSwingProgram(); }
    });
    TimeUnit.SECONDS.sleep(1);
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        ssp.label.setText("Hey! This is Different!");
      }
    });
  }
} ///:~

然后通过invokeLater方法创建并初始化gui对象,使其线程安全.但是几页后,作者提供了以下代码:

The gui object is then created and initialized through invokeLater method making it thread safe. But few pages later the author presents the following code:

//: gui/Button2.java
// Responding to button presses.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import static net.mindview.util.SwingConsole.*;

public class Button2 extends JFrame {
  private JButton
    b1 = new JButton("Button 1"),
    b2 = new JButton("Button 2");
  private JTextField txt = new JTextField(10);
  class ButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      String name = ((JButton)e.getSource()).getText();
      txt.setText(name);
    }
  }
  private ButtonListener bl = new ButtonListener();
  public Button2() {
    b1.addActionListener(bl);
    b2.addActionListener(bl);
    setLayout(new FlowLayout());
    add(b1);
    add(b2);
    add(txt);
  }
  public static void main(String[] args) {
    run(new Button2(), 200, 150);
  }
} ///:~

SwingConsole在哪里:

where SwingConsole is:

//: net/mindview/util/SwingConsole.java
// Tool for running Swing demos from the
// console, both applets and JFrames.
package net.mindview.util;
import javax.swing.*;

public class SwingConsole {
  public static void
  run(final JFrame f, final int width, final int height) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        f.setTitle(f.getClass().getSimpleName());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(width, height);
        f.setVisible(true);
      }
    });
  }
} ///:~

因此,与前面的示例相反,在主方法/主线程中创建并初始化了实现JFrame的对象.

So contrary to the previous example an object implementing JFrame is created and initialized within the main method / main thread.

我的问题是: (1)第二个例子是错误的还是第一个例子被夸大了? (2)仅在setVisible调用之后并且在该语句之前可以通过安全方法在主线程中调用swing方法,通过invokeLater调用swing方法就足够了吗?

My question is then: (1) Is the second example wrong or is the first one exaggerated? (2) Is it enough that I call swing methods through invokeLater only after the setVisible call and before that statement it is safe to call swing methods within main thread?

推荐答案

第二个示例是错误的.必须从事件分发线程创建并使用Swing组件.请参见 https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html .

The second example is wrong. Swing components must be created and used from the event dispatch thread. See https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html.

javadoc 引用:

对应用程序的主方法或Applet中的方法的调用不会在事件分配线程上调用.因此,在构造和显示应用程序或小程序

Calls to an application's main method, or methods in Applet, are not invoked on the event dispatching thread. As such, care must be taken to transfer control to the event dispatching thread when constructing and showing an application or applet.

(重点是我的)

这篇关于如何在Java Swing中以线程安全的方式初始化gui对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆