在相关文件更改时动态刷新JTextPane

时间:2011-08-23 10:30:45

标签: java swing refresh dynamic jtextpane

我正在工作的当前项目使用log4j库创建一个日志文件,并且还必须具有“showLog”功能,该功能创建了一个可以查看日志的框架。此外,修改日志文件时必须刷新此帧(附加新的日志消息)。

嗯,除了刷新操作之外,我已经完成了所有操作,这就是问题,我该如何动态刷新?

这里是我的代码的片段,我只放了相关的行:

  • 接口操作:运行事件操作

    public interface Action {
        public void executer();
    }
    

  • Class CadreTexte:创建并管理显示日志文件的框架

    public class CadreTexte extends JFrame {
        private JTextPane log;
        public CadreTexte(String titre, File texte) {
            super(titre);
            if (texte.exists() && texte.canRead()) {
                this.texte = texte;
            }
            else {
                throw new ExceptionGenerateurs("NE_FILE"); //Own exception
            }
            initializeFrame();
    log= new JTextPane(); log.setEditable(false); java.net.URL urlFichier = null; try { urlFichier = texte.toURI().toURL(); } catch (MalformedURLException e1) { throw new ExceptionGenerateurs("Fichier de texte non montrable"); } try { log.setPage(urlFichier); } catch (IOException e) { System.out.println(e.getLocalizedMessage()); //CATCH } finally { urlFichier = null; } JScrollPane docSP = setScrollPane(); // bars as needed, contains JTextPane getContentPane().setLayout(new BorderLayout()); getContentPane().add(docSP,BorderLayout.CENTER); } }

  • Class Vue:主框架。它有一个Action对象列表,存储在HashMap中。可以通过菜单访问操作。由于这个类非常大,我只提出了最重要的一行:

    1. ActionPerformed功能:

      public void actionPerformed(ActionEvent e) {
      JComponent composant;
      Action handler;
      composant = (JComponent) e.getSource();
      String idEvenement = composant.getName();
      modele.log(Modele.LOG_DEBUG, String.format("Événement. ID: %s",idEvenement));
      handler = ACTIONS_MAP.get(idEvenement);
      if (handler == null) {
          modele.log(Modele.LOG_ERROR, "Action non identifiée");
      } else {
          handler.executer();
          modele.log(Modele.LOG_DEBUG, "Fin action");
      }
      }
      

    2. Action visualiserLog:

      Action visualiserLog = new Action() {
      public void executer() {
          if (cadreLog == null) {
              cadreLog = new CadreTexte("Fichier du log", model.getLogFile());
              visuLog = true;
          }
          else {
              visuLog = !visuLog;
          }
          cadreLog.visualiser(visuLog);
      }
      };
      

最后,激活visualiserLog动作的MenuItem是JCheckBoxMenuItem

我希望你在理解了这个大问题后能帮助我。如果有人需要更多信息,请提出要求!

问候!

注意:如果有人可以编辑并给出正确的问题格式,我会非常感激,我一直在和编辑打架,它赢了我=(

2 个答案:

答案 0 :(得分:2)

我不确定自动刷新是个好主意:日志文件通常经常被修改,并且很快就会变得很长,所以你有可能不断重读一个长文件来更新该区域,这个区域不断更新,可能会变得难以阅读。

如果你真的想这样做,我认为唯一的解决方案是首先读取文件并存储其长度或修改日期,然后启动一个线程,每N秒将长度或修改日期与一个存储在内存中。如果已更改,请重新读取文件并更新文本区域和长度或修改日期。

注意不要从轮询线程更新文本区域,而是从事件派发线程更新。使用SwingUtilities.invokeLater来执行此操作。

答案 1 :(得分:0)

您可以创建自定义log4j appender。您的自定义appender可能会以某种方式通知您的GUI已记录某些内容 - 这应该比轮询文件更有效。

你可能正在重新发明轮子。 Apache Chainsaw看起来可能会提供您需要的功能。