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

Java 如何不让setText崩溃/冻结我的整个应用程序?甚至使用Swingutility和线程?,java,multithreading,swing,Java,Multithreading,Swing,我一直在尝试修复.setText崩溃问题,该问题是在我随机按下num0按钮时发生的 但似乎我只能通过使用 new Thread(new Runnable(){{uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu但在这种情况下,我无法访问我的JTextField 因此,我编写了一个RunnableOutput类来发送和应用 帽子也失败了。例如: RunnableOutput.java package u

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

  • 但似乎我只能通过使用
    new Thread(new Runnable(){{uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu但在这种情况下,我无法访问我的
    JTextField
因此,我编写了一个
RunnableOutput
类来发送和应用 帽子也失败了。例如:

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

      revalidate()
      repaint();
      
      在这种情况下,您将
      JComponents
      添加到已经可见的
      容器中

      2) 从已经可见的
      容器中添加/删除
      JComponents
      必须在
      EventDispatschTread
      上完成,应包装到
      invokeAndWait

      3) 我建议将(事件声明为线程安全的
      方法)
      setText()
      append()
      包装到从
      Runnable\Thread
      Executor
      util.Timer
      调用的
      invokeLater

      (四)

      (五)

      (六)

      7) 正如建议的那样,为了更快地获得更好的帮助,请使用

      编辑

      1) 您必须添加代码行

      revalidate()
      repaint();
      
      在这种情况下,您将
      JComponents
      添加到已经可见的
      容器中

      2) 从已经可见的
      容器中添加/删除
      JComponents
      必须在
      EventDispatschTread
      上完成,应包装到
      invokeAndWait

      3) 我建议将(事件声明为线程安全的方法)
      setText()
      append()
      包装到从
      Runnable\Thread
      Executor
      util.Timer
      调用的
      invokeLater

      (四)

      (五)

      (六)

      7) 正如建议的那样,为了更快地获得更好的帮助,请使用

      编辑


      为了更快地获得更好的帮助,请发布一个“请在这里找到SSCCE:”我将滚动到“向上”以获得SSCCE。链接?不,谢谢。为了更快地获得更好的帮助,请发布一条消息。“请在这里找到SSCCE:“我将滚动到“向上”以获得SSCCE。链接?不用了,谢谢。@YumYumYum所有内容都隐藏在公共的void draw中(Graphics2D g){这个周期性地重新创建里面的所有对象,这些对象只创建了一次,否则outofmemory杀死了当前的JVM:-)哇,你真是个天才。在这种情况下,你有什么建议吗?我的目标是让键盘捕获+JPanel作为模式,这样我就可以让它看起来像游戏UI了。所有其他的都不那么重要,所以我用了这种方式。但是我会的像你这样的专家,建议作为第一选择。@Yumyum留下这段代码,创建一个空的JFrame,将图像作为背景放在JPanel上,然后你将同样的输出放在屏幕上,而不需要高级绘画和处理器requirements@YumYumYum所有东西都隐藏在公共空间中绘制(Graphics2D g){这个周期性地重新创建里面的所有对象,这些对象只创建了一次,否则outofmemory杀死了当前的JVM:-)哇,你真是个天才。在这种情况下,你有什么建议吗?我的目标是让键盘捕获+JPanel作为模式,这样我就可以让它看起来像游戏UI了。所有其他的都不那么重要,所以我用了这种方式。但是我会的像你这样的专家,建议是第一选择。@Yumyum留下这段代码,创建一个空的JFrame,将图像作为背景放在JPanel上,然后你将同样的输出放在屏幕上,而不需要很高的绘制和处理器要求