如何不让setText崩溃/冻结我的整个应用程序?即使使用SwingUtilities和线程? [英] How to not let setText crash/freeze my whole application? Even using SwingUtilities and Threads?

查看:97
本文介绍了如何不让setText崩溃/冻结我的整个应用程序?即使使用SwingUtilities和线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试解决.setText崩溃问题,该问题是在我随机按下num0按钮时发生的.

I have been trying to fix my .setText crash issue, which occures when i press the num0 button randomly.

  • 但是似乎我只能通过使用来解决它 new Thread(new Runnable() { __overwrite__swing__textfields___ });,但在那种情况下,我无法访问我的JTextField.
  • But it seems i can only resolve it by using new Thread(new Runnable() { __overwrite__swing__textfields___ }); but in that case i can not access my JTextField.

因此,我编写了一个RunnableOutput类来发送和应用,但 帽子也失败了.示例:

Therefore i have written a RunnableOutput class to send and apply but t hat also failing. Example:

RunnableOutput.java

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:

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)您必须添加代码行

1) you have to add code lines

revalidate()
repaint();

在这种情况下,请将JComponents添加到已经可见的Container

in the case(s) you add JComponents to the already visible Container

2)必须在EventDispatschTread上添加/删除已经可见的Container中的JComponents,应将其包装到invokeLater/invokeAndWait

2) add/remove JComponents from/to the already visible Container must be done on EventDispatschTread, should be wrapped into invokeLater / invokeAndWait

3)我建议包装(事件声明为Thread Safe方法)setText()append()到从Runnable#ThreadExecutorutil.Timer

3) I'd suggest to wrapping (event are declared as Thread Safe methods) setText(), append() into invokeLater called from Runnable#Thread, Executor or util.Timer

4)使用SwingTimer(EDT上的保证输出)或Runnable#Thread(必须包装到invokeLater/invokeAndWait中)

5)对于Swing GUI来说,使用SwingWorker会更好,也许比带/或Executor/util.Timer的Runnable#Thread更好. /a>

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

6)请勿阻止EDT

7)为更好的帮助而建议,请尽快使用 SSCCE

7) as adviced for better help sooner edit your question with a SSCCE

编辑

   new Thread(new Runnable() {

        public void run() {

            final RunnableOutput a = new RunnableOutput();

            if (SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        a.setText(nameTextField0, text);
                    }
                });
            } else {
                try {
                    SwingUtilities.invokeAndWait(new Runnable() {

                        @Override
                        public void run() {
                            a.setText(nameTextField0, text);
                        }
                    });
                } catch (InterruptedException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }).start();

这篇关于如何不让setText崩溃/冻结我的整个应用程序?即使使用SwingUtilities和线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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