如何不让setText崩溃/冻结我的整个应用程序?甚至使用SwingUtilities和Threads?

时间:2012-04-13 10:04:41

标签: java multithreading swing

我一直在尝试修复我的.setText崩溃问题,当我随机按下num0按钮时会发生这种情况。

  • 但似乎我只能通过使用来解决它 new Thread(new Runnable() { __overwrite__swing__textfields___ });但在这种情况下我无法访问JTextField

因此我编写了一个RunnableOutput类来发送和申请但是t 帽子也失败了。例如:

RunnableOutput.java

package ui;

import java.awt.ComponentOrientation;
import javax.swing.*;

/**
 * JTextField - Wrapper for thread-safe 
 * 
 * @author root
 */
public class RunnableOutput implements Runnable {
  private JTextField outputArea;
  private String messageToAppend;

  // initialze outputArea and message
  public RunnableOutput(JTextField output, String message) {
    outputArea = output;
    messageToAppend = message;
  }

  @Override
  public void run() {
    outputArea.setText(messageToAppend);
  }

}

Menu.java:

public static JTextField nameTextField0 = new JTextField(20);
public void IPpanel(JPanel configPanel) { 

  JPanel Numlock = new JPanel(new GridLayout(0,12));
  JButton num0 = new JButton("0"); 
  num0.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {

      // Fails: 
      // was expecting this should fixed it but indeed still not
      SwingUtilities.invokeLater(
        new RunnableOutput(nameTextField0, "Unit test: 0"));       

      // Fails: 
      // wont work few times works but when randomly i press the 
      // button it fails
      // Same result with: SwingUtilities.invokeAndWait();
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          nameTextField0.setText("Unit test: 1");
        }
      });

      // Works: does not freez but does not change/apply the values
      new Thread(new Runnable() {
        Menu.nameTextField0.setText("Unit test: 2");
      });        

    }
  });
  Numlock.add(num0); 

  configPanel.setLayout(new GridLayout(0,1));
  configPanel.add(Numlock);

}

跟进:

  • 使用多态并修复所有

1 个答案:

答案 0 :(得分:1)

1)你必须添加代码行

revalidate()
repaint();

在案例中,您将JComponents添加到已经可见的Container

2)从{/ 1}}添加/删除JComponents必须在Container上完成,应该包含在EventDispatschTread / invokeLater < / p>

3)我建议将invokeAndWait方法(Thread Safe方法)setText()append()包装到从invokeLater调用的Runnable#Thread,{{{ 1}}或Executor

4)use SwingTimer (guarantted output on EDT) or Runnable#Thread (must be wrapped into invokeLater / invokeAndWait)

5)for Swing GUI would be better to use SwingWorker, maybe better that Runnable#Thread with/or Executor/util.Timer

6)don't block EDT

7)建议您尽早使用SSCCE

修改问题以获得更好的帮助

编辑

util.Timer