【问题标题】:How to not let setText crash/freeze my whole application? Even using SwingUtilities and Threads?如何不让 setText 崩溃/冻结我的整个应用程序?甚至使用 SwingUtilities 和线程?
【发布时间】:2012-04-13 10:04:40
【问题描述】:

我一直在尝试解决我的 .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);
  }

}

菜单.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);

}

跟进:

  • 使用多态性并修复所有这些问题

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE。
  • “请在此处找到 SSCCE:” 我将滚动到“向上”以获取 SSCCE。链接?不用了。

标签: java multithreading swing


【解决方案1】:

1) 你必须添加代码行

revalidate()
repaint();

如果您将JComponents 添加到已经可见的Container 中

2) 在已经可见的Container 中添加/删除JComponents 必须在EventDispatschTread 上完成,应该包裹在invokeLater / invokeAndWait 中

3) 我建议包装(事件被声明为Thread Safe 方法)setText()、append() 到从Runnable#Thread、Executor 或util.Timer 调用的invokeLater

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 编辑您的问题

编辑

   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();

【讨论】:

  • @YumYumYum 一切都隐藏在 public void draw(Graphics2D g) { 这会定期重新创建里面的所有对象,这些对象只创建一次,否则内存不足会杀死当前的 JVM :-)
  • 哇,你是天才。在这种情况下你有什么建议?我的目标是将键盘捕获 + JPanel 作为模式,这样我就可以让它看起来像 UI。其余的都不是那么重要,因此我使用了这种方式。但我希望 Guru 像你一样,建议作为首选。
  • @YumYumYum 留下这段代码,创建一个空的 JFrame,将图像作为背景放到 JPanel 中,然后您将同样的输出到屏幕上,无需高画质和处理器要求
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
相关资源
最近更新 更多