4

在我在 textarea 中显示文本的函数中,我编写了以下代码行,但它没有显示任何文本

        jTextArea1.setText( Packet +"\n" +jTextArea1.getText());

我正在使用 swingworker 执行后台任务,这是我的代码

public class SaveTraffic extends SwingWorker<Void, Void> {


public GUI f = new GUI();

@Override
public Void doInBackground() throws IOException {
              //some code
              sendPacket(captor.getPacket().toString()); 
              return null;
             }//end main function

@Override
public void done() {
    System.out.println("I am DONE");

}


public void sendPacket(String Packet) {

 f.showPackets(Packet);
}

}

以及我在我的 GUI 表单中编写的以下代码行

 public  void showPackets(String Packet) {

 jTextArea1.append( Packet);

}

解决方案:公共类 SaveTraffic 扩展 SwingWorker {

     public GUI f = new GUI();

     @Override
    public Void doInBackground() throws IOException {
    f.add(jTextPane1);
   // some code

   publish(captor.getPacket().toString());

   // the method below is calling sendPacket on the background thread
   // which then calls showPackets on the background thread
   // which then appends text into the JTextArea on the background thread
  //sendPacket(captor.getPacket().toString());

    return null;
   }

  @Override
   protected void process(List<String> chunks) {
   for (String text : chunks) {
     jTextPane1.setText(text);
     f.showPackets(text);
   }
  }

  @Override
  public void done() {
   System.out.println("I am DONE");

   }

}

4

3 回答 3

6

而不是使用 setText() 使用 append()

于 2012-05-20T15:51:16.950 回答
5

您的问题是一个非常不完整的问题,一个没有足够信息来回答的问题,一个迫使我们猜测的问题,但基于您原始帖子中的这一行:

该函数被连续调用...

我猜,我敢打赌你有一个 Swing 线程问题。您可能需要阅读并使用 SwingWorker。

从这里开始了解 EDT 和 SwingWorkers:Swing 中的并发

是的,您的问题是您从后台线程中进行 Swing 调用引起的 Swing 并发问题。为避免这样做,您需要从 doInBackground 导出数据并在 Swing 事件线程上调用它。一种方法是通过发布/处理方法对:

public class SaveTraffic extends SwingWorker<Void, String> {

  public GUI f = new GUI();

  @Override
  public Void doInBackground() throws IOException {

     // some code

     publish(captor.getPacket().toString());

     // the method below is calling sendPacket on the background thread
     // which then calls showPackets on the background thread
     // which then appends text into the JTextArea on the background thread
     //sendPacket(captor.getPacket().toString());

     return null;
  }

  @Override
  protected void process(List<String> packetTextList) {
     for (String packetText : packetTextList) {
        sendPacket(packetText); //edit, changed to match your code
     }
  }

  @Override
  public void done() {
     System.out.println("I am DONE");

  }

  public void sendPacket(String Packet) {

     f.showPackets(Packet);
  }
}

查看我上面链接的教程和 SwingWorker API 以获取更多详细信息。

于 2012-05-20T15:52:39.793 回答
2

由于您的代码片段太小而无法给出正确答案,我能想到:

  1. 当你在更新的时候jTextAreaPacket是空的吗?你能检查一下吗。

  2. 调用此方法jTextArea时是否有任何文字?如果没有并且Packet为空,您将看不到任何结果。

编辑:根据评论:

要附加文本,请使用append,另请阅读教程

虽然我希望setText至少第一次显示文本,但请参见下面的最低示例代码:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class TestJTextArea {
    static void init() {
        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        final JTextArea textArea = new JTextArea();
        frame.add(textArea, BorderLayout.NORTH);
        final JTextField textField = new JTextField();
        frame.add(textField,BorderLayout.CENTER);
        JButton button = new JButton("Add");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setText(textField.getText());
            }
        });
        frame.add(button,BorderLayout.SOUTH);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        init();
    }
}

对此,我也同意 @Hovercraft Full Of Eels 的观点,即您可能有 Swing 线程问题,或者只是使用 append 来附加文本

于 2012-05-20T15:55:21.370 回答