从许多不同的类中更新一个JTextPane

时间:2015-03-09 13:06:40

标签: java jtextpane

我必须通过按钮同步两个数据库。在Button下,我在JScrollPanel中有一个JTextPane。我的TextPane类看起来像:

public class InfoArea extends JTextPane {
  private final HTMLEditorKit   kit              = new HTMLEditorKit();
  private final HTMLDocument    doc              = new HTMLDocument();
  private static ia;

  public static InfoArea getInfoArea {
    if (ia == null) ia = new InfoArea();
    return ia;
  }

  private InfoArea() {
    setEditorKit(kit);
    setDocument(doc);

    showInfo("Please wait...");

    setEditable(false);
  }

  public void showInfo(String msg) {

    try {
      kit.insertHTML(doc, doc.getLength(), "<b><font color=\"#00AA00\">" + msg + "</font></b>", 0, 0, null);
    } catch (BadLocationException | IOException e) {
      e.printStackTrace();
    }
  }
}

&#34; TextPane&#34;在GUI中添加到SOUTH。

现在我有几个课程:

private static final InfoArea ia = InfoArea.getInfoArea();

首先,我初始化数据库连接。因为这样做非常快,所以信息会立刻显示出来。但后来我做了这样的事情:

private void doSmth() {
  for(int i = 0; i < smth; ++i) {
    if(sync()) ia.showInfo("OK");
    else ia.showInfo("Not OK");
  }
}

在其他类中,结果集可能需要一段时间。问题是,在每个方法运行之前,文本窗格不会更新。我对这种行为很反感,我知道问题在于事件调度程序线程(EDT)。我尝试更新showInfo(String msg),如下所示:

private void showInfo(String msg) {
  SwingUtilities.invokeLater(new Runnable() {

    public void run() {

      try {
          kit.insertHTML(doc, doc.getLength(), msg, 0, 0, null);
      } catch (BadLocationException | IOException e) {
          e.printStackTrace();
      }
    }
  });
}

但这不是诀窍。我也尝试过覆盖doInBackground(),publish()和process()的SwingWorker但也没有成功。我还尝试了一个工作线程而不是SwingUitilities。最后我试过了:

private void doSmth() {
  for(int i = 0; i < smth; ++i) {
    SwingUtilities.invokeLater(new Runnable() {

      public void run() {
        if(sync()) ia.showInfo("OK");
        else ia.showInfo("Not OK");
      }
    });
  }
}

没有成功。另外我相信这次尝试是最糟糕的,因为它阻止了EDT。

你可能会注意到,我现在有点绝望,因为我不知道在哪里看别的。抱歉没有发布SwingWorker和WorkerThreads的所有尝试,但他们会炸毁这篇文章。它已经够大了。

有人可以告诉我,我需要做些什么才能让它发挥作用?对于希望在同步过程运行时看到某些内容的客户,我需要它。如果缺少某些东西,我也愿意提供更多信息。

1 个答案:

答案 0 :(得分:0)

自己解决了。我误解了昨天发的一些文章。解决方案是将整个任务放在一个线程中,而不仅仅是输出的方法。

正如我所说,我单击一个按钮开始同步过程。该按钮只调用一个方法:

public void syncDB() {

  ia.showInfo("Sync cat...");
  doCatSync();

  ia.showInfo("Sync item...");
  doItemSync();
  ...
}

现在我必须围绕任务包装一个线程:

public void syncDB() {

  new Thread() {

    public void run() {

      ia.showInfo("Sync cat...");
      doCatSync();

      ia.showInfo("Sync item...");
      doItemSync();
      ...
    }
  }.start();
}

这就是诀窍。我总是乐于改进。